It’s truly liberating being done with the graphics arc (at least for now; I’m 100% sure I’ll find things to work on!). It’s like uncorking a champagne; suddenly ideas and features are gushing out at super-speed. I’ve built up quite the backlog over 6 months of graphics work, so I’m working through the game one area at a time bringing it up to where I want it to be – and also trying to expose the player to some of the depth the system already has.
Entertainingly enough at the beginning of the week I applied a Visual Studio update and recompiled. Most things worked fine, but one function that has performed admirably for months was suddenly super slow. I painstakingly profiled and improved it on the algorithm level (I wasn’t being as efficient as I could have been), and got it back to speed. Then on Friday, VS updated again (including the C++ parts, so another rebuild) – and the old function was fast. Fortunately, the new code was now even faster – so I stuck with it. Really not sure what happened there!
Yes, I know I said it’s done… but a few enhancements came along quickly and easily this week.
- ASCII mode replaces tiles that are “open space” with tiles from lower depths (up to a maximum, currently 5), and darkens the tiles. This gives a better sense of where you are (it’s a DFHack add-on for DF I’m particularly fond of).
- ASCII render mode is much more careful about background selection, so floors aren’t too loud on the eyes. Walls are properly bitmasked, too.
- Fixed a bug that was updating 3D chunks when you weren’t in 3D mode. Enjoyed the performance boost.
- ASCII water color has a bit of variance (noise-based), since 3D mode has it I thought it should share.
- ASCII mode has bloodstains once again.
- ASCII mode cycles between glyphs when there are multiple renderables sharing a tile.
- ASCII mode now displays particles. It uses the same particle system as the 3D game, but the positions are translated to terminal-space and displayed as glyphs.
- I bit the bullet, and ASCII mode now has GPU accelerated lighting! It uses the lighting path in the 3D engine (rendering cube-map depths for lights), and does a coordinate translation to use the same values in ASCII mode.
- Blight (the state left by ant monsters and other creatures of the void) now has a proper texture. It was oddly pink before.
- Mounts are now rendered. Badly. I need to improve this so it doesn’t look like cavalry are stuck partly inside their horses. It’s still an improvement, it wasn’t obvious that natives HAD a mount before. This is also the first-step of a future vehicle system.
- The 3D engine is now double-buffered, with mouse lookups happening on the previous frame’s buffer. This eliminated a big OpenGL stall. I figured this out from an article on how Unreal does rendering. (Basically OpenGL draws are async, but reading the result causes the whole pipeline to stop until it’s caught up. Reading the previous frame’s buffer means that everything has to be rendered already – since it was displayed – so no pipeline pauses)
I’ve been trying to expose some of the game’s depth in the GUI, by showing you what all the things do. I’m also trying to make less of a UI disaster.
- The Units List is now tabbed, and tabulated.
- The Settler Info panel is now tabbed, tabulated, and has placeholders for systems that are coming soon.
- You can select an item and view it’s details in the new Item panel. This shows off a lot of the depth in the system; items now display a description, their creator, quality, wear, and tag-type. What you can do with the item is outlined, as is from what it was made. Armor tells you exactly how useful it is, including various “hidden” modifiers (quality, material, and so on). Weapons and ammo likewise. It’s still uglier than I’d like, but it’s really useful! Items tell you what they can be used for, if they are a component (this is automatically derived from the raws).
ECS and Engine Work
There have been a few things about the underlying ECS that have bugged me for a while, so I set about fixing them.
- Did a housekeeping run, removing a few templates/systems that aren’t used anymore. Faster compiles, less confusing code.
each_without. I’d fallen into a pattern of doing a query such as
each<item>and then querying the resulting entity to see if it did not have a tag, such as
each_withoutshort-circuits this by excluding any entity that has the first tag type. So
each_without<claimed, item, item_type_chopping>will give me all of the existing items that can be used to chop down trees, excluding any that are marked as
claimedby a settler. This provided a LOT more of a performance boost than I expected, and it’s mysterious as to why – my guess is cache coherency.
- Items used to store their category as a
bitset. I did a lot of “find item, check bitset, proceed if true”, which was inefficient (and not really how I like to use an ECS). So each of the bits has been replaced with a “tag component” (that is, a component without any additional data). So now I can query for
each<item, item_type_chopping>and just get lumberjacking tools. Code is easier to read, and performance improved – so a double-win.
- Items now have
creatorcomponents. Quality can influcence damage, and reduces the rate at which an item wears out. Wear worsens over time (subject to quality), and worsens a LOT in combat. Items can wear out and fall apart. I’ll need to get a repair mechanism in there in the future, and make settlers a bit more eager to replace items – a long, heavy battle can leave you really short of items. I also need to work on verbage a bit, there’s something wrong with having your skirt shot off…
- Tracked down ALL of the ways in which items could be created, and forced them to go through a single code path. This fixed several bugs, and ensured consistency.
- Created a bunch of voxel models, and began cleaning up ASCII glyphs for items on the ground. This is tricky, there can be a LOT of items lying around after a nasty battle.
- Fixed corpses. They were invisible, which wasn’t what I had in mind.
- The new settler information panel. There’s quite a bit here that is aspirational, such as relationships and mood. It’s much nicer than the old mess of text, though.
- The new item panel; it’s not finished, but shows relevant data. It’s hard to expose the ridiculous amount of information I have for each item, but this is a good start.
- The aftermath of a battle in ASCII and 3D. Corpses, blood-stains and items everywhere.. It was an epic battle. I declared war on the “Renfro Kindred, of the Central Cozy Savannah”, a human tribe of nomadic raiders (mostly on horses). They surged forward in waves, while the brave settlers fired their pistols through the ship’s windows and the turrets fired as fast as they can. After six days of battle, ammunition was almost exhausted – but the Renfro Kindred lay dead around the ship. The damage system doesn’t affect mounts yet, so all of their horses are waiting patiently for their dead riders to return (you can hunt them and make horse roasts, if you want…)
- ASCII mode before lighting. This shows off a few things. The camera is on the middle-deck of the escape pod, so you can see inside – with all the settlers and their cryogenic beds. The exterior is on lower levels, and is showing because of the “deep dive” code. Notice how it darkens on lower elevations. Lastly, tiles with multiple renderables are cycling through. The flashing in Dwarf Fortress tends to inspire me to tidy up, or warns me that a bad guy is mounted. Get some lighting in there, and I’ll have some pretty decent looking ASCII!
- ASCII battle scene, showing off particle effects. This is the same code as the 3D version, but the laser beams are translated into ASCII-space. I’ll probably improve the glyph choices, but the basics are there. Definitely needs some performance improvement!
- ASCII mode lighting – colored light inside the ship, streaming out of the door. This is the underlying light map, generated on the GPU using the same path as the 3D lighting.
- ASCII mode – dawn. The sun is starting to come up, and we’ve zoomed out a bit. Shadows are cast, which combined with the deep-diving effect gives some pretty nice (if too dark – I’ll fix that) light/shadow in ASCII mode.
- Oh dear, I’m stuck inside a horse. Please send help.. It’s great that locals show up on their mounts now, I definitely need to work on the rendering.