
Very minor update today, since I didn’t have much time to code, but got a few things implemented.
First, VectorStorm materials now have an optional “layer” value. This value defaults to zero. Within a scene, material batches are drawn in order, according to increasing “layer” values. This allows us to force transparent geometry, such as the extending arrow effect, to draw later than opaque geometry, such as the ground surface. Note that this only works when rendering is performed via the material batching interface on the vsRenderQueue; materials applied by directly setting them within a vsDisplayList will render exactly as requested within the vsDisplayList.
Second, I’ve been removing lots of old, dead code. Most notably, I’ve now removed the carcass of the old combat system. Now that players and monsters are attacking each other using via configurable attacks, the fake old system really isn’t necessary any longer. The Player AI really needs some serious refactoring; I’m probably going to spend the weekend trying to massage the code into a simpler and more extensible state.
Setting up multithreading code is complicated!
Here’s what’s new:
- Set up a generic “task management” system for MMORPG Tycoon 2. Systems generate “tasks”, and tasks are assigned out to worker threads, which work on those tasks, and then let the main game know when the tasks finish. Heightmap building now uses these generic worker threads, instead of having their own threads. Right now, there are eight worker threads. But in theory, it’s probably best to have the same number of threads as the user’s CPU has cores, potentially plus one.
- Clutter generation stuff occurs using dedicated threads. I need to convert these over to use the new generic worker threads.
- The game now waits for all queued up tasks to complete, before rendering the next frame. This fixes some problems I was having before, where different blocks of terrain were updating at different times and not matching each other, just due to how long they took to calculate in the background threads.
- Fixed some issues with my OS X semaphore implementation (since OS X doesn’t support unnamed semaphores, for unknowable reasons).
- Worked around a renderer bug, where anything which had no texture was being drawn opaque, regardless of its material settings. This affects the live trunk, too; I’ll bring the fix across at the same time as the various threading fixes I’ve mentioned in the past week or so. (If anyone needs a quick workaround in the meantime, just remove the line “m_state_SetBool( vsRendererState::Bool_Blend, false );” from vsRendererSimple::SetMaterial() on VS_RendererSimple.cpp, line 958.)
And now, I’m completely sick of dealing with the complexity of threads, and so the next thing on my list will be more player AI. I think I’m going to work on making players assemble into parties that do quests together. That ought to be entertaining.
And it raises some interesting questions, which actually come up in the development of real MMORPGs; how to handle characters who are of differing levels, but who want to team up — ignore it? Boost the level of the lower character? Lower the level of the higher player? Not allow teaming between those characters? And worse, what do we do when a character completes a quest multiple times, accompanying different party members. Do they get the reward multiple times?
My understanding is that most modern MMORPGs now give credit for completing a quest again in this sort of situation, but older MMORPGs often will not give repeated completion XP. I wonder whether I need to make this configurable for players, or whether I should just take the modern approach and assume that that’s what everyone will want.
Lots of stuff to think about!

Apologies for all the similar screenshots lately; it’s what happens when I’m working on the behind-the-scenes tech, instead of new features.
So I’ve finally finished converting the world across to being generated in a background thread. This means that as the player moves around the world, there are no longer any frame rate stutters as new blocks of terrain are created in front of the player. I’ve also dramatically simplified the world rendering code, which comes as a tremendous relief.
So now that I’m not worrying about performance, I’m going to be diving back into more detailed world-building. Which should mean more interesting screenshots in the near future!
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.
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.