First off, an announcement: we have decided to suspend development of simultaneous networked multiplayer for Clockwork Empires indefinitely. There are, simply put, technology issues and design issues that we don’t feel we can satisfactorily solve in the foreseeable future. Furthermore, we don’t want to devote time to addressing those issues if that time will detract from the single player experience, which people are currently enjoying and which is the major thrust of the game. Support will exist in engine for round robin “let’s play” games, and we will continue to build that out as we work our way out of Early Access and into a new stage of development, which we are tentatively calling, uh, “Access.” As always, we thank you for your patience and understanding of the harsh realities of game development.
That said, let’s talk about “Access.”
Somebody recently posted on Twitter that polishing a video game was a straight forward process: if it doesn’t move, make it move; if it moves, put a sound effect on it; if it moves and has a sound effect on it, add a particle system. That’s a pretty accurate guide, honestly. In our case, we went into Early Access with a few things that were not in the best of states, and one of the ongoing things that needs to be done in order to transition them from “Early Access” into “Access” is to address the problems that people have with them. In some cases, this is a question of making some changes, watching the feedback, and then continuing to improve the system or re-designing it. Sometimes, such as in the case of cults, or emotions, or what-have-you, we have to take a few swings at this particular issue.
The project I’ve been meaning to tackle for awhile now has been the process by which buildings and modules are placed in game. In the original version of Clockwork Empires, buildings were not intended to be placed by dragging and dropping rectangles. Rather, they were placed by tracing an outline with line segments. While this let you create interesting buildings and all manner of terrifying Euclidean geometry, this also introduced problems: you could only attach a module to a building at a 90 degree angle, so it would be possible for players to create buildings that they couldn’t attach a module to, etc., etc. At a different junction, modules were only ever placed *outside* of buildings. At some point in development – I think in the middle of 2013 – we collectively decided that we needed to be able to have characters go inside of buildings and interact with the contents directly, which is something we originally didn’t want to do because it opened up many cans of worms. After several rather painful iterations, we ended up with the system that we currently have today.
The system that we shipped had a number of problems. The following is a short list, off the top of my head:
- Various things could cause buildings to explode or not render correctly, such as putting ovens in corners in various configurations; alternately, occult roofs could be generated by various Forbidden Configurations of modules. (These have, by and large, been fixed.)
- Snapping was, and still is, a mess. Very often modules will snap to somewhere where you don’t want them to go, violating a UI principle called “The Principle of Least Astonishment.”
- Module placement, by and large, never felt “right”. There is an expectation that the module in game will be as centered around your mouse as it can get, and that was never really satisfied because we would center things, as much as we could, around the current… vertex? Square? What? And then snapping happened and that got weird too.
- No visible feedback to the player about where they were dragging their building tile to, and building tiles corresponding to vertices and not to tiles during the selection process.
- Various other issues involving creating a module, and having that module move from the rendering thread, to the gameplay thread, back to the rendering thread. In particular, this could create a very laggy and unresponsive module placer.
- Various issues where you could place buildings next to each other and not have A Good Time, or have modules placed into other modules, or putting farms under modules, or various other sorts of Forbidden Configurations.
- A recurring crash when placing multiple modules.
- Footprints extrude from buildings too far, and don’t match the footprint of the module.
- General other problems with moving and deleting modules consistently.
There were also the following technical problems, and a lot of these technical problems prevented us from addressing the UX/UI problems identified above:
- “Who the heck owns the blueprint data?” A lack of clear ownership semantics in the codebase meant that the relationship between a building, its modules, and the footprint was never clear. This is because the code was originally written for a system where buildings had modules attached to them, and stockpiles were also always building attachments, and then stuff kept getting shoehorned in and refactored and so on and so forth. What a mess. This, in particular, was causing the recurring crash when placing multiple modules, where various “child modules” would never be correctly linked, or de-linked, from their “parent” module, but sorting this out meant a journey through data structures that humankind was not meant to probe;
- When we rebuild something, say after moving a module, we don’t do a good job of propagating the changes downstream, because – well, we don’t know who owns the blueprint data. So things like footprints don’t regenerate themselves cleanly after you move them or delete them.
- Orientation of modules was… well, complicated to work out, because all orientations were defined relative to the center, and the center of a module would be ambiguous for something like a 2 x 3 module (where is it centered in game? Where is it centered on the renderer? Help!) This ended up in a mass of sign-juggling, across two different systems (the spatial dictionary, which stores all game positions and tracks all entities in game)
- General legacy code and various stinks and messes.
- No good support for standalone modules, which are not attached to a building; this blocks various things like conduit generators, bunkers, and turrets.
- How the heck are we actually going to add conduit inputs and outputs to this thing, anyhow?
I have sort of known that a full scale rewriting campaign would be necessary to get these things dealt with in order for us to ship Clockwork Empires, but the time had never been right until the start of this month when I finally snapped and decided to start rewriting things from the ground up. I made a few key architectural changes:
- Module templates can now exist free from buildings, and don’t have any common ancestry with them. (Previously modules and buildings were both shoehorned into the same class structure, which is one of those decisions that made sense back in 2012 but right now is just a bad thing.) Because all of this is now clean and separated, things like “adding things to the right scene graph” and “removing things from the render tree when you switch into, and out of blueprint and regular mode” are now much easier to work with and debug. No more trying to figure out why the access points disappeared on a model.
- All rotations for modules are all calculated relative to the upper left hand corner of the module model (which is how it’s actually set up in the actual model.) We still want things to feel like they are centered with respect to the mouse, but we now just translate *once* instead of *all over the place*; a clear win.
- Module templates and building templates now have a local ID and a local player ID. This means that we can re-link a building and a module with the templates you created across threads, whereas if you get a building or a module over the network (or in a replay) we will recreate them for you.
- Zone templates (stockpiles, farms, graveyards, roads) are now their own things.
One major issue we’ve had in the past is that it is very hard to visually debug obstructions and the like; the spatial dictionary lives on the game thread and the renderer lives on the render thread, and they don’t really talk directly. Consequently, the game lets you dump out all the obstructions in the game to a SVG file for debugging purposes, which is fine but you have to load the SVG in an appropriate viewer and then figure out which way is up on the screen etc. I threw a wobbly fit and added code to display the spatial dictionary obstruction data directly on top of the terrain, a code change made possible by a previous cleanup pass I made to fix some rendering issues with the grid flickering in and out on AMD cards. That turned out to be very helpful, especially in trying to rewrite the portion of the spatial dictionary code that computed obstruction information for modules. Without a visual aid, that would have been impossible; as it was, it took me a day of cursing and swearing.
I’m hoping to get the first version of this deployed into the experimental build stream early next week, so that we can bang on it for a couple of weeks and get all the bugs out. As building things is one of the key feedback loops of the game, it’s hugely important that it feels fast, fun and responsive.