First person dungeon crawlers, 90s style, in a modern game engine? Here's a rundown of how we made one in Unity in 2019.
Most 90s dungeon crawlers, ours included, are just glorified spritesheets arranged to look like a hallway. While technically we are in a 3D game engine, we don't render any meshes. The dungeons are just grids made of different types of blocks, stored in a map along with encounter and object data separately.
To display any given perspective, given an [x, y] coordinate on the grid and cardinal direction the player is facing, we can compute which pieces of the walls to render. If a block is directly in front, show the largest flat wall. If there's one 2 spaces ahead and to the left, show the correct side panel for that distance. Every block in a certain radius of the player will determine what sprites are visible.
A setup like this requires a lot of art assets. We ended up having about 15 different sprites per block type, or in our case around 100+ sprites per tileset. And that's before considering objects, environmental decorations, or animations.
Slap on a static background and you've got a wall and ceiling...
So using an array of sprites, a grid-based rendering system and an orthographic camera to display it, we've got the bare minimum for a 2.5D dungeon crawler. It's very flat, and movement is restricted by tiles that the player basically teleports between. It feels meh.
Thankfully, movement is pretty easily faked, and this is where a 3D engine comes in handy. Walking in Backspace Bouken is essentially just a brief zoom into the current frame, followed by a snap back and an immediate re-render, now standing on the next tile. A small "bob" of the camera gives the feeling of taking a step forward. Well, either that or it gives you motion sickness.
So walking is easy, but what about turning? Turning is harder.
If you want to render 2 directions at the same time in a system like this, you're gonna need more setups. And they're cheap, so why not just have one for each direction?
But remember, we're using a very targeted orthographic camera to render 2D sprites to screen positions, so we can't just rotate around these in 3D and expect it to look like it should. Instead, we render each setup to a Render Texture and rotate around those.
Render that view to yet another Render Texture and into a UI/frame and you've got a basic idea of how the game works under the hood. You can render all sorts of different objects with this system too by simply placing them "inside" the blocks you render onscreen and having sprites for every distance of block.