Hello, it’s been a while! My intention was to update a dev diary for my Haunted PS1 jam game every couple of weeks or so, but in the end I struggled to find the time, and it was all I could do to get the game finished before the deadline. Now that I’m finished (and have spent a week working on a patch to fix a few issues and add a few things that didn’t make it into the original build), I figured I’d write up a bit of a post mortem talking about the process of making the game.
Given that in my previous post I had just finished prototyping the spline-based 2.5D movement and camera, I’ll pick up from there. The next thing I did was make it so that you can move between two different splines. This was actually a little underused in the final game (which ended up being fairly linear), but it allowed me to have branching paths.
In this video you can see the initial path the player is on; the first box they pass through is for switching to the spline they are already on, so this does nothing, but the second box switches them to the upper path, which allows them to move around the corner, rather than going straight. Something else you’ll notice from the video is that it looks a bit more like a PS1 game than it did before. This is due to a post processing filter that emulates the dithering algorithm used by the PlayStation. Alas, I don’t have the technical skill to have made this myself, but it is thanks to a Twitter thread by Jazz Mickle. Another material I used comes from this thread by Lilith, the developer of BloodbornePSX, and emulates the PlayStation’s affine texture mapping and vertex snapping.
On the subject of the PS1 look, I took a few liberties with it, so I wanted to talk a little about my reasoning for doing so. The poly-count and texture size are fairly accurate; I kept the character to around 700 triangles, the walkways are generally about 30 polys apiece (I used masked textures for the railings and mesh), and there are never more than 100 in a single room, so we’re looking at a maximum of 3,000 triangles. The rooms are a slightly different story. Initially I made them as cube where each wall was divided into two triangles, but because of the way the affine texture mapping works, this caused some major distortion in the way the textures were displayed. As a result, I subdivided the walls into (generally) 8x8 squares, so that each triangle took up less screen space, and therefore suffered from less texture warping. As a result, the polycount for the rooms is generally at around 900 triangles. However, combined with the player and all of the walkways and other objects, I’m fairly confident there are never more than 10,000 triangles on screen at a time, which is the PlayStation’s limit. The textures are also all either 32x32, 64x64 or 128x128 pixels, which is consistent with most PlayStation games I’ve looked at. The result of this is below:
Where I’ve been less authentic is the lighting. I did initially look into ways of doing vertex-based lighting (as opposed to Unreal Engine 4’s lighting, which is calculated per-pixel), but this was hard to do, and after spending a day on it I couldn’t really get it to work right, so I gave up. I also considered having everything be unlit, but it would have been a lot harder to achieve the kind of atmosphere I was going for. In the end, UE4’s lighting was the nicest solution, and the easiest to do quickly, so I took an authenticity hit in the service of getting a look I was happy with. It’s also worth noting that because I didn’t have to worry about memory constraints, I was able to load the entire facility in and have you go seamlessly from a title screen into the game and all the way to the end without having to load or unload anything, but this would definitely not have been possible on original PlayStation hardware. In general, though, I think the game still evokes the look of a PS1 game, which is what I was going for.
So, to go back to the development process, after getting the basic movement mechanics working, I started building the facility using UE4’s BSP (Binary Space Partition tools). This let me play around with the layout and basic level design without committing to modelling anything before I knew how it all fitted together. This is what I ended up with:
As you can see here, I’ve decided on the number of rooms that I felt comfortable with modelling in the time allotted for the jam, and set up walkways for the player to move around on. As I was doing this I was setting up splines, so it was possible to move from the start of the level to the end of the level. I also implemented some basic puzzles as I went along, which meant building a few more mechanics: switches that can be interacted with, doors that open when the relevant switch is pulled, and camera transitions for showing which door opened (I could probably have left this until a bit later, but I wanted to get a feel for how obvious it would be which door you’d just opened).
When I was happy with the flow from start to finish, and was happy that I wouldn’t need to change too much going forward, I exported my BSP mesh as an FBX file and imported it into Blender. I was then able to take the individual rooms and walkway pieces, clean up the meshes, UV-map and texture them, set up collision and bring them back into the game with minimal fuss. In all I think it took me about two weeks to do all of this; I hadn’t done a lot of environment modelling before, so I was probably a little inefficient in places, and texturing is still not something I’m great at. Here’s how the facility ended up looking, with the exterior mesh and without it:
A couple of notes here: the black areas around the three hallways are there so that you can’t see through the back faces of the rest of the level geometry; this seemed like the most elegant way of handling transitions from outside to inside, so it blacks out the top and bottom of the screen. When you then move into the larger rooms I don’t have to worry about the camera passing through the walls, because I can move it into positions where this doesn’t happen, which isn’t possible in the narrower spaces. Also, the reason why the walkways and pipes look more and more lumpy as they get further away is due to the vertex snapping that I mentioned before. I probably could have turned this off before I took this screenshot, but it didn’t seem like that big of a deal!
That’s all for now; in the next post I’ll look at how I got the game to look and feel like it’s underwater, with particle effects and sound effects, and how I set up the various events that happen throughout the game. Thanks for reading!