Space Trucker cover
Space Trucker screenshot
Genre: Shooter, Adventure, Indie

Space Trucker

2.5 Dimensions

Since the late 90's it has been standard to use 3D models in video games to represent characters and geometry. The advantages are pretty clear with being able to rotate in any direction. With the advent of skeletal animation the superiority of animating characters this way becomes the standard. Both of these technologies took a long time to get right and have made games better.

Older computers in the early 90's and late 80's would not have the processing power to render characters as 3D models with any sort of speed required for real-time rendering that a real video game needed. At the time it was impressive to just render your environments using models, this was before the creation of modern lighting and shadow casting systems also.

Space Trucker wanted to revive some of these aspects for aesthetic reasons since it's storyline takes place in the 90's with an alternate Cold War theme. It fit the tone of the levels we were generating and made the pacing feel overall more complete. This is not an attempt at being retro as much as it is a practical way to have more than 10 enemies on the screen at 4k resolutions without major performance degradation while maintaining a constant 60FPS.

The way older rendering methods would work is to use a texture atlas which contained various poses the character would be in at all stages. So facing you directly, you have walking, this is 3 frames of moving one leg in front of the other played in sequence in the game engine. You would have all of these animations for every bit of rotation in 8 different degrees such as front, front-left, side, back-left, back (same for other side) such as walking, running, shooting, standing idle, dying, and corpses.

The technical term is a directional sprite, which changes displayed material offsets based on the viewing angle of the camera that is looking at it. All of this together makes for a pseudo 3D effect which is known collectively as a 2.5D sprite. An example of what this systems looks like using numbers to display the faces as the camera rotates around it in the resource editor.



This system works good for objects like barrels, crates, characters, lights, and some other effects used throughout the game. However, the effect don't lend well to weapons or characters which are viewed from extreme angles such as 90 degrees straight down towards your feet. Since the billboard sprite is at it's heart a 2D image it would become invisible when viewed from this angle or worse a line from the top of the polygon used to render the billboard.

Another example of this would be a weapon being held by the player from a first-person perspective. These are not so much directional sprites as they are perpendicular to the camera at all times, so the effect would be wasted there is no rotation on the Y or Z axis for these types of sprites. A different type of sprite rendering class is used for weapons and special critters like bugs on the floor and rats so that they will look right when being looked down at or straight on from FPS camera.



The above animation may seem a little strange but it is rotating around the cockroach in the same way we did with the directional sprite but this time the sprite is not changing its material offsets and instead loops through a series of frames that make up a given animation name, in the case of our buggy friend here it would be his walk cycle.

Animated sprites and the directional sprites are both used extensively in Space Trucker for things like weapons, characters, decorations, blood and gibs, corpses, bullet casings, light flares, and even machines and equipment sometimes. It is great for adding detail to existing 3D models to combine both the old and the new school items into a model which gives the game a unique style that stands out from other indie games on the market right now.



Next post we talk about how it is possible for Space Trucker to have thousands of lights on a level without dropping below the desired 60FPS target. This is accomplished with static lighting!

Cutting Floor

As you develop a game sometimes features you thought would be really cool end up being boring. This while seemingly looks like a design failure can actually be a pretty common occurrence. It's hard to realize how something will feel in a game when you are talking about it or designing it.

For this reason the implementation of a given system will typically vary ever so slightly from it's initial design. This is all for a very good reason, the developer should not force features that do not work simply because time was invested into it does not make it worthy of players time.

Below we have a shot of how the space trucks energy system was envisioned to function. We took ideas from fusion reactors, stirling engines using heat transfer, pulse generators to start the reactor, drive shafts with energy being converted from various forms to another.



Even when looking at the white board for such a system it looks way to complicated. However, at this stage of development it was allowed and most of these machines got created and others are still in the game to this day. The point being that without this process of creating large systems, and then slowly trimming away the unwanted features and things that don't work it will be much harder to just create a system like this on the first proverbial dice throw.

It would be a waste of time at this point thinking about things like removing items before we even know what works. So we move onto the next part which is finding places on the space truck for all this equipment. Before plotting the rooms out find pictures of what you want the machines to look like on something like Google Images and create a document to specify the general look and feel for each type of machine and the predicted energy and or fluid requirements it might have during this stage also. Below is an excerpt from a document we used for this very purpose.



With something like that as your disposal it makes the next part much easier when you have an idea of how big a given machine might be you can see it existing in one of the compartments we created in our prototype space truck. It is worth mentioning at this point that the final ship in the game does not look this way and these whiteboard drawings are apart of the brainstorming process to help us get these ideas out of our head and into the real world.



Now we have all the systems we created above and their interactions bound to some sort of tangible object that could be modeled and gives us an idea of how big it should be in relation to the rest of the ship and the player driving it. The graphic above shows us the basic plot that can actually be used as the basis for designing an actual 3D model that can be used in the game.

Modeling starts with the creation of a floor plan based on the sketches we created in in whiteboard sessions. All of this data is now concentrated into a single design that we can use to push the development of the entire ship forward. The sample floor plan here was from deck 7 or the very bottom of the whiteboard concept. The acronyms on the various parts represent what they are such as FTL standing for faster-than-light drive.



Blueprint created we are now ready to move onto the creation of actual models based on this. When I say based on this I literally mean based on this in the sense the blueprint is designed as a per-pixel representation and is made to that scale. In this system 10 pixels made 1 meter in real life length.

Walls can placed down, doorways start to take shape, the ship really starts to become alive and you can see it happening right before your eyes and it is very exciting. However, it becomes apparent that we are going to have a problem with this ship being well... huge... but since we can use all these parts no matter what happens we keep modeling and don't stop and redo everything because that would just be a waste of time. Always go forward and never backwards!



After about a month of doing this non-stop you are left with what we sought in the first place. A unique 3D model of a starship that really shouldn't exist but we forced it to anyway because we are awesome like that. This is a space truck! The design is way to big though and there is no way we could ask player to circumnavigate this ship and travel to other places, we could make an entire level, or even an entire game exploring this vessel it was so huge.



Here is another shot with the skin of the ship removed before any texturing or UV mapping took place. You can see the front window there where the pilot would sit and a chair for scale. The rest of the ship extends outward in every direction behind them like a labyrinth of death and confusion. On the bright side those machines are really starting to take shape and look great, remember what we said earlier all of this work can be used no matter what happens. We can make this ship and then gut it for parts and use the pieces throughout the game, and we still have the ship to incase we would like to do something with that specifically in the future.



You continue the work and trust the math, never second guessing yourself and pushing forward at all times. Texturing and UV mapping of these components on the ship occur at this point. Please forgive the quality on these renders these are from early concept builds of the game and were done quickly, even simple renderings like this took several minutes to complete wasting precious time.

The ship's skin and guts are looking great though we are really onto something here. It is also worth noticing that the ship does not look like a semi truck anymore but actually like a ship. This was done during one of the re-designs where attempts were made to make the design more compact. Like GlaDOS taught us, trim the fat.



After another month of development on this concept the final image of the ship starts to come out. The one that we ended up using in the game came from a similar design process but ended up with a much smaller and compact design each time this process is done. The plus side to all this is we have the backlog of data leading up to this conclusion. The final shot here is from a hallway leading towards the engineering section where the gravity generator was in this ship design.

All of the parts in this ship ended up getting used in one way or another on other levels and components, decorations, and anything else where they could be used. Nothing went to waste and we got several unique ship designs out of it.



Thanks for reading. Next post we enter dimension 2.5D and talk about why enemies and weapons look the way they do in Space Trucker.

Map Editor

When we begin work on a new level there is always this nice feeling in the air. You have the design documents, know what you are making, but overall the excitement is from now being able to see it yet and as you start to place all of the pieces of the level down and fill out rooms it begins to become a place and not just a collection of polygons.

A proper game engine will allow you to orchestrate hundreds of simple systems all at once. What does simple mean? Well in essence the KISS principle is something that can save your sanity. It is an acronym for "Keep it simple, stupid". It was supposedly created by the US Navy in the 1960's. It was also a buzzword in the 70's but here we are again using the buzzword for the sake of game development! What better purpose could there be...



Above is an example of a door controller system which is used in the game. It requires the use of all the other systems built such as the grid network to talk to the other machines. In this example all doors are also machines that can be controlled by the grid network by passing messages around.

Configuring a door in the game is not something that requires code, a level designer would open their level and place down an entity which will not render in the game when it is running but only in the editors. It is called a door controller and takes a list of doors it has control over. This allows us to change the value on the door controller to manipulate many doors at the same time.

Some locations in levels have setups like this where there are many doors that lead into a given area, with a keycard reader or a switch in the middle to allow interaction from the player and when that happens it will trigger all of the doors to open at the same time.



One of the more interesting things about abstracting the control of doors this way is that it can be used for other things and is by no means limited to doors only. Here are some examples of what we could use this simple system for:


  • Moving platform such as an elevator to make the player move between two vectors.
  • Plane moving down slowly to simulate a room draining or flooding with fluid.
  • Engine with pistons that pump up and down to simulate mechanical motion.
  • Control rods being inserted into a reactor to cool it down right before a meltdown.

All of these features could be supported without having to add any additional code or systems into the game that might introduce some sort of instability in the code base. The absolute worst thing you could do is copy and paste code from one part of your project into the other this will only hurt you in the long run as any bugs discovered will require what is known as shotgun edits to continue editing your code and this is where major bugs slip through the cracks.

Sure you could design tests for all of these things, but a code base that is suffering from these symptoms typically will not even have tests that can be run making auto-discovery of these problems impossible without manually looking for them and or worse players finding them in your finished product. Thankfully Space Trucker does not suffer this fate.

Below we have a shot of a room that is from an alpha build of the game where not all locations have been populated with items to make them feel like a place. This particular place is a lobby before entering into a deeper laboratory. The wooden construction horse that is there is used to signal to map designers, and QA testers that a given room is not yet completed but someone has been through there.



So you are going to load up the map editor and work on some of these levels and see how many rooms you can fill out. One of the first things to look into is a basic lighting pass. There are pre-defined scene files that can be imported into the map editor that allow for lights that don't exist to be brought in from a common collection of them. The next step would be glass for the windows.

Rooms that look into another room will have opaque glass for privacy purposes (and object occlusion), however a room that has windows or outlooks into a common area within the same part of the map will use transparent glass which can be broken and shot at with weapons.

Handrails will get placed down in areas where you would figure they would be in real life. You start to get a sense for a place at this point like "Oh, people could fall off this ledge here there should be a railing." When you do this it will look correct after you place them and you keep doing this over and over for each type of object you place down in the editor.



By this point we have configured lights, glass, doors, buttons to control the doors, and now we really got a room going on. To complete our feng shui we begin putting computer workstations into pre-made slots that the level generator created for that very purpose. The game makes use of a static lighting system so there can be literally thousands of light sources in a given level and it will still run at 60FPS @ 4k resolutions.

Next post we are going to talk about things that don't make it and enter the cutting floor, where tons of crazy ideas go in and only the strongest survive!

Personal Touch

A little over a year ago, right around the time the development of Space Trucker was starting there was a loss in my family. I heard over the phone that my Oma had passed away, I got to talk to her one last time and tell her that I love her which is really more than any of us could ask for. It was a very surreal day, the passing of time felt slower and I was reminded of good times growing up playing in the backyard and swimming in her pool with friends on those hot summers.

When all of the assets in her home were being split up amongst the family I found out my sister was going to inherit all of the tapes and records of her singing from the 40's, 50's, and 60's. I remembered then how she used to do show tunes and had a really amazing singing voice. I personally lacked the equipment to transcode from tape and records so I asked her to please create digital copies of these items so I could use them in the Space Trucker project.

Development on the game continued as normal until around the prototype stage I was finally the recipient of a couple of CD's with the digitally remastered versions of the songs. This was not just a simple dubbing either, great care was taken in the conversion process to clean up the audio, remove artifacts, and generally make it as high quality as the source media would allow with today's technology.



When I got the discs in the mail I was super excited. I set to work on creating images of the audio data contained within and eventually to the OGG format our game engine uses along with OpenAL for playback. With the conversion from physical media complete I was free to edit them in programs like Audacity and snap the tracks together, figure out which ones I wanted to use, and organize them based on BPM for use in the game. Eventually all of this culminated in a radio station that the players can listen to in the game before the end of the world occurs while everything is still working fine.

Since the game takes place in the early 90's it made sense lore wise even that someone who is in their late 20's (AKA the player character in the game) it would not be out of touch for them to be listening to music from this era especially if they had a liking to it. Accommodations were made in the game's storyline and character creation to fit for this so everything would be just perfect. You can listen to some of the tracks for yourself, I have them all on a YouTube video for your personal enjoyment below the drop.



It really brought me lots of joy and happiness to see this come to fruition. The way the music sounds in the game fits well with the tone we are trying to achieve as you can hear background noise like people laughing and clapping sometimes between songs. This compliments the life on Earth, and makes it all the more ominous when communications cease and you cannot hear the people laughing anymore.

As you cruise throughout the galaxy it is comforting to know that my Oma's voice will be there coming through the radio as the stars flyby at faster-than-light speeds. Furthermore, the idea that even long after I am gone the stories I have told with my previous games, this one, and the ones I have yet to create will live on like my Oma's singing voice. I hope that you all enjoy this story and piece from my personal life.



The next post will be about the map editor, how rooms get filled out, how doors get wired up, and a few tidbits about how levels come to life.

Grid Network

Imagine having a bunch of machines in a room, each of them does a seperate function. All of them are required to function, and each of them has slightly different requirements. Each machine can have resources that another might need, and each one needs to be ticked but not all the time. The final complication would be the fact that not every machine can query the grid network at the same time since it is single threaded. It sounds daunting at first, especially if you needed to program something like this but the solution can be fairly straightforward if we take advantage of a popular programming pattern known as chain of responsibility.

The principle behind this design pattern is that each object in a chain has the ability to pass messages to the next machine it is connected to. Every machine you have would be connected together in a large chain, in code this would take the form of a linked list. We use this ability for each node in the network to know about every other node to pass messages around in the form of requests. Here is what the diagnostic panel for the grid network looks like in Space Trucker at the time of writing.



Some of the terms might be confusing so let's clear that up. Reconstruction is when the grid network checks the map for all compatible machines and builds up the chain of responsibility, this would be something that happens when the map is loaded initially but could also happen while the game is running (such as when a machine is destroyed or added to the network).

Provider regions are literally regions of space on a given level where machines can exist. The purpose for compartmentalizing this is to have different rooms which can be cut off from other rooms. Another example of needing this would be for oxygen distribution so we could fill the given volume with reserves from a machine to produces oxygen.

Node points are the actual machines on the grid network, each node point in a provider region is capable of passing around resources to other nodes in that provider and other providers also. The requests sent and received is for keeping track of how many times a given machine will ask to get something like electricity or water, and vice versa how many times it gets a request to deal with something a machine produces like fuel for reactor or a battery taking electricity that was generated.



An example scenario might be a electric turbine that is spinning. It produces energy to feed into the network, there is a polling time for this to occur and is all event based. When the machine triggers the want to pass electricity around the grid network it gets added to a queue of requests that get processed every time the game engine updates which is about 20 times a second.

The energy produced from the turbine goes into this queue and when passed around the chain of responsibility proceeds to ask every machine how it would like to proceed with the following resource letting the machine itself decide at the time if it would like that. In the case of our turbine it could add energy to a machine that needs it, but the system is designed to work on levels. The energy coming out of the turbine is in bursts of 512 "energies" per update, if the machine has something in the queue already it cannot make another request until that previous one has been dealt with.

So a computer on the bridge of our ship does not need this much energy, it can only take energies in increments of 32 per update so the turbine packet passes by the computer and onto the next machine and asks it if it can take the 512 energies it has and each thing keeps telling it no until it arrives at the ship's battery which is configured to allow packets up to 512 to be accepted into it. Once the turbine energy packet hits the ship's battery on the chain of responsibility it is then consumed by the battery and the grid network informs both the battery and the turbine of this operation.

A request is marked as being successful if something in the chain accepts what it was either requesting or providing. In the case of the turbine it was successful when it was accepted by the ship's battery, thus charging it up some towards its ceiling of about 10k energies. Failure, while sounding harsh is actually not that bad. It really means that the request just did not get accepted by anything on the network during the time it was passed around the network, this is done done for every single time the packet visits each machine but cumulatively where each packet is measured as a whole on whether it succeeded or not based on what it was trying to do such as provide energy to machines.



With the possibility for so many things happening at once it makes you realize that you need tools that exist in the real world... in your game world in order to properly measure what is happening. Especially if we would like to convey this information to the player of our game. Above is what is known as an annunciator panel, it shows an array of conditions based on pre-defined categories. In the example video above the switch was flipped to perform a light test which loops through and triggers each light individually for testing purposes only.

During normal conditions this is configured so each light on the panel has the ability to hook directly into a given machine using the grid network as a basis to quickly get pointers to the information where it exists in memory rather than having to search for it. During the reconstruction event a dictionary of machines in the grid network was created and then used as a reference for a method to get a machine by a given type.

This makes the operation of the each panel very fast, and not directly dependent on the machine but the existence of it in the grid network. This means that if the machine is deleted the game will not crash, instead the panel will just never update since it never gets the pointer to a current machine instance and therefore will not do anything. Using this style of design prevents jarring null reference exceptions in code that can halt development when in reality nothing is actually wrong or missing just a typo on the programmer's part or maybe the level designer had not placed the right machine down but none of these are problems using a system like this since you just notice the problem and then correct it. Sometimes the problem can be corrected without even having to close the game while it is running, which makes the life of working on a complex system like this much easier.



One of the final challenges in a system like this is the graphical display of data on a terminal. Not to say it is more difficult than displaying it on LED's and gauges, but rather it requires a different sort of finesse to move the data into a correct space the game engine can understand. When working with entities in the game world it is easy to refer to things by type, for example you can hook something by a type such as querying the grid network like "give me all the batteries" which would return array of all batteries in the network based on provider regions they reside in allowing for easy iteration and or specific checking based on the provider the machines resides in.

Since the GUI elements are not game entities it requires something else. The GUI system uses the concept of controls and a screen control manager which is based on 2D vector coordinates meaning we have only two variables an X and a Y direction to work with. There is sort of a Z plane, in the sense that one control can exist on top of another control but this is not configured via code but rather by hierarchy. Some special edge cases exist and allow for properties to make a given control 'always on top' or 'mouse cover' which means that when that control is above another control mouse clicks cannot fall through to the control below it so that the GUI operates in the way both developer and especially players will expect it to. The purpose of which is to stop accidental clicks, if you are interacting with an interface with some buttons on it, and another dialog pops up and covers them clicking where they exist in the space below that other control should not fire the event for clicking the button it will be ignored when it is covered by another control to prevent this unwanted behavior.

The solution to this problem is two-fold and requires a couple more well known design patterns like the one we used to build the grid network messaging system. For the GUI to represent the state of an entity in the game world we need to use a structural pattern known as a proxy. It will provide a surrogate or placeholder for another object to control or access it.



This system we will call the GUI proxy, with its purpose being to allow a machine to change controls on a given control without any direct bindings to them. The proxy class would contain methods like UpdateTextBox, UpdateProgressBar, UpdateEnabled, and UpdateVisible so that a control could be manipulated by proxy and this all this information can be serialized and passed along to the GUI when it asks to update. An update to an in-game GUI should occur during a render event and not several times between ticks to optimize the performance overall.

Finally, the last pattern we need is on the GUI side. We can use the behavior pattern known as the observer to talk to the GUI proxy and ask it questions about what state our controls should be in without directly binding to them at runtime. With this one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.



Using both of these patterns allows each computer workstation entity with a monitor and in-game 3D GUI to update only when something has changed according to the GUI proxy. Each control is hashed with it's name, position, and rotation in the game world to keep it unique and to stop cross-talk between other GUI's and the proxy itself. Using this unique hash key we query the GUI proxy for changes on startup and hooking a notification event that triggers when the data changes.

Now that we have this grid network system and the ability for it to talk to entities and GUI controls alike we can start to use it to build out the rest of the functionality on the ship. Each machine will have it's own requirements and design that needs to be followed but using this system we can accommodate them all and anything else we might come up with in the future.

Next post will talk about how you can leave a truly personal touch on your game.

Lore Distribution

Enter a laboratory that looks ransacked and all but destroyed. There is blood smeared on the floor and walls, in the corner you notice a dimly lit computer terminal with a blinking cursor that beckons you closer. Looking over your shoulder you don’t sense anybody else as you place your fingers on the keyboard and begin to investigate the secrets the terminal holds. The only sounds in the room that of the idle click and clack of the mechanical keyboard as you navigate the menus on the computers monochromatic display.



Space Trucker makes extensive use of interactive terminals. They take many different shapes and sizes, but overall their functionality is the same. When you interact with the terminal you can use the menu driven commands (or numpad) to enter numbers to your corresponding selection. Other systems that use graphical interfaces have a mouse cursor and let you click buttons to interact instead of the command line interface.

There are variants on this design such as locked terminals that require hacking by your PDA in order to gain access to them. Other terminals can be destroyed in explosions or gunfire. These terminals typically will tell you about research projects taking place on the facility you are on, give you a code to a place you might encounter later in the level, or in a different level later on in the story.



Technology wise this is driven by a file based system that looks inside a specific folder for plain text files which developers can create and drop into sub-folders. The computer is assigned to one of these paths relative to game's data directory; which in turn generates the menu commands, their titles, and numbers them. This can be as deeply nested as required by the developer. Most circumstances this is used to have one menu with several text files in each subdirectory to tell a story about a given location.

Since compiling the game isn’t necessary to use this system it is easy to pass around the text files to get proofreading and feedback on them. Another possibility is multiple developers collaborating on a single level by writing logs separate of the level design process, and then including them and linking to terminal afterwards.

Through exploration the player is able to read about the lives of the people that inhabited these bases, what their ambitions were, their hopes and dreams before it all changed in a moments notice. None of this is required to proceed in the game, but there is lots of lore distributed evenly throughout the game's primary campaign just waiting to be discovered.

Next post I will be talking about how machines talk to each other using a piece of technology made for Space Trucker dubbed the grid network.