Game Developer Joakim Larsen spoke about the development process behind the upcoming Titan Station game, talked about gameplay mechanics, and shared a comprehensive breakdown of the lighting setup.
Hey, I'm Joakim Larsen, and I live in Stockholm, Sweden. I grew up on a farm in the north of Sweden and, after finishing high school, started working at a call center and then IT. Work had me move down to Stockholm. After a couple of years, I realized that in Stockholm, I could actually work on something I care about – 3D art and games.
I started studying 3D art, worked hard to build a portfolio, and got a chance to work at DICE on DLC for Battlefield 3 and then Battlefield 4. After DICE, I went to Paradox and worked on Hearts of Iron 4 and Stellaris. I was enjoying my time working on research and pre-production for a new game, Crusader Kings 3, when I got an offer for the job I'd dreamed of back when I decided to become a 3D Artist – a Hard-Surface Artist. Starbreeze/Overkill needed a Weapon Artist to work on their The Walking Dead game. For almost four years, I was churning out hard-surface models and really enjoying my work.
All in all, I have worked on big games, small games, canceled games, and DLCs for various games, doing everything from characters to grass textures.
The Titan Station Project
As Starbreeze/Overkill was going through tough times with the failed release of The Walking Dead, the idea of making my own game grew. What can I do? What kind of games do I enjoy? I have played and enjoyed games like Gone Home, Firewatch, and Tacoma – maybe I could make one of those games?
I and my wife had just had a baby boy, so I thought it would be a brilliant idea to resign and live off my savings while I make a game by myself. I have always been a jack-of-all-trades kind of guy, so to do the programming, come up with a story, write dialogue, art, lighting, and so on was intriguing – how hard can it be? The plan at first was to make a really simple, very short game and then get a new job after like a year. But as I worked on it – it grew and unfolded into more than I could have hoped for.
With the story I wanted to tell and with the scope I had, I decided that a sci-fi setting would be best. I have always loved retro sci-fi. Before all the "floating and transparent magic screens" of today's sci-fi. So, what better place to draw inspiration from than Alien, Space Odyssey, and Star Wars? The game Alien: Isolation tackles a similar kind of retro-futuristic design and was also an inspiration. Mix all that with the interior design of the 60s-80s, the sunken lounges, the carpeted floors, the strong colors, the lines of colors and you get Titan Station.
Choosing Unreal Engine
The first time I used UE was back in the Unreal Engine 3 era. Then, I was blown away by how competent, robust, and fleshed-out the engine was. During my years in the industry, I am yet to use a better engine.
One of Unreal's biggest strengths is that it's well-documented in every aspect. Do you have a problem? Google it – someone else has probably already tackled it. Can't understand how a system/function works? Open the documentation, or go to YouTube. Still not sure? Open the example level and see how it's done.
Another huge factor was Blueprints – the visual scripting/programming language of the engine. Titan Station is made using Blueprints.
The freedom Blueprints offer is fantastic. I could, all of a sudden, do a lot of things all by myself. I did not know how to use Blueprints when I started this project, but it was relatively easy to pick up and learn. Did I mention that Unreal is well-documented?
Thoughts on UE5
What I am most excited about in Unreal Engine 5 is Lumen. Baked GI is a lot of work, making lightmaps, waiting for bakes, and iterating on it. The GPU baker sure helps but Lumen will make it even faster.
Nanite is exciting as well, of course, but I never once had any problems with poly-count in this project, even though I beveled most of the models so as to not have to spend time on baking. I don't have LODs in this project either.
Creating the Game World
My general production plan was to not make anything proper or final until it was 100% certain that this asset will be used. This rule applied to everything – art, sound, blueprints, and so on. For the longest time, it was just colored boxes and blockout meshes. That takes a lot of self-control but it definitely paid off. I could easily and quickly toss away work and redo it.
Most of the assets in the game are hand placed but I did use some grouping and such to make it easier and faster. I knew from the start that I would have to make kits to make this station on my own and I think every asset is used at least a couple of times. Most of it is modular kits that snap together nicely (most of the time..)
I made some use of Editor Widgets. Simple scripts to replace assets or add something to an asset, or count how many lights are used and such. It's very useful and I will use it heavily for upcoming projects.
If I were to do it all again – I would definitely make blueprints with construction scripts or Editor Widgets to generate the placement and such.
All 3D was done in Maya, some cloth simulations and such were done in Blender. For the Titan surface, I used tweaked and optimized Megascans assets. A friend who works as a Character Artist made the character and the first-person hands/arms.
The main idea was to not have any gameplay. Basically just follow a story delivered by radio, computers, and things you pick up and read. Sounds crazy, right? But it's been done before in games like Dear Esther.
I feel that shooting down hordes of enemies rarely does it for me, it usually gets in the way of the good stuff – with that said, I loved Wolfenstein: The New Order and the 2016 DOOM. Looking back at games like Bioshock: Infinite, it's not the endless murdering I remember fondly from it. It's the story moments and places I visited. When replaying it, I just want to cut out all the shooting.
Gameplay can also sometimes feel forced, like "OK we need to have some sort of gameplay here." That can often feel out of place and not fitting with the story or the world.
In the end, I actually ended up with some gameplay, since it fits with the story and the world. As you go into cyberspace, you have to do some connecting of boxes and mixing them. Each time you go into cyberspace, it gets just a little more challenging or different.
In playtests, I saw that players quickly get bored of doing the same thing several times, not very surprising, so I cut out a lot of stuff to have each puzzle be different enough, and when you have done all the puzzles, you will have learned something you will use to "defeat the final boss."
Setting Up Lighting
Artistically, I wanted the lighting to be dark to light and never flat. The shots below illustrate this. You are in the dark section, you can see light streaming in from outside of the station, but in the distance, you see the brighter section.
I wanted exaggerated fog and smoke and I wanted to be able to walk around inside the station and look out at the exterior of the station and see Saturn and the elevator going down to Titan.
Technically, this made me go for a static, baked lighting solution, so I could get Global Illumination. This was not without its challenges. The fog and lighting system is made to be used on the ground, with a horizon and a sky – not space. It took quite some tinkering and hacking to get this working.
Static and stationary lights do not cast light shafts for the volumetric lighting. It gets baked down to the volumetric lightmap and it does a good job on a big scale, but for smaller scale such as cables casting shafts, it's not feasible.
I´m using a moveable light only for the shafts, tweaking it so it hits as few objects as possible so as not to create any sharp shadows and cost as little performance as possible. A static light in the same position is also there to render GI and nice soft shadows.
As I was getting tired of waiting for the static lights to bake using the CPU lightmass I was looking into GPU baking in Unreal – I found out that Unreal would get GPU lightmass. I started using it as soon as it was available, and it saved me a tremendous amount of time.
GPU lightmass has a limitation of 256 static/stationary lights when baking. Maybe that doesn't sound like a problem, but I am doing a whole space station with several sections with only a level change when going to Titan. The limit of 256 lights, in that case, is hard. The solution was to use emissive materials whenever possible and complement them with a movable light for volumetric lighting.
For some emissive materials, I have set up values, textures, and such in two versions. One for baking and one for when the game is played. It's using a material collection parameter to change which one is used.
Another challenge with GPU lightmass is that geometry gets in the way. Windows looking out to the station, for instance, had to not cast shadows so as to not block the incoming light from the sun. It had to be its own mesh with Cast Shadow unticked. This goes for any case you want a light behind geometry baking light, either have it as above or do a material collection swap.
To be able to better control the volumetric lighting, I made some simple materials and used them on meshes for places I wanted to increase the volumetric lighting.
With Virtual Texturing(VT) enabled, I could tweak lights in real-time and see as they adjusted. When I had the "final" lighting in place. I disabled VT since it caused too much visual popping when loading in textures.
When you go down to Titan in the game, there's a storm over there, it's very dusty and windy. I wanted to create an environment where you would be struggling to find your way forward, without being annoyed, that is.
To get this working with a good framerate, I baked the lighting with a high density of volumetric lightmap.
Then, I shot tons of particles with a material similar to the one I used to control the volumetric fog through this and got this smokey/dusty feeling.
Assembling the Game
The station went through a lot of variations in design, layout, and such. For the longest time, you were never going to see the actual station, but rather look out and see Saturn. Then, I made a section where you would actually go outside and see a small portion of the station.
In the end, I made the hard call: I had to make an actual station and fit all the interiors inside it. That was a lot of work and challenging in all aspects. Looking at it now when it's "done", it all feels obvious, but I guess that's always how it feels when you see the solution to the problem.
Titan's surface was also a challenge and it went through many iterations. First, it was basically a small camp where you climb a hill and start a tower. Then it was a quite large environment where you were to drive a vehicle around starting towers and talking on the radio. I liked that idea. But it was not without its challenges. What you can talk about during this, making the driving fun enough, and so on.
It was also a matter of scope. Making a driveable cool sci-fi car, with sounds and a world to drive around in. I made a whole environment you drive around, a blocky car you drive, made the dialogue, and so on, but in the end, it would have taken way too long to push that content to a final quality and it in some ways dragged on for too long and I couldn't fit the story elements I wanted into it. I had to cut it.
I'm happy with how the final Titan surface ended up and what happens there and it all worked out for the best in the end. The puzzle section of the game, cyberspace, also went through many iterations as well. The only thing I knew was how it was gonna look and what you do in there has to convey to the player. The player has to unlock computers by connecting boxes and mixing them to the correct values/color to unlock the system.
In short, you can build with the colored boxes and mix them with other colored boxes and connect those to the portal.
The technical solution is basically a bunch of collision boxes. As you build a cube, that cube checks for collisions around it and acts accordingly. Sounds simple, but it was hard to get that working properly by changing to the correct color/value. Performance was also an issue. It would have been a lot easier to just check every frame the status of each box, but it ends up being a lot of boxes to check. Instead, it's all done by collision checks on creation.
In general, for the whole game, I don't use per frame/on tick – to save performance. Only very few things run on per frame/tick. It is often possible to find some workaround to have things triggered by a collision.
The CRT Terminals
I know I wanted CRT screens for the computers in the game. That felt most fitting for the retro sci-fi feel. There are ways to get an interface into the gameworld in Unreal Engine, but I wanted a rounded surface and input by keyboard/controller, not clicking on a screen.
The way I did it was by making a blueprint with a camera in and a widget. The camera renders the widget to a rendertarget and that is used on the screen. To get the CRT-like feel, the camera blooms the render.
On interacting with a computer, the widget overrides the input. This is set up in the Widget Graph, functions, Override.
This was nothing short of a mess to get working properly. I had to define every menu's behavior, both for the keyboard and for the controller. This is just one part of the huge spaghetti:
I also did one more thing, a bit of an "old school" trick – to get the CRT light leak/scattering around brighter areas. I took the rendertarget, got a lower mip, and added the rendertarget on top of this mipmapped version. In the rendertarget texture, I enabled mip generation.
Picking Up Items
A lot goes into just picking up an item. First off you have to fire a ray from the player's POV, check what that ray hits, and if it hits something you can pick up and that is in the range: Show the "pick up icon". If it's not, hide the icon.
Some other major parts:
- Is it very dark or very bright where the player picks up the object?
- Does this object give the player a password?
- ...there be text rendered, i.e. a note?
- ...the player be able to rotate the object?
- ...there be an event trigger?
- ...the character or someone else say something?
- ...it makes a sound? What sound?
I made a blueprint that could be customized by flags and parameters and used for almost all objects that the player picks up and inspect. As I wanted the lighting to be baked my first solution for picking up items in the world was to render a version of the picked-up item in a rendertarget and display that on screen using a widget.
This was made by interacting with an object > telling a blueprint with a camera and a static mesh to change the current mesh to the one I want to look at and start recording. This solution worked, and the main drawback was the performance cost, that the edges of the object could end up a bit jagged, and that the object did not have matching lighting to where the player was standing.
These drawbacks made me make another solution – just move the object in front of the player. Or rather, hide the static object, and show the same mesh or another mesh for the object you inspect.
- Lighting in the area the player picks it up in might not be ideal for looking at the item.
- Clipping through other meshes when moving the object from the start location to the inspect location.
In the end, I went with both solutions, since each item you pick up and inspect has its own requirements. Mainly, the non-render target solution is used but for areas where it's very bright. I have a support light for areas where it's dark, but I can't really make the object darker unless I use the render target solution.
Sounds and Music
For voice acting, I did the same thing as for art by using AI-generated voices before recording with real voice actors. AI voices are getting quite decent – not as good as real ones but definitely good enough to judge if a conversation is working or not.
There is a lot of talking in this game and iterating on it with voice actors would have been a nightmare timewise. It still was a tremendous amount of work to get everything recorded and set up in the engine and I still ended up with some re-recording and re-writes, but doing a couple of first passes with AI voices was definitely the way to go.
Sounds were also challenging, I have never done any sound work before. Music was an even bigger one, I wanted a more orchestral tone since it would be more fitting with the retro-sci-fi tone. Music and sounds were bought, mainly from the UE Marketplace. The main difference between music and images to me is that an image I can look at for 2 seconds and make a judgment – music and sounds need to be listened to a lot. That takes time, a lot of time. So, while I have been working, I have been listening to a lot of music that would fit the game and even more that did not fit.
This content is brought to you by 80 Level in collaboration with Unreal Engine. We strive to highlight the best stories in the gamedev and art industries. You can read more Unreal Engine interviews with developers here.