When disabling sound loading on demand I get
java.io.IOException: javax.sound.sampled.LineUnavailableException: line with format PCM_UNSIGNED 22050.0 Hz, 8 bit, mono, 1 bytes/frame, not supported.
at com.robbix.mp5.ui.SoundBank.preload(SoundBank.java:48)
at com.robbix.mp5.Game.load(Game.java:38)
You should rather find a solution that keeps all sounds in memory and doesn't use one thread for every sound.
I never programmed anything with audio, so I can help you little with that.
I suggested OpenAL, because its one of the (probably few) sound libraries with java bindings (namely JOAL). Its probably the most platform independent sound library. I don't know if it is suitable for your game. But its used by some serious games, so its probably worth being looked at.
I like the idea of using zip archives as container for several small image files. When doing a little test with the Eden SF "fidget1" frames I get better compression than converting each file to png.
As for the choice xml or not, I can tell that its probably a bottleneck, but at a place where it won't hurt. You have to parse xml files only once at startup (either of the whole application or a single game) and that is still fast enough to be unnoticed. (Civilization IV uses xml and it has no performance issues)
I like the xml format, because it can be modified in a mere text editor.
One thing that I don't like is its verbosity, especially the lines
<OffsetFrame offsetX="11" offsetY="41"/>
<OffsetFrame offsetX="11" offsetY="41"/>
...
We should find a better solution for those.
Sadly, I think that's probably the more compact way to express that in XML. Be thankful it's not something like SLD style files used in map styling for various geographic information systems. I've always found them to be needlessly verbose, even for XML. They seem to not like tag attributes. I think their equivalent would have been more like:
<OffsetFrame>
<Parameter>
<OffsetX>11</OffsetX>
</Parameter>
<Parameter>
<OffsetY>11</OffsetY>
</Parameter>
</OffsetFrame>
Those files have always made me cringe.
I like the idea of using zip archives as container for several small image files. When doing a little test with the Eden SF "fidget1" frames I get better compression than converting each file to png.
I like the xml format, because it can be modified in a mere text editor.
One thing that I don't like is its verbosity, especially the lines
<OffsetFrame offsetX="11" offsetY="41"/>
<OffsetFrame offsetX="11" offsetY="41"/>
...
We should find a better solution for those.
Yeah, the frm-xxxx.bmp files compress fairly well, as there is alot of repetition in them. It's the sound files that make the download so big. And all the unused sound files are in there too.
I was thinking of re-writing them using JSON or YAML. In JSON, that XML sample would could look like this:
["11", "41"],
["11", "41"],
...
I don't want to use one big file as I like the idea of modularity. I have this overly ambitious idea that we could be able to pipe things like new maps, new sprite sets, new sounds, new tilesets, even new unit types over the network on the fly as a multiplayer game is loading.
I think I'll put it on the list to have the sprite loader read two formats:
* open set of folders and files with a xml config file
* a single binary file that contains the config info and all sprites for a unit/event. May also be zipped.
And an extra program that builds the .dat file. That way, it can be uncompressed for editing, and then compressed for deployment.
I was thinking of re-writing them using JSON or YAML. In JSON, that XML sample would could look like this:
["11", "41"],
["11", "41"],
...
Sometimes my ideas are a bit ugly... Judge for yourself:
Keep the xml format for the files
Introduce a new data type "matrix" that looks like this: "[11,41;11,41;...]". It represnts
Files could then contain lines like
<OffsetFrames matrix = "[11,41;11,41;...]" />
Handle this in your program by reading it as a string and parsing it with your own function.
Map scrolling added so now you can have maps bigger than the screen!!! This was an obvious lack of feature which actually only took about 20 lines of code to add, because of some planning-ahead I exercised earlier.
Youtube video of combat and mining on 48x48 map (http://www.youtube.com/watch?v=KatgRPbHS1w). Before I could only fit a 30x20 map on my 1024x768 laptop screen, so not much could fit.
The combat demo now has four groups of tanks numbering 150 each (mw, laser, railgun, rpg) converging on the center of the map where 81 acid clouds await. Running it reveals serious performance problems with all those vehicles on screen.
The mining demo isn't much different, just more smelters, mines and trucks. This one hardly slows down at all from the bigger map - a pleasant surprise.
So... considering the noted performance problems, and the fact that the combat demo ends up using about 150MB of memory, I would really appreciate a code review. The google code project is linked at the top of the page. It can be checked out through subversion or browsed on the site.
Memory-wise: there are literally hundreds of thousands of Position objects being created as the program runs. The Position class contains only two integer values: x and y. Because there's no way to allocate the pair on the stack in Java, they get allocated on the heap and sit until the garbage collector cleans them up - any ideas? The profiler also showed a similar number of HashMap entries - so that's something else to look for. Look at com.robbix.mp5.basics.Position
and com.robbix.mp5.ui.SpriteLibrary
.
CPU-wise: I ignored this other problem in an attempt to avoid premature optimization, but its time has come: Every mechanics cycle, the entire list of units on the map is copied and iterated over. Every draw cycle (immediately following a draw cycle) the entire list of units is copied (sorted) to a sorted set and iterated over. I suspect this takes some time for 100's of units. Look at and com.robbix.mp5.ui.DisplayPanel
.