Kerbal Space Program
Modular Part Design Retrospective
This section covers the development and design of the modular part system that drives gameplay in Kerbal Space Program. I will only be covering the development and history that I have first hand knowledge in, while I was part of the development team at Squad. The system has since changed considerably over the course of the project’s history, though many of the same design principles and foundations are still relevant today.
I am officially credited as a technical artist on KSP, though I spent the majority of my time designing parts, writing config files, programming new part logic and making procedural FX systems. I would also create special FX, as well as modelling and texturing a number of iconic parts in the game. I would pitch new designs to the development team for approval for upcoming sprints, and once approved, I often collaborated with Mu (Mike Geelan) and Nova Silisko to get them implemented.
I’d also like give special thanks to Mike Geelan Aka Mu, who spent a lot of time patiently teaching me good programming practices and design patterns. He always made time to help me out, and work through an engineering problem when I was stuck and didn’t understand something.
This document is in progress, I’ll continue to update it as I have time.
History - C7 Flight Pack
I was first introduced to Kerbal Space Program, by my friend Kyle. At the time, the game was relatively unknown and still very early in development.
When I first played it, it became very clear to me that the game was something special. The concept of cobbling together rocket legos was incredibly fun and surprising.
The potential of the game really struck a chord with me, and I was very happy to discover that data files were available as text files that could be edited outside of the game. I decided to challenge myself, by imaging I was a content designer on the project. What else could be done with this system of snapping parts together?
I didn’t want to simply make another rocket part mod, as there were already plenty of them available in the KSP Yard and forums.
As I loved aviation, and flight sim games. I challenged myself to using the existing code to hack together aircraft. That mod would later become known as the C7 Flight pack.
For the flight pack, I designed about 40 parts in total, belonging to several sub types. I created all 3D models, textures and descriptions.
Modular Wings
basic control surfaces
stabilizers
landing gear
fuselages
jet engines
cockpits
Designing the pack had a number of challenges as there was no real code support for what I was doing. Landing gear was for example just regular parts with low friction and a very high impact damage resistance values. Cockpits were designed with very high torque power, allowing you to essentially wrench the flight path into the direction you wanted to go.
The pack ended up becoming quite popular, becoming the subject of a number of Youtube video series.
The final version of the pack, is still available in the KSP Yard.
Skilled players even made multi stage aircraft and spaceplanes that could get to orbit by carrying a smaller craft.
Joining the development team
I spent a lot of time interacting with the KSP community in those days, getting feedback on the flight pack, and trying to improve the mod. There was no runway in the game, so players were regularly landing in fields.
I was very surprised when I heard that the game would be adding runways in a future update. I had become friends with the community manager for KSP, and asked her about it.
Much to my surprise, the runway had been added to support players using the mod I had created. She then introduced me to the creator of Kerbal Space Program, Felipe Felanghe. We spent a lot of time discussing part design, aircraft and modding in KSP. As the game was steadily becoming more popular over time, I was approached by Squad to officially join the development team in early 2012. There, I would be tasked with designing new parts and implementing aircraft into the game.
I agreed, quitting my day job in IT to join the development team at Squad full time.
Part system
To get familiar with the project, I spent time diving into the code of parts in depth. In particular I find fixing bugs to be a good way to get to know a code-base, determining where things can and do go wrong. I did this as a warm up before starting to implement aircraft into the game. My first goal was to add a proper air breathing aircraft engine.
The parts were initially designed as traditional classes inheriting from part.cs, which in turn derived from Unity’s Monobehaviour. Specific parts, used optional overrides to implement gameplay logic.
When I added an aircraft engine to the game, I realized I would need a whole other class, with yet another version of specialized fuel handling, control logic, FX and everything else. Likely with it’s own set of bugs and issues. If we wanted to add new behavior to all engines, we would needed to manually edit every file following the current pattern.
I took a look at the data of all engine parts, in order to better understand the ways in which their data varied. As well as how their behavior differed logically.
Original Inheritance Diagram
To design and program new parts types, you overrode the provided base methods from the Part class with custom logic. To save time, code was often copy / pasted and tweaked as needed. This pattern was very familiar, mimicking the base method overrides used when inheriting from Monobehaviours in Unity.
Engine Design Analysis
Liquid Engine
consumes external fuel (liquid fuel)
amount of thrust varies based on throttle (thrust and fuel consumption are linked)
Engine Nozzle is vectored by pitch and yaw inputs
Special FX logic (Thrust varies particle system)
Applies physics forces to the part’s rigid body, based on thrust
Deactivates when decoupled
Solid Rocket
consumes internal fuel
when activated always provides maximum thrust / does not receive control inputs
Special FX Logic (Particle System start and stop)
Applies physics forces to the part’s rigid body, based on thrust
Stays active when decoupled
Airbreathing Engine
consumes fuel to produce thrust (liquid fuel, and oxygen)
thrust varies based on throttle
Engine nozzle is vectored by pitch and yaw
Requests fuel from the ship / other parts
Special FX Logic (Added special glow FX when the engine was hot)
Applies physics forces to the part’s rigid body, based on thrust
deactivates when uncoupled
There was a lot of common functionality here, and overall engines shared the majority of their logic.
Part System Redesign
Goals
Eliminate boilerplate needed to create new parts
Remove code duplication
Reduce complexity of bug fixing and maintenance
Improve iteration times (Prototype without needing to recompile and rebuild the game)
Give modders more power to create new parts, without needed to change the game’s source code
Provide an easy way to share common functionality between parts, that could be edited an upgraded in one place
As a concrete example, I added engine heating special FX as part of developing Atmospheric engines. However, if I wanted to add this to the other engines, I would have needed to abstract the FX code into a utility, or static method, passing in all required data and calling it from the appropriate place in code in each engine class file.
Part Modules
After collecting data, and analyzing the existing parts, it was clear there was a lot of potential for improvement. We discussed many possible solutions at this time, going through the pros and cons of each, and how well they fit with our design goals.
I wanted to cut up the logic into discrete “lego-bricks” or modules that I could combine in any way I wanted to express new part designs. I knew that the game would need a lot of content over the course of development, so it was important to get this right.
After discussing things with Mike Geelan, he programmed the underlying framework, expanding the part class and building out the part modules. This process took a lot of back and forth, with me testing and trying to implement parts, and Mike adjusting the underlying structure of Part Module class as needed. While he was doing that. I went through and analyzed all the existing parts in the game, selecting and cutting out any pieces of common logic to make new part modules. From there, I re-implemented all parts in the game using the newly designed modular systems.
Though I wasn’t aware of it at the time, we had created and implemented a data oriented design pattern for parts very similar to a component system model. For more information, I’d recommend the excellent articles by Cowboy Programming and Scott Bilas talk on the design of the game object system in Dungeon Siege.
A potential alternative hierarchy, using an engine base class with child classes. This was rejected, because it would still require a full recompile, and modders would have to add new classes to create new types of engines.
After the refactor, Parts now contained a list of Part Modules. The modules were defined in a part’s config file, and could therefore be reloaded at runtime for rapid iteration and testing during gameplay.
To make new types of parts, we only had to combine the existing modules in interesting ways.
Resources
One final missing piece of the puzzle was the handling of fuel and resource consumption for parts. What existed previously was a mix and match of part derived classes implementing their own logic.
Fuel consumption was highly coupled behavior, as fuel burned, it decreased the mass of the parts it was contained in. This a key component of the Rocket Equation and was necessary to recreate for the rockets to behave in a believable fashion.
After surveying existing parts for how they reacted with fuel, there emerged two main types of logic. Resources that could flow, and resources that could not. Static resources could only be used by the part the fuel tank was contained in and did not provide their resources to the rest of the ship. While resources that could flow would follow predictable logic to drain tanks in order.
I saw a lot of potential to create new gameplay with simple part modules that provided, converted and consumed resources while operating. So the system was designed to account for this, allowing bi-directional flow of resources, and not limiting them to just fuels. Any part module could interact with the resource system. Queries were not guaranteed, while you could ask for 100 of a resource, if it wasn’t available you would only get the remainder. Similarly, if a container was empty the resource system would reply with how much was successfully stored.
Mike again handled the backend coding here, building out the resource system and testing with me to ensure the design was working as intended.
An overview of a resource query by an engine module under the new system. Resource flow and management was delegated away from parts, and controlled centrally as a key game concept.
Adding new resource became a simple matter of adding an entry to the Resource Database. This was editable in a config file, and did not require recompilation. Resource containers simply contained a key to retrieve the resource definition from the database. In this way, we could non destructively adjust the balance paramaters of resources globally.
After this change, we were able to completely eliminate fuel tanks as a discrete part. Now, any part could store fuel by adding a resource definition to its config.
Before and After
As this was a data driven system, I feel it would be useful to discuss how the data changed, and get into some of the details of what part configs looked like after the system was implemented.
The system was met with a lot of fanfare at the time of its release. The modding scene exploded with new mods as the barrier to entry became much lower, eventually becoming a hallmark of the game’s success over the years.
Several of these modders would later join the development team at Squad. The number of parts officially, and un-officially (via mods) in the game quickly exploded, and we were able to release lots of official content every update, in spite of the breakneck monthly cadence.
The solid rocket engine now consisted of two modules and a resource container for its fuel.
A solid rocket engine’s data in the new system
An old part data file. Here the engine parameters and data were specific to the engine’s.cs file which inherited from part.
The definition of a Liquid engine in the new system
Part Module Design
This section is in progress, please check back again soon.