Dev Dairy: Growtopia thoughts

What I’ve been up to

Working on Growtopia mostly.  Despite Growtopia being nearly two years old now it has just had its most profitable month!

Some stats:

Total user accounts: 5.6 million
Total worlds created: 95 million
Daily unique users: 337,000
Daily hours played: 550,000
Daily peak concurrent users: ~40,000

Sadly, that’s pretty much all I’ve been up to

As a self employed developer I’ve learned that when something does well, you focus on it and ride the money train while you can because it won’t last. You bank the extra to tide you over when things get slow.  Success dictates where you spend time because you’d be a big idiot not to.  Something like that.

This is why I worked on Legend Of The Dragon (off and on) for seven years.  As the BBS era came to a close, so did my updates.

Maintaining Growtopia is now less about programming/creating for me and more about isolating problems, fixing bugs, monitoring servers, answering the hardest support questions, scanning logs, putting out fires, figuring out why we have are having dropped packets, which incidentally, we are currently having an issue with.  Maybe a bad router, man I hate when it’s hardware.

Can I do this and still have the “emotional energy” to make something new (part time)?  To actually program again?  Hmm.

Dev Diary: A look at Visual Studio 2013, Unity, and UnityVS

oldman

I’m a bitter old man

When you’ve been making stuff as long as I have you get comfortable with your tools.

I am a greased ninja with Visual Studio 2005, VisualAssist, and C++.

I’m a snail drenched in chunky peanut butter working with anything else.

But yesterday I gave Visual Studio 2013 + Unity a shot and it actually wasn’t half bad, so here are my tips if that’s something you’re interested in.  Beats MonoDevelop by a mile as far as I can tell.

My tips for people upgrading from old VS versions:

  • First I downloaded Visual Studio 2013.   I guess it’s “Ultimate” and free for 90 days?  Fine.  After that we’ll see, but I’m pretty sure I’m not going to cough up $13,299 for Ultimate!
  • Set keys to the included VS 2005 layout.  Changed it so F7 will compile all.
  • MOST IMPORTANT: Enabled Options->Environment->Tabs and Windows->Floating tab wells always stay on top of the main window.  Without this I found VS 2013 totally unusable.
  • Turned off the silly all upper case menu fonts
  • Installed Productivity Power Tools 2013 (adds some stuff to make the IDE smarter, sort of like VisualAssist?)
  • Oh God, what are these vertical lines connecting every matching brace?!  Disabled that, FAST.
  • Stopped it from showing “References”
  • Turned off its funky new scroll bars, but ended up turning them on again, gotta see how that feels, they do have some interesting data
  • Installed UnityVS (MS did something very smart, they bought it and made it free)
  • Imported the “Visual Studio 2013 Tools.unitypackage” into a simple Unity project (this file gets installed by UnityVS  into C:\Program Files (x86)\Microsoft Visual Studio Tools for Unity\2013 or something, have to dig for it)
  • Inside Unity I double clicked a source code file and viola, it did load the project in VS 2013!  It wouldn’t start the Unity project when I hit F5, but it did connect to the process, so after manually starting the game in Unity it did perform debugging fine.  I think Visual Studio has THE BEST debugger around so this should come in handy.  Er, I mean, I’m guessing, since my code never has bugs of course. <awkward silence and then someone coughs in the back>
  • When you hit a breakpoint, the Unity editor side seems to completely freeze until you hit Resume, too bad, seems like it would be useful to tool around in there and look at objects during debugging.
  • Anyway, everything works and doesn’t feel half bad.  So far.  I assume the crashing,  freezing, and constant reboots that also plagued my experience with MonoDevelop/Unity will start soon though.

Anyway, here’s a picture of what debugging looks like.  I think it would be handy to be able to write non-Unity specific C# code and simultaneously have Unity and non-Unity VS projects open using it, maybe C++ as well as I still like that for my server backend code.  (See my Space Taxi Multiplayer test)  (Uhh, ignore that code in the screenshot, it’s uh, an exercise for the reader to figure out how to make that less stupid looking and redundant)

unity_and_visual_studio

 

3D movies, kid? Pfft, try 4D! (A review)

4dx

So I got a chance to experience “4DX” Spider Man 2 at our local movie theatre.

Despite buying tickets online weeks in advance, I still got a horrible seat. (front, far left)  Sadly, this sort of makes the 3D effect worse and introduces eye strain.

So what does paying extra for the “4DX” experience get you?  What do these fancy electronic chairs do?

Well, they mostly kick your chair throughout the movie, punctuated by an occasionally spitting on you.

Shoot, back in Salem, Oregon, you got this for free.

Every time a “chair effect” kicked in, I was mentally pulled away from the film, it actually detracted from the movie.

I realize theatres need to add value to remain relevant but..  I don’t think this is working.

What I’d like is a seat perfectly in the middle, be able to pause to use the restroom, and eat and drink anything I want.  No commercials or waiting.  So yes, I want my living room.

Adventures in Unity3d 1: A simple event scheduling system and sound manager

Forget the cloth physics, kid

So I’m learning Unity and figured it couldn’t hurt to blog about my experiences while still fresh.

After doing a few of the sexy terrain and physics tutorials which instantly let me do amazing things with a few clicks, I realized I probably couldn’t even write tic tac toe.

OH YEAH?!  Be amazed:

Fine, it sucks.  But that wasn’t the point, it forced me to come to grips with how objects, scripting and using classes together all worked in Unity and C#.

(And yes, the enemy “ai” is actually Board.GetRandomEmptyCell() … busted! )

Source is here as a zip.  (Requires Unity 4.3, despite the intense graphics it doesn’t require pro)

A common trait of programmer-centric devs is are constantly thinking about projects on a “shared” and “app specific” level.  They are organizing code into two places, with the more generic stuff meant to be reused.  We just can’t help it!  It’s why we always end up with engines and middleware.

So in case it’s useful to anybody else, here are some general utilities I wrote and an explanation of why they are useful.

You can download them as a unity package here:  rt.unitypackage (they are also in the tic tac toe source above)

RTAudioManager

I didn’t see a simple way to play a “crap.wav” filename from script (you have to create an object and attach a sound and ..) , so this is a very basic class that takes care of stuff like that.

You add an audio file under Assets/Resources (uncheck 3d sound source on the file in Unity – That one confused me, as there is no error, you just don’t hear anything…) and can play it from anywhere like this:

//don't add the .wav or .mp3 at the end, it's automatic
RTAudioManager.Get().Play("scream");

Or to get fancier:

//Play at 1.0f volume and a pitch mod of 2 (twice as fast)
RTAudioManager.Get().PlayEx("scream", 1.0f, 2.0f);

To play a song (will kill any current song playing)

//plays mysong.ogg or mp3 etc at 1.0f volume and 1.0f pitch mod, looping
RTAudioManager.Get().PlayMusic("mysong", 1.0f, 1.0f, true);

To set it up in a project is easy, just add RTAudioManager.cs to an empty GameObject somewhere.  (It will rename the gameobject RTAudioManager if it isn’t already)  It uses a singleton style .Get() to give the same instance to everybody.

RTEventManager

One of the first things I do in a new programming environment is figure out how to call any function in N seconds with any number of parms .

Even in the crappy Tic Tac Toe above, the difference between everything happening at once and instead using subtle delays (for instance, a delay before the AI moves) makes a huge difference.

If interesting timing is simple to add and tweak in your game, you’re much more like to do it, if you’re as lazy as I am.

Coroutines and other schedulers I found didn’t quite fit my requirements.. plus, I like to waste time re-inventing everything anyway!

Same as RTAudioManager, to set it up you just add it to an empty GameObject in your scene.  There is no other setup needed to just start using it.

It uses SendMessage internally and things it sends to must have a unique GameObject name.

Let’s say you want to use the above RTAudioManager to play “pain”(.wav) in 1 second instead of instantly.  No need to build a special timer, just use RTEventManager like this:

//schedule the function "Play" to be called in one second, sending a string variable to it.
RTEventManager.Get().Schedule(RTAudioManager.GetName(), "Play", 1.0f, "pain");

It’s a little ugly, but not too bad to understand.  The .GetName() is just a function I added to the RTAudioManager class to make it easy to get the GameObject name its attached to, but a string of “RTAudioManager” would have worked just as well, you just have to be sure you know what stuff is named.

Want to call a function called Respawn that is in an attached script on your player GameObject (which is named “Player”) in 5 seconds with no parms?

//note that you don't have to send that extra parm
RTEventManager.Get().Schedule("Player", "Respawn", 5.0);

But what about RTAudioManager.Get().PlayEx(“fileName”, 1.0f, 2.0f);  from above? What if we want that to happen in 5 seconds?  That needs three parms, how can we schedule that?

Well, I couldn’t figure out a great way, but because the scheduler’s single parm can be of any object type we can work around the problem.  One way would be to send a custom class, but I’m far too lazy to be creating classes everywhere so here’s what I came up with instead:

//will play in 5 seconds
RTEventManager.Get().Schedule(RTAudioManager.GetName(),
   "PlayEx",  5.0f, new RTDB("fileName", "scream",
   "volume", 1.0f, "pitch", 2.0f));

What’s going on here?  RTDB is a simple database key/value (which can be any object type) system that can be created and sent inline with a flexible number of parms.  Key “fileName” is a string, key “volume” is a float and so on.

Unfortunately, when doing this, the receiving end must expect what is coming and know the keyname(s) to extract the data.  RTAudioManager’s code to receive it looks like this:

public void PlayEx(RTDB db)
{
PlayEx(db.GetString("fileName"),</pre>
db.GetFloatWithDefault("volume", 1.0f),
 db.GetFloatWithDefault("pitch", 1.0f)
 );
 }

It’s just a front end for calling the real function.  It will warn if sent the wrong type.  If a parm is left out, it will use a default value so it still works. (filename is the only thing absolutely required)

On the bright side, you can easily add support for more parameters without breaking backwards compatibility in places you’ve already used it.

Speed considerations

Now, you may be worried about the costs of using SendMessage internally, the name lookups, and inline initializing and usage of RTDB and the like.  Well, unless you’re sending 25+ messages a second I wouldn’t worry about it.  It’s mostly for controlling program flow and timing, if you’re sending 1000 messages a frame (for instance, trying to control a sprites x/y animation with it)  it’s definitely the wrong tool for the job.

One click build and upload

Oh, also included in the zip above is a windows .bat file that builds and uploads the web version of the game.  You’d have to edit it a bit, but here it is:

call app_info_setup.bat
REM get our ftp logon info
call d:\projects\SetFTPLogonInfoTanked.bat

:Actually do the unity build
rmdir build\web /S /Q
mkdir build\web

echo Building project...
%UNITY_EXE% -quit -batchmode -buildWebPlayer build/web .
echo Finished building.

rmdir temp /S /Q
mkdir temp
mkdir temp\%FILENAME%

xcopy build\web temp\%FILENAME%\ /E /F /Y

rename temp\%FILENAME%\web.html index.html

if not exist temp\%FILENAME%\index.html beeper.exe /p
if not exist temp\%FILENAME%\web.unity3d beeper.exe /p

ncftpput -u %_FTP_USER_% -p %_FTP_PASS_% -R %_FTP_SITE_% /www/ temp\*

echo File uploaded:  http://www.%_FTP_SITE_%/%FILENAME%

:Let's go ahead an open a browser to test it
start http://www.%_FTP_SITE_%/%FILENAME%
pause

It requires ncftp to be installed.

Oh, app_info_setup.bat sets the app name, but it also would need to setup the ftp site and password data. Basically you need this somewhere, could even cut and paste it to the top of the .bat:

SET FILENAME=breakout
SET UNITY_EXE=A:\pro\Unity\Unity.exe
SET _FTP_SITE_=mydomainname.com
SET _FTP_USER_=username
SET _FTP_PASS_=mypassword

Breakout test

To get slightly more graphical, here’s a “throwaway breakout” I whipped up (using the old 3d physics, not the new box2d stuff)  (Maximize to look slightly less ass, use arrow keys to control):

Was watching the Unite keynote (woah, Richard Garriott!)  and believe I heard that 10% of all downloads happening on iOS are now Unity based.  That’s just.. wow.

Why Unity and C#?  Aren’t you that hardcore C++ guy who made Proton SDK?

Yeah, but that doesn’t mean I have to use C++ for everything.  I still use Proton (ahem, Growtopia) and it’s my go-to weapon if I have to port an existing C++ product to mobile. (as with Dink Smallwood)

But let’s face it, supporting the newer graphic technologies on the plethora of platforms and graphics chips out there is a losing battle for a one-person developer.  Especially if I’d like to actually make games too.

(Note: Others are still adding new features such as GLES2 support  to Proton in separate distributions, which is fine with me)