New year new dimension (aka 3D maps!!!)
Not gonna bury the lede: inspired by another project in the Lancer community, about two weeks ago I did a quick tech demo to answer the question “what would LT look like rendered in 3D?”
Unfortunately, both I and everyone I showed it to really, really liked it:
I say “unfortunately” because we’re a lot later in the development process than I’d like for this kind of change AND I have almost no experience in 3D games. 🙃 But I would be a fool to ignore this clear an experimental result!
Moving to a 3D map solves these problems:
-
Depicting elevation. We’ve been jumping through some pretty wild hoops to try and depict size 3 terrain without obstructing the tiles above. A 3D view allows for more interesting and taller terrain-shapes and covering up tiles is fine because the player can rotate the camera.
-
Handling cliffs. The most complicated part of the map system was handling having cliffs in-between tiles and the auto-tiling system to select the right graphics for given elevation data. There was a whole second tilemap offset by half a tile in both directions for cliffs over top of the ground — which meant there had to be a system of sorting z-indices for units on both the ground and elevation layers. Putting stuff in 3D space handles visual ordering for free.
-
Destructible and constructable terrain. It’s gonna be so much easier to make a crater the size of the moon from a charged apoc rail or for a Kobold to play minecraft by being able to add and remove voxels at will and have the engine set up to handle it.
Reasons this is not a huge change of scope that will sink the project:
- I’ve been doing an AMAZING job keeping the game logic separate from the view layer. It’s a common backend engineer’s fantasy to be able to say “yeah you can just swap out the frontend for a new one” — and we’ve actually done that! The circled areas here are the only things I’ve had to change so far: only stuff that handles rendering to the map-space.
-
We keeping the style of lowish-res pixel art. We’re not modelling the robots in 3D or animating them; they remain billboarded 2D sprites. I think we can make the game look good with this style (3D pixel-art-esque games are somewhat in vogue right now) AND this will be easier to pull off with our limited 3D experience. The only change is that the map is rendered with 3D voxels instead of 2D tilesets.
-
Well, that’s not totally accurate; the one data-level change that I have had to make is a more nuanced system of figuring out what properties the terrain has at any given voxel; a blast-1 smoke bomb should not affect a cliff 4 tiles up (this is that leftmost little red island on the graph above). But I’ve already made the appropriate changes and it took like two days soooo no worries there.
I feel like expanding on that last point: under the hood, this is still almost entirely a 2D game. This means we have decided against allowing overhangs (e.g. no archways, walking under bridges) or stacking flying units up on top of each other (flying is still an on/off status rather than giving you precise control of your height). This hedges out a tonne of edge cases and will allow us to proceed with the current engine without too severe of a speed bump.
Show the goods!
Now that I’ve justified to myself and y’all why this idea is good and feasible, let’s see where we’ve gotten two weeks out from that initial test!
Once I got the new cursor hooked up to be able to point at a tile (harder than it sounds; you have to do raycasts and have collision shapes and there was a Godot bug on those that cost me half a day), it was just a matter of feeding that current-tile data into the engine and the event system happily moved units around like we’ve always been in 3D.
Our current approach for ramps is that they’re going to count as elevated tiles, but be cheaper to walk up (no half-speed climb penalty) and will render units on them halfway between their raised and lower parts.
We briefly discussed and discarded the feature of dynamic water tiles. They raise too many questions when combined with destructible terrain. I ain’t simulating minecraft or dwarf fortress here. Instead, it’s likely that we’ll let the level designer choose a z-level and have everything below that be “underwater”.
As a bonus side-effect of space rules being the same as underwater rules, this’ll give us zero-G maps for free by choosing the maximum water level and making it look like space instead of water. Game design! :)
I’ve also got multi-voxel objects loading in correctly. These have a “true” origin voxel, but cast out a rectangular area that intercepts requests for terrain at those voxels and feeds the request its own terrain data. There’s nothing actually at those voxels in the map file, but the game acts like there is. It works on rotated objects via the sort of 3D math I’ve spent my life avoiding up to this point (meet Quaternions).
(Those hangar buildings are from this Kenny asset pack! I expect to lean on his resources a lot in the coming months.)
Here you can see me learning how to manually generate meshes from terrain data. In order to show tile ranges (for movement, attack, line of sight) I need a “shell” mesh that sits on top of the terrain like shrinkwrap. I can then draw a texture on it with the same 2D shader I described here to get the final effect:
And finally, this morning I got 3D bezier curves working for movement preview lines:
What’s next?
As surprisingly easy as switching to 3D has been, it has taken and will continue to take time we weren’t expecting. A vertical slice for early access backers is still months off — I’m still hoping for Q1 next year, but I’d say it’s likely that’s going to slip.
Remaining todo items to catch up 3D to where we were in 2D:
- convert the attack and ability effects to use 3D
- different textures for the edges of terrain cubes
-
texture variants for terrain types (so not all grass blocks look the same)
-
getting 2D UI to position itself correctly relative to the tile it’s relevant to
- update the mission editor to use the new 3D maps
After we get those done, I be back to hooking up the player-facing UI (e.g. alternate actions e.g. melee vs thrown), character sheets, and working towards that treasure of a shareable early access demo.
Carpenter and Martina have been hard at work on the pilot portrait creator. I don’t have a good picture of it, but we’ve gotten masking layers working which allows hats/hoods to stop hair from poking through and skin-wide texture modifications like tattoos, scars, and short beards. That’ll definitely be ready to try out as a standalone program sometime in the next few months.
Happy new year! If you choose to celebrate, please do so safely and covid-consciously! Also it was my birthday a few days ago and I’m 33 now! Cool!