A brand new game
for Windows, Linux, Mac, HTML5, 3DS Homebrew and more
Monkey Good and Monkey Bad
16th September, 2013
People keep asking about how I manage to code AGameAWeek, and one thing they all eventually pick up on is that I'm currently doing it all with Monkey.
Monkey is a fantastic language which allows for all manner of different targets, and does a great job doing what it does.
It isn't perfect, and it's not for everyone, but it suits me down to the ground.
As with any development tool, it all comes down to preference, and whether or not you agree with the methodology of the language.
For me, Monkey is fantastic. For others it will be a nightmare.
Today I've decided to create a Pros and Cons list that I can quickly link to, because I kinda feel like I'm repeating myself on Twitter every other day!!
The IDEMonkey is a "keyboard" language.
By this, I mean that, for the majority of the time, you'll be writing your game using your keyboard. There's no mouse-driven GUI Layout stuff, there's no "click the player sprite, select movement style" stuff, and if you're using the default IDE there's not even any auto-complete, auto-correct, auto-indent, or other "Visual" stuff.
Monkey and it's IDE are based solely in the world of typing. In the days of old when you had to actually remember how you spelled your variable names, and where you would make use of those Page-Up and Page-Down buttons that are ever-present on your keyboard.
Monkey is most definitely an old-skool language, and the IDE fits the bill.
It isn't too powerful, and yet it does exactly what you need it to do.
As long as you know how to write it, then the IDE will happily oblige.
The LanguageMonkey is a "classic" language.
By this, I mean that, for the most part, Monkey feels like an olden day "BASIC" language.
The syntax is very much structured like old basic, with for-next loops, and = not ==, a=a+1 not a++, mod not %, and NOT not !=
There are tweaks to the language, which are needed due to the different ways that modern systems work, but for the most part you can get away with bundling everything into a great big loop, and "doing it old-skool"
The Logic/Render SplitDue to all the different targets and other complexities, Monkey needs you to split your code into two distinct areas.
One is the "Logic", and the other "Drawing".
You can get around this by building a decent framework so that you basically "pretend" to draw during the logic loop, stuff all the drawing commands into a buffer, and then when the Drawing loop is called, spit it all back out.
OnUpdate() and OnRender() are called, with OnUpdate occurring every X millisecs, and OnRender happening whenever the system can manage to keep up!
For the most part, this split helps keep your gameplay smooth, and the framerate as stable as possible.
It takes a little getting used to, however, as you stray back to old habits, and occasionally accidentally trigger a drawing function inside your update loop, which inevitably causes the game to crash.
The TargetsMonkey can target MANY different things, from Android to iOS, HTML5, Flash, Windows and more.
If you want to focus on one specific target, then you can, but the whole point of using Monkey is to make things multi-targetted, so you might as well make good use of that functionality.
There are things to keep in mind when targetting multiple system, though.
For the most part, you'll want to try to stick to Actual Monkey Functions. These are the things that are built in, created by the author, and are as stable as they can be.
By using default commands, you can be sure that as much as possible, what you code for one thing should work on another.
There are obvious things that won't, like GameCenter obviously only works on iOS, and then there are "quirky" things, like SetColor (to recolor your sprites) is terribly slow in HTML5, but as you learn with Monkey, you'll soon become accustomed to these various abilities.
You can easily use Pre-Processor rules to enable/disable different things, depending on the current target, and when used wisely, these can save you a lot of trouble.
The "Load/Save" ThingSince I first installed Monkey, the developer has been busying away adding various file-access methodology onto various targets, but he's still not 100% there, and there are all manner of complexities and pitfalls to watch out for.
For ease of use, the basic language at it's most simplest, uses "String$=LoadState()" and "SaveState(String$)" commands.
These allow for only one single string to be loaded/saved for your game, but it DOES work on all targets (or at least, all that I've tested!)
You can cram up to about 1Mb of data into that string, and easily load and save it, meaning you've plenty for storing scoreboards, names, current game progress and more, as long as you can find a neat way to shove it all into a single string.
If you want to attempt other file-access methods then go ahead and flick through the docs, but be aware that not everything works on every target, so there may be complications further down the line.
Online/Network FunctionalityThe developer is slowly adding online features to Monkey, but it's currently very target specific. Just like file-access, it's a case of trial and error, and seeing what does/doesn't work.
Ironically, HTML5 seems to be the least capable, which is bizarre given that the thing's running in a web browser!
If you're going to add online functionality, be ready to make good use of pre-processors so that you can keep your code as uniform as possible.
The "I have to CODE that!?" bitMonkey is a language. It is not a complete game engine. If you want things to happen, you have to code them.
Monkey gives you basic functionality, like the ability to load a .png file, and the ability to draw it at different scales, rotations and even change it's color.
But it isn't a Sprite Engine.
If you want a Sprite Engine to keep track of your sprites for you, then you have to code one.
It isn't a Font Engine.
If you want nice fancy bitmap-font text on your screen, you'd better be prepared to write a bitmap-font display function.
It isn't a Tilemap engine.
If you need a scrolling background, then start learning, because you're going to have to make it yourself.
You could, of course, simply grab some of the numerous sprite/font/tilemap engines that are available. The MonkeyCoder website has a whole bunch of ready made frameworks, and a crazy amount of libraries, ready for use.
I coded mine. I enjoyed the time spent learning these things, and getting to grips with the core of the language.
You might want a shortcut. But be aware that if you do use a shortcut, you're probably skipping some of the important stuff.
Audio ChannelsAlthough Monkey has a fairly competent audio engine, you'll want to keep tabs on the various audio channels.
HTML5 seems to be able to cope with no more than 8 sounds at a time. I'm not entirely sure why this is, but you'll need to keep an eye on that, and limit things accordingly.
Other than that, you should be able to keep a standard of 32 channels going at once, which is more than enough for most games.
Be aware that, in HTML5 at least, trying to play a sound that you haven't loaded yet results in a blank white screen and your game crashing. If this happens to your game, your audio code should be the first thing you look at!
Other Debugging TipsBe sure to try your game using Debug mode, and watch the lovely line-number stats that appear to help track down the causes of any crashes.
In HTML5, drawing null images is fine, but on Android it'll cause a crash.
Be sure to doublecheck your variable name spelling, although you'll probably catch that before the game's managed to compile!
Make use of the DebugLog command to check complicated functions work as expected.
If things "disappear" suddenly, double check your OnRender loop, and that you aren't overwhelming it. Don't forget to CLS, and clear your Sprite Buffer!!
Monkey doesn't "do" a lot of debugging, so you're going to have to understand where and why most of your issues occur, and have the ability to figure out exactly what's going on.
Again, Monkey is very old-skool, and you DO need to do a lot of the legwork yourself.
Be aware of what you're coding, be sure you know the limits of the language (and the various targets), and then take things step by step to ensure everything still works the way it oughta.
If something suddenly breaks, use the classic method of cutting out chunks until you narrow it down!! It helps!
The ResultIf you work hard, and you make yourself a nice suitable framework which copes with all the targets, then Monkey is your friend.
I can currently write a game ONCE, and have it compile and play in HTML5, as a Windows EXE, for Android targets and iOS, too. I can also, kinda, get it running on a Mac, but I've barely tested that properly, and apparently Linux is simple, too.
I write once, and then it's more or less as easy as clicking the "target" menu, and hitting F5.
Monkey IS a good language, and it can do a lot.
But it's also a multi-target language, and as a result it has many pitfalls which you need to understand.
If you just want to make a game, I'd probably recommend BlitzMax. But if you want to make a multi-target, mobile-capable game, and you prefer the old-skool functionality of Basic, then Monkey's a fantastic choice. You can't really go wrong.
You can grab the 100% Free HTML5 "demo edition" of Monkey from the website.
It's the complete language, but only compiles to HTML5. But you can play about with it, learn the ropes, and figure out if the language is right for you.
Give it a whirl, see if you can get to grips with it, and if you do enjoy it you can then buy the complete edition which lets you compile for everything else.