Devlog: Modularizing LumotePreface: You may notice this looks very different than what we have now. Lumote used to be a crystal creature in a high pressure cave system full of inorganic life... I'll make a post about that evolution in art direction in the future.
DisassemblyWhen we initially set out to take our UE4 game jam entry
Bump and extend it out to be Lumote, we knew we wanted to make it one giant map. The game is extremely dark and as you progress you illuminate the world. Because of this, we wanted to not only give you some larger sense of progress, but also offer some nice vistas to show where you've been and what you've accomplished along the way.
The blue glow of discovered checkpoints and solved puzzles lingers in the distanceWith that in mind, we started laying out the world. It's made up of a central hub surrounded by towers; you go up one side of a tower and down the other where you exit into the hub and progress to the next tower. We began by roughing in the flow of the first tower, making sure you can't reach places you shouldn't, and winding around so that you can get some nice views of where you have been. As we progressed, we were also building the puzzles which fit nicely into the flow. However, we soon came to realize that constructing the world this way caused some problems.
Each coloured section is a different puzzle in the tower.First of all, the entire game world was in a single file. This meant that we could not iterate on the high level flow of the world and design new puzzles at the same time. We knew this would be an issue in advance but made the concession that since there are only two main level builders, we could work around each others’ schedules.
Secondly, we have always had aspirations for
Lumote to offer either user-generated puzzles or procedural world assembly, or maybe even both. While this isn't a feature on our road map for the initial release, it is something that we would love to see one day. That means, having the entire world as one massive asset really limits the possibilities.
The third, and most important, issue was adjusting difficulty and pacing. Each time we added a new puzzle, there was often the realization that we had made something that would be more appropriate earlier or later in the game. Often this meant that all edits were destructive, replacing a puzzle literally meant that the old one was gone. If it was really good we might save off a copy of the map so we could isolate it and reuse it later, but that wasn't ideal and became quite time consuming.
Modular level sections can be swapped out and rearrangedAfter getting back from GDC 2016, we started discussing how we might overcome these problems as we continue to build out the game. The result was a fully modular version of the world, where we can snap puzzles together and easily swap them out or reuse them to adjust the pacing and difficulty of any part of the game.
Left an example of the hard to work with monolithic world. Right same area but in the modular world.As you can see in the above example, this area is roughly the same before and after modularization.
Puzzles & ChunksSo now that we have this plan to break up the world in the individual puzzles that can be reassembled in any order. The first step was deciding a minimum size that a puzzle could be. All puzzles will be required to fit within a box that is a multiple of the minimum size in order to easily snap them together.
Voxel engines like the one in Lumote generally work by segmenting the environment into smaller pieces called chunks. These chunks allow for local modifications to be less computationally expensive when recalculating rendering and physics information. As it turns out, our levels happened to be almost exactly a multiple of our voxel chunk size which is 32x32x32.
For my sanity and yours, I'm going to present the world as a 2D grid through out this post.
Purple lines are level boundaries, green lines are chunk boundariesReassemblyWe need to define a box for each level to fit in. Levels aren't restricted to a 32x32x32 cube, they can be any box but the box dimensions are always a multiple of 32 voxels. Once we've properly defined the box for a level, we specify up to 4 evenly spaced connection locations on the vertical faces of the level. Pink for exits, and blue for entrances. This configuration allows us to define modular levels that are can be almost arbitrarily arranged while not restricting the internal design of the levels too much.
Blue entrances, pink exits. Levels can be any dimension of boxOnce all the levels have their bounds defined, we use a custom flow charting tool to define the connectivity of the world which is then used to create, rotate and translate the levels that form our world.
Some possible level arrangements based on the 5 levels in this exampleFilling in the gapsAs you can see from the above level arrangements, we just have a bunch of floating levels. Lumote is a single world, there are no level load screens, just one big puzzle game all visible to you at once. This means we can't just have a bunch of weird floating platforms everywhere, we want to make the levels feel grounded and solid. In order to fill in all these missing walls and pillars, we enlist the help of our voxel engine and we simply extrude lowest part of each level downward to infinity.
Extruded final worldAnd finally, here is an example of a bunch of levels all stitched together using this system, this constitutes about 26 individual puzzles.