Monkey, XNA and CLR Profiling
Since the weekend I've wanted to do some CLR profiling on the code generated by Monkey and tonight I finally managed to do it. I've never done CLR profiling before, hell, I don't even know what it stands for and until the first the first time I started making Ninjah in XNA I didn't even consider needing to be careful about memory allocations so this is all new to me.
On Monday I concluded that I couldn't realistically do much more with my coding so it must be something Monkey is doing to cause a hell of a lot of garbage collection. All of the blog posts I could find mentioned CLR Profiling so with the help of THIS and THIS I did it and got the following...

Cause of allocation from DrawImage

Cause of memory allocation for DrawText
The bars between the blocks indicate the amount of memory allocation that has occurred through a function, method or whatever it is. In the first instance, you can see that the DrawImage function I call is calling DrawSurface which is allocating lots of memory to Vector2's and Vector3's. In the second example you can see that the DrawText function I call, is calling DrawImage which is calling DrawSurface2 which is again allocating lots of memory to Vector2's and Vector3's. Such a frequently used function should not be causing so much allocation. The PC based GC can handle this (which explains why I didn't run into any issues early on), but the Xbox based GC really cannot and to quote THIS ...
- GC on Windows is not a good thing and you should try to avoid generating garbage where reasonably convenient.
- GC on Xbox is a very bad thing, and if your game is intended for Xbox 360 you should go out of your way to avoid it everywhere possible.
DrawText I can do without but Blitz really need to fix DrawImage to make it usable for Xbox 360 games.
Monkey -> Xbox = :(
I am developing Ninjah primarily for Xbox 360 via Xbox Live Indie Games. Until Friday I had been developing this on my PC and making the assumption "well if it runs on my old laptop it will definetly run on a current gen games console like the Xbox 360". This has turned out to be quite a naive assumption because Ninjah runs badly on the Xbox, quiet badly considering how simple to code actually is.
I have spent most of the past weekend trying to find what was causing the slow down and to start with I was confident that the issue related to the manipulation and presentation of string objects. I removed these items from the main menu and indeed, the stuttering I had been experiencing stopped. Running the Remote Performance Monitor indicated that there was now very little garbage collection happening. "Yay!
" I thought to myself, "I have solved it". While inconvinient, it certainly wasn't a show stopper. All I needed to do was replace the reletively small number of strings in the game with images of text (e.g. the tutorial text, level names etc). Before starting this, I thought I'd check the actual game area again and unfortunately the stutter was still occurring due to the GC having to work extremely hard still.... joy.
Now, when I had been making Ninjah directly in XNA, I had run across a problem where using lists to store instances of classes was also causing stuttering (at the time I didn't know it was due to garbage collection, but in retrospect, it seems pretty obvious). The solutions mentioned on forums stated to use an object pool. An object pool can be as simple as having a predefined amount of instances stored within an array. These objects are only drawn/updated when they are active and when a "create" call is made, the array is searched through for an inactive instance which is then activated and manipulated to appear as a brand new instance.
Basically, at the start of an app I create 500 new particles in an array and from this point onwards no additional particles are ever created, this pool of 500 is recycled as required. This is great because it leads to very little additional memory allocation which in turn causes garbage collection. For Ninjah via Monkey, I had been using lists because I assumed they wouldn't cause these issues, however, I now believed that this was causing the GC stutter.
So... I figured that to fix the problem I would go through the irritating process of replacing all list code with array based pool code. All in all, this actually went much quicker than expected and I was looking forward to seeing Ninjah running at a constant 60fps on the Xbox. It didn't and it was still stuttering. I went as far as having just a simple level drawn on screen with no game logic being run and the stuttering still occurred. I removed all currently unused graphics from the build, no change. I removed all sounds from the build, the same. I even went as far as to remove all instances of a Local variable being created and it made no difference at all.
I felt very much like I was sat on the floor with a crowbar in hand, out of breath, surrounded by the broken parts of my once functioning game; all in all a bit gutting. At this stage I made another assumption (I've really got to stop doing this), that deep down I had coded something badly, so for peace of mind more than anything I decided to make a very simple app from scratch that did nothing but draw a set amount of particles.
I am in two minds to see that this too is causing the garbage collection to skyrocket once a certain number of draw items is hit, this lead me to believe that there are issues above my coding (relating to the way Monkey transcodes source to XNA/C# code). The good part thinks "well, it wasn't me afterall, there was nothing I could have done differently". The bad part things "I have absolutely no control or ability to fix this problem".
I briefly entertained the idea of saving each level to an individual image file to reduce the number of draws required, but I shouldn't have too and really, I just think that the issue will show up later down the line in another area. Drawing ~200 items a frame is a tiny amount compared to what should be possible.
As it stands then, I am pretty much at the mercy of Mark the developer of Monkey. I can continue work on Ninjah on the assumption that one day the transcoding will be Xbox friendly, but if that doesn't happen any time soon I will have to consider releasing it on PC first and/or working on it directly in XNA (something I'd rather not do because the Monkey language seems much easier to me).
Garbage Collection
So... the slow down is due to garbage collection. Garbage collection happens due to memory allocation. As far as I can tell, memory allocation occurs when new instances of something are created.
I managed to get rid of the stutter on the main screen by getting rid of all string instances however, there is still slow down during game play which is irritating. I am currently using lists to iterate through the tiles, but I am beginning to think I am going to have to move over to a 2D array. This is irritating because I had to do the same thing when working directly with XNA. Stupidly, I assumed that Monkey would handle things differently, but it appears not.
So the way I see it at the moment, I am going to have to update all code relating to lists and change it to arrays... yay.
Im gonna watch the grand prix and maybe try later.
Ninjah stuttering on Xbox
So yesterday I ran Ninjah on the xbox for the first time and unfortunately there appears to be some stuttering, even on the main menu which doesn't really have anything yet.
The videos below show what I am talking about.
[youtube]jGUBq9rG6-E[/youtube]
[youtube]ym4K0epGfeE[/youtube]
You will notice on the xbox video there is a brief but regular pause. I am at a loss as to why this would happen, so in that respect I am glad I've already made good progress this week because I can imagine this will take a lot of my time : / MOW!
Targets for 26th June
- 14 more levels ( 18 / 14 )
- alternative tile set
- pre play animation
- extra gameplay particles (particles!)
- Skid particles
- jump particles
- actually finish the ninjah sprite
- make buttons look nicer
- brief intro sequence
- come up with a 'company' name? : o
- make it a bit more exciting when a new best time is posted
- remove debug controls
- ghost recording and playback?
- editor - move blocks
- improve coin collect particles
- Mark tutorial levels as such in the select screen
- shift level data into app (currently sits in savestate, which is bad!) Currently can only save to savestate, so manual copy and paste required.
- alternative level episodes (maybe?)
- 10 map marathons (set a time for 10 levels in a row)
- sort out level state saves
- fix hollow rect code
- make horizontal colour collisions never safe
- improve editor background grid
- Gun sound effect
- Coin sound
- fix change next to change block
- fix bad xbox performance
Weekend 18th/19th
I aimed to complete 5 tasks from my todo lost and I would say I managed 8.5.
I can add items to the list whenever I want, but I will always aim to clear at least 5 items a week. Hopefully I will be removing them quicker than I am adding them!
Targets 18th/19th June
Over this weekend I would like to have completed at least 5 of the following. I will add to this list as I find additional things that need changing.
- 10 more levels (6 / 10)
- fix tile drawing code
- alternative tile set
- pre play animation
- extra gameplay particles (particles!)
- more in game sounds
- fix sprite jump on restart
- add button pointer icons to menus
- add restart prompt when stuck
- add 1 frame delay before more can occur (to make sure changes can happen)
- fix change/exit particles spawning when level restarted via x button
- actually finish the ninjah sprite
- fix ninjah safe when touching neutral bug
- make buttons look nicer
- brief intro sequence
- come up with a 'company' name? : o
- make it a bit more exciting when a new best time is posted
- remove debug controls
- ghost recording and playback?
- editor - clear current level
- editor - move area of blocks
- improve coin collect particles
Ninjah colour generation system
Here is a screen shot of the complex colour generation system that I have utilised.
Ninjah Fireworks 2
This weekend I intend of doing some particle work (because particles make ugly things pretty so they do), finalising the movement engine and then making 5 levels.
Away from that, I need to look at music playback because currently I cannot get things to loop without an annoying gap.




