Aug 04 2011

Bored of clutter yet?

Tag: Full Games,MMORPG Tycoontrevor @ 11:29 pm

Feels like I’ve been working on clutter for ages and ages.  And from a certain point of view, I guess I have.  These clutter systems are kind of a simpler version of most of the rendering parts of MMORPG Tycoon 2;  creating and destroying renderable geometry when it’s needed, so we don’t have a ridiculous amount of geometry just sitting around in memory all the time, not being used.  This is an important consideration, when your game world is the size of World of Warcraft!  The stuff I do here will eventually generalise out to the height map, and then (hopefully!) to most other procedural geometry int he game, and should make the game feel a lot more responsive.

So today I’ve done phase two of the multithreading of clutter.  Yesterday, each “clutter tile” kept its own thread which would sleep while waiting for a “build some new clutter” job to arrive.  Today, there is now just one “worker thread” which handles all clutter rebuilding tasks.  This behaves a lot more nicely (particularly for people with fewer cores on the CPU), and should scale a lot better.  And it’s noticeable faster again to rebuild tiles of ground clutter, even compared against how fast it was yesterday.  From my point of view, the system side of ground clutter is now basically finished.  All that remains to do is to generate different types of clutter depending upon the terrain type (right now, it generates grass on everything, even bare mountain faces)

The plan is that tomorrow and over the weekend, I’ll be bringing this same system over to edge clutter, and to the base height maps as well.  This should substantially improve the frame rate jitters that I currently get when a new block of world terrain comes into view.


Aug 04 2011

Multithreading

Tag: Engine,Full Games,MMORPG Tycoon,VectorStormtrevor @ 12:55 am

Just a couple quick notes today, because I really ought to be sleeping instead of posting.

Today, MMORPG Tycoon 2 has finally become a multithreaded game.  It’s not ubiquitous by any means, but it’s taken the first step;  the ground clutter is now being generated in a background thread.  The only bit of clutter-related code which is now occurring in the main thread is copying the final geometry into the buffer that OpenGL renders from.  Now all the setup work as you move around the map is being handled in separate threads.

This means a couple of things.  For one, it means that MMORPG Tycoon 2 can finally use a little more of the CPU time from everyone with a multi-core computer (which is just about everyone with a computer from the last six years or so), and it also means that as more tasks can be moved out into other threads, I’ll be able to do more and more processing without hurting the game’s frame rate.

I’ll also note that Mac OS X’s support for semaphores is half-broken, and Win32′s support for semaphores is bizarre and generally unrelated to traditional semaphores.  Makes me a sad coder.  (for the non-coders in the audience:  semaphores are a tool for synchronising multiple threads, to help keep them from stepping on each other’s toes)

More details tomorrow.  Or later today, I guess, technically.  And semaphores will eventually be ported back into the VectorStorm trunk, if anyone wants to look at them.  Also fixed some bugs in the vsTask class, and added features to the vsMutex.  Will need to move all those changes back to the live trunk in the near future.  Maybe over the weekend.


Aug 01 2011

More on clutter and suchlike

Tag: Full Games,MMORPG Tycoontrevor @ 12:53 am

I’m not certain whether today’s shot is noticeably different than yesterday’s.  But regardless, I’ve made some pretty massive changes under the hood (with some more still to come).

The big exciting new thing from my point of view is that I’ve flipped the switch, and made the generated ground clutter be generated in tiles, the same way that height map data is, just smaller.

The upshot of this is that the game once again runs at well over 60 fps on my old laptop (it had been down to about 40), and with far more visual detail than before.  I’m quite pleased.

Technical discussion follows:

Previously, edge clutter (the grass that was seen in older screenshots) was being generated as part of the height map.  Each ground quad would select one of its edges and sprout another quad of surface detail there.  That surface detail quad was carefully set up to almost exactly match the shade of the ground, just to try to hide or soften the edge.  This worked great, but doubled the amount of geometry being generated whenever I needed to load up a new section of height map, and doubled the number of triangles being drawn.  Additionally, it ended up looking a little “samey”;  all grass everywhere in the world was being blown from east to west, for example.

The other system present was a big list of “ground clutter” triangles, which I was checking every frame, and re-orienting to best face the camera.  This was a big time-sink for the game, moving all those vertices around every frame.

Now, ground clutter and edge clutter are both being generated by a common system, which generates them in blocks around the camera.  This is a big improvement for edge clutter because it means that I can only draw the edge clutter that’s relatively close to the camera (edge clutter is currently in 64×64 meter ’tiles’), and not bother drawing the edge clutter that’s a long distance away.  I was doing this already with the old system, but the height map’s 256×256 tile size made it impossible to draw only the clutter that would really be visible.

Additionally, this is a massive improvement for ground clutter because it means that I don’t need to test every piece of ground clutter each frame;  there are only nine tiles of it (32×32 meters on a side), and I can just decide for each tile whether to keep it or whether to throw it away and generate a new tile somewhere closer to the camera, instead.

The best thing is that I’ve factored out the whole “generating the nearest tiles” behaviour, so a single logic engine is now driving both types of ground clutter, and it’ll be easy to add more things which get created around the player in this way.

I haven’t converted the current height map tiling over to this new system;  the height map tiling works based upon using tiles to fill a circle centred on the camera, while the system powering the clutter works based on using tiles to fill a square.  The square is much, much simpler to handle, but causes the system to create things diagonally more often than straight north/south/east/west.  For ground clutter this is unnoticeable.  For mountains, you really need to see mountains at a particular distance, regardless of which direction they’re in, so the height maps themselves need to stay on the old system.

There’s also some exciting news in the near future.  Can’t talk about it yet, but real soon.  :)


Jul 23 2011

On the pleasures of memory management

Tag: Engine Designtrevor @ 12:38 pm

Error:  Allocation from MMO_GroundClutter.cpp line 42 was allocated using new [] but was freed using delete;  should have been delete []!

I can’t say how proud I was to have had my memory management system be smart enough to print out such a cogent and useful error message.  I’m less certain about how bright an idea it was for it to do the correct thing after displaying the error, instead of crashing immediately.  This error message, for example, has been generated by the game for three days now, and I only noticed it today.  If it had crashed immediately, I would have fixed it at once.

For those who aren’t familiar with the pleasures of C++, a large part of working with the language has to do with requesting and returning blocks of memory (by which we traditionally mean RAM).  We use those blocks of memory to store data temporarily.  Textures, models, various bits of gameplay, etc.  In C, there was only one way to get a block of memory:  you called “malloc()”, passing in the size of the data block you wanted to receive.  And when you were done with that data block, you called “free()”, the same way.

In C++, for various reasons, two more methods were added:  ”new” (for creating an instance of a C++ class), and “new []” (for creating a lot of instances of a C++ class in a big array).  Because these different blocks of memory contain different data and are allocated in different ways, they need to be freed in different ways.  For “new”, you must call “delete” to release the object.  For “new[]“, you must call “delete[]“.  In many memory management implementations, calling the wrong one will cause your program to crash, so it’s important to get this right.

VectorStorm’s memory management system isn’t a fast one.  I should say that up front.  When a game asks for memory, the memory management system does a pretty dumb linear search through its preallocated heap space looking for a spare area that it can hand out.  It also isn’t very memory-efficient;  it allocates extra space before and after each memory block that it hands out, storing information about how the block was allocated, by which file and which line of code, as well as boundary guards for detecting whether something has accidentally written past the end of the block.

These things all make it possible to easily detect issues like mismatched allocation/deallocations, leaks, and other places where programs have accessed memory incorrectly.  So every time I make a mistake about these things (which thankfully isn’t very often), it’s there to poke me with a stick.

It’s worth also noting that VectorStorm’s memory management also isn’t friendly to devices which want to use virtual memory (i.e. almost every modern computer or phone), since it handles all its own allocations inside of its own huge data block.  From the OS’s point of view, a VectorStorm game uses only a single memory block, which is several megabytes in size.  (In the case of MMORPG Tycoon 2, it’s currently about 600 megabytes in size, and will eventually be even larger.  Most of my other games are in the 6-30 megabyte range).

Between it’s lack of speed and lack of friendliness toward virtual memory support (or fragmented memory in general on the target device, as is often the case on, for example, the iPhone), I expect that for any major release I’d swap over to using the regular OS-provided allocation/deallocation functions instead of VectorStorm’s built-in ones.  But for the purpose of development, it’s great having a system like this there to catch errors early.  I know from long experience that it can be a real bear to track these things down otherwise.


Jul 21 2011

Newer ground clutter

Tag: Full Games,MMORPG Tycoontrevor @ 11:10 pm

So I’ve finally settled on a new ground clutter appearance.  I’m really digging this.  It’s subtle, but just lends a bit of texture when you’re down low near the ground, but is soft enough that it completely vanishes once you’re only a little bit up into the air (which means that I can stop drawing it then).

I also noticed that the “Old” screenshot of ground clutter that I posted yesterday was the wrong one;  it actually showed the newer clutter models, just using a different sort of colour.  I’ve now updated the first screenshot in that “Ground Clutter” post to actually show what ground clutter looked like before.  Pretty dire, eh?

Now I’m trying to decide what to do with the mid-level clutter, which is the larger streaky stuff visible in the screenshot.  In my codebase, it’s called “edge clutter”, since it’s generated along polygon edges.  It looks pretty good from the air, but starts looking odd when viewed from down here.  Maybe I fade it out as you get down next to the ground, or something like that.

Plenty of stuff still to think about, I guess!


« Previous PageNext Page »