Space256
Open source space game.
2022-05-10: First Post!
2022-06-03: Spell check, formatting, moved image.
Open source space game.
2022-05-10: First Post!
2022-06-03: Spell check, formatting, moved image.
Space256 is an opinionated, mad effort to build physics-powered gameplay into a space MMORPG.
Kerbal Space Program (KSP) proved that millions of players love a brutal, unforgiving, single-player, high-fidelity physics simulation with a thin layer of gameplay added on top.
Eve Online proved that millions of players love a brutal, unforgiving, multi-player sandbox with no specific goal but deep layers of gameplay and real, player-driven economy.
Combining KSP and Eve would be extremely ambitious and borderline insane. Adding in new algorithms from computational geometry, cryptography and procedural generation research would make for an almost impossible scope.
The number one advice you get in game development is to never build your own game engine. It's too hard, too expensive and way too risky. And if you're mad enough to do it, at least don't build your own physics engine.
We're doing all this. And we're doing it the hard way.
Physics is the core of all gameplay.
Physics define the most fundamental assumptions in all games and virtual worlds.
Gravity or zero-g. Deformable or indestructible terrain. Air, water and buoyancy. Soft-body or rigid-body dynamics. Weather and radiation. Borders, walls, entrances and exits.
Even ephemeral features usually considered beyond the tangible world, such as player chats, can be rooted in physics. In Eve Online, each star system has its own local chat, and players automatically join/leave the chat when they enter/exit a star system. The sudden appearance or vanishing of a player from the local chat is an important part of the gameplay, especially in and around PvP battles.
Another part of gameplay considered ephemeral but still rooted in physics is the transfer of in-game assets. In vast space games, when players instantly transfer ownership of objects at distant space stations, this assumes FTL communication within the game world.
Even the very dimensions of our familiar 3D environment can be bent or bypassed for gameplay. A great example is the portal gun in the widely acclaimed 2007 Portal game that allows players to create two distinct portal ends. The portal creates an immediate visual and physical connection between two locations - similar to the spell Dr Strange and Wong cast both in combat and for casual travel. Despite bending (or breaking if you prefer) the physical laws of three dimensional space, the Portal gameplay is strongly internally consistent and rules bound (the marvel portals a bit less so..). For example, both the magnitude and direction of objects velocity are conserved when they move through a portal. The result is immersive and intuitive, despite how much it challenges our every day notion of 3D space.
Gameplay is about constraints, and physical constraints are as important as physical freedoms. The voxel-based cubism of minecraft is simultaneously a great restriction and a great freedom.
A big part of what makes KSP amazing is the endless possibilities for failure. Faulty builds, faulty planning and faulty operations.
Spend hours carefully building a large, complex spaceplane with a combination of CR-7 R.A.P.I.E.R. engines and LV-N "Nerv" Atomic Rocket Motors. Launch the plane on the runway and carefully fly it until one crucial moment in hypersonic acceleration when the maximum thrust of an ill-placed engine rips off the entire tail fin.
Such experiences are key to KSP gameplay and immersion. Players quickly restart flights to iterate on ship builds and try everything under the sun. In MMORPGs and virtual worlds, players can't simply reload. And if the world has meaningful resource constraints, then crashing a ton of different ship builds is too costly.
Builds, however, are one of the most loved game designs across all game genres. Players love to plan and discuss builds, sometimes even more than using them. And players love to work towards the skills and costs required for a given build.
KSP and Eve ship builds are dramatically different in both design and purpose. In Eve, you're trying to get an armor or shield tank and weapon configuration good enough to beat a difficult NPC or PvP encounter. In KSP you're trying to avoid exploding on the launch pad.
In Eve, ships have full integrity until they explode - all weapons and modules are 100% functional until the very last hull hit point. In KSP, even the most robustly built ship easily comes apart if colliding with anything a bit too hard - all ship modules have realistic impact and G force tolerance.
In each game, the nature of builds is a direct consequence of the underlying world physics. Eve have just enough physics fidelity to give a feeling that ships, asteroids and other space objects are solid. KSP have such high fidelity that the exact mass, shape and material strength of each individual ship module is realistically simulated.
Space256 aims for a game design and gameplay of physics and ship builds in-between KSP and Eve that combines the immersion of both games into a new type of game. We want:
In essence, the physics of configuring and flying ships should feel realistic, consistent and immersive assuming a classical sci-fi setting. Instead of bending (the current understanding of) physics, the strength of materials and power/efficiency of engines/modules is configured to get to the desired gameplay.
The story, lore and world setting supporting this physics will be detailed in another blog post. Roughly, we imagine a classic space sci-fi setting a few hundred years into the future where real-world physics is combined with stronger-than-present (but not crazily so) build materials and more powerful and much more efficient engines.
Physics fidelity and realism are ultimately constrained by hardware capabilities. Modern CPUs and GPUs have enabled games such as KSP to reach levels previously only possible in scientific supercomputer simulations
Parallel to hardware advancements there's a steady stream of new, more efficient computational geometry algorithms. While these algorithms are often developed for real-life robotics and scientific physical simulations, they can also be very useful for increasing physics fidelity and realism in games and virtual worlds.
The computational complexity of updating and querying dynamic convex hulls have been lowered to O(lg^2 n) and O(lg n / (lg lg n)), respectively, only a few years ago. This data structure is now feasible for deformable terrain in large-scale multi-player worlds.
Modern software languages and tools make it easier than ever to implement, test, benchmark and maintain these type of algorithms within a complex and scalable backend. Golang is used to implement the backend parts of the game engine / protocol as for us it's the right balance between speed and maintainability as both the complexity of the system and our team grows. Cgo makes it easy for the golang code to call C code for algorithm hotspots such as dynamic convex hull operations and cryptographic primitives. And we're just dim-witted enough to think that the golang GC will ultimately not be our demise.
Godot is an incredible open-source game engine that can be used to implement everything we need client-side. The strong separation of client and server (really protocol) logic means that Godot is strictly used for UX and translating player interactions into API calls to the game protocol. Today, Godot is more than powerful enough for advanced 3D graphics and strong multi-platform support. And crucially, all of the Space256 Godot code is open source and can be forked by players or used as a reference for building their own clients interfacing with the game/world protocol API.
Classical Mechanics is the first layer of Space256 physics.
Objects like starships and asteroids have mass, size and are subject to forces like gravity, friction, engine thrust, collisions with other objects and weapon effects.
Classical Mechanics is deeply intuitive to the point where we generally do not think about it in our daily lives or even in most games. When things are out of the ordinary such as gravity being lower or higher than 1g is when we really take notice and pay attention.
Players adapt quickly to environments such as zero-g as long as the physics is realistic enough to enable immersion - reasonable collision detection and resolution, objects having inertia both with regards to linear forces such as engine thrust and angular forces like turning your starship 180 degrees.
To reach our game design goals while balancing realism, performance and simplicity of implementation, we make several fundamental gameplay assumptions.
There is a lower threshold of mass where objects stop "emitting" gravity, and most environments feature some degree of universal damping from atmospheres or dense gas clouds. For example, in most asteroid fields, asteroids do not attract each other with gravity and if having undergone acceleration from some force, eventually reach a "resting" state due to friction from the ambient gas cloud.
More generally, there is a strong design principle of all objects being at rest by default and always returning to a resting state after interactions with other objects. This is especially important in a game world that is not only multi-player and aiming for large scale, but also features full state verification of the present world state and all historical states.
In Elite Dangerous, a base layer of classical mechanics is combined with a layer of fly-by-wire that limits ships to move in the same direction they point with players controlling forward/backward throttle rather than directly the ship thrusters. This makes combat feel more like atmospheric, topgun-esque dogfights than more chaotic, high speed, large distance zero-g combat. The result is an immersive, cinematic sci-fi gameplay where players feel like the physics is realistic yet ships are easy and fun to pilot. The fly-by-wire layer can be disabled, exposing players more directly to the underlying physics layer. When disabled, pilots must counter each rotational move with an opposite move to avoid the ship spinning out of control. However, even with fly-by-wire disabled, there is always a layer enabled that add hard constraints on angular and linear velocity to a common reference frame.
In Space256, the physics model is more hardcore, by default exposing players and their ships to raw classical mechanics. Players directly control ship engines, though the game client by default simplifies control in several ways such as throttling all engines of the same type in unison and by default countering a rotational move with an equal counter move once the player ceases their active move. This design creates a strong separation between the game client and the server side (really, game protocol side). To the maximum extent possible while keeping complexity reasonable, simplification of physics is implemented client-side as automatic "helper moves" rather than in the physics/game engine.
Another example of helper moves is the game client by default halting engine thrust when it detects that the player's ship is accelerating in a direction that will soon lead to its stable orbit becoming a sub-orbital trajectory. A simple warning requires players to confirm they want to deorbit. Advanced players can disable this behavior, and that is a core design principle: all "helper moves" are completely optional but enabled by default to help new players.
Space256 also aims to add some layers on top of the raw classical mechanics physics using game design rather than physics design. To enable the popular banked turn of first rolling the ship and then pulling back on the stick, we design most engines in the game, including the vacuum-optimal ion engines, to have two dimensional (up/down; pitch-axis) thrust vectoring. Going further, all ships have a built-in Control Moment Gyroscope (CMG) implemented as a 3D vector that allow ships to pitch faster than yaw, even in zero-g/vacuum environments.
In Space256, all environments have a universal "damping" or "friction" value that like an atmosphere adds drag on all moving objects. When this value is set to zero, the environment is in perfect vacuum. Moving objects drift indefinitely if there are no forces acting on them. When the damping value is positive, moving objects experience a drag force opposite to the relative motion of the object. If no other forces act on a moving object, it gradually slows down until at rest.
Zero damping environments are chaotic and can feature cascading collisions (similar to Kessler syndrome) that eventually cause all objects involved to drift apart. A high positive value can be used near space stations to create the classic soft sci-fi setting of ships moving slowly even with engines burning and quickly slowing to a standstill when engines are shutdown.
In the Space256 game context, "universal" damping refers to the local reference frame and possibly some neighboring reference frames. There is no damping value that is universal across the entire game universe.
The damping value in each environment is driven by the game design, gameplay and supported by the lore and setting of the world. Examples of positive damping include atmospheres, dense gas clouds and damping fields generated from natural and man-made objects. Zero damping is the default when no sources of positive damping are present.
One wild idea is to feature rare, player-acquirable, natural objects that generate universal damping fields. Mined from rare, dangerous asteroids, these object can only be moved if unpowered, and only re-powered if stationary relative the local reference frame. When powered, the object generates a spherical field of universal damping whose strength at any given position is a continuous (but not necessarily linear) function on the distance to the object. Like air, this damping field can inflict damage if objects move fast enough in it. Whereas air inflicts thermal damage through aerodynamic heating, this field inflicts radiation damage through... a mechanism our amazing sci-fi lore will surely soon explain!
If the game features damping fields generated by natural or man-made objects, it's tempting to complicate matters further by featuring inverse damping field generation. Such fields would partially or fully negate damping from other sources, which could make for very exciting gameplay such as PvP combat in a "bubble" of low or zero damping within a larger field of higher damping.
Explaining inverse fields lore-wise may actually be less challenging, as when they exist within large dense gas cloud we could imagine a mechanism pushing the gas matter away similar to how the solar wind "blows a bubble" in the interstellar medium from the pressure of charged particles.
Classical Mechanics, like most layers in the engine, is implemented using the Entity-Component-System (ECS) software pattern. In ECS, Entities are unique ids, Components are game state data and Systems are functions that take some game state data as input and enacts changes on some game state data (potentially overlapping with the input data).
Since Entities are Ids, Components are Data and Systems are Functions it's tempting to rename this pattern to Id-Data-Function (IDF), but we'll concede.
A benefit of ECS is that we avoid coding logic into objects or classes that are then inherited. Instead, we call an update() function on the set of entities who are part of the set of components owned by each system. This may sound more complicated at first, but leads to an overall simpler software architecture and much easier maintenance as the game engine grows more complex.
The classical mechanics system updates all movable entities with mass, 3D position and velocity and/or forces acting on them. The update function of the classical mechanics system is pretty simple. Force generators enact linear forces and torque that updates linear and angular acceleration. Acceleration updates velocity and then position and orientation.
The orbital mechanics system simulates orbits using Kepler's laws of planetary motion. Each orbit models one object (the primary) around which another (the secondary) orbits. The primary is usually a planet, moon or large asteroid. The secondary can be almost any game object.
Each orbit is defined relative to a reference frame. Generally, this reference frame is anchored in the center of the primary object, e.g. the center of Earth for a geocentric orbit.
Orbits and their reference frames can be nested. A simple example is the Moon orbiting Earth within its reference frame, which in turn orbits the Sun. However, a more accurate model is to consider the Earth and the Moon as a binary planet/system. Both objects orbit their common center of mass (barycentre), which lies within the Earth but 73% of its radius out from its center. While it's easy to model both orbiting their barycentre and set that as the root of the reference frame, this makes other things more complicated, such as how to model player starships launching on the surface of Earth into an Earth orbit.
The way reference frames are connected with orbits is one of the hardest unsolved problems in the space256 game design. There's significant trade-offs with each way of modeling reference frames in a persistent and continuous world, and so far we're starting with the simple yet often inaccurate way of rooting orbital reference frames in the center of orbital primaries.
While any number of objects can orbit a primary, each orbit is modeled as a two-body system and does not consider the influence of other gravitational objects or general relativity. This greatly simplifies the implementation and allows us to use simple and efficient equations to calculate boundary checks.
Orbital Mechanics is implemented in almost the same way as Classical Mechanics. We update all movable entities with mass that have orbital elements.
Entities that have mass and are movable either have their position defined as 3D coordinates relative one specific reference frame, or as orbital elements relative one specific primary (and its corresponding reference frame). This design allows entities to by default be at rest; requiring no updates on each game engine loop.
If an object is orbiting a primary and we define its position as 3D coordinates and velocity, we would need to update the velocity and position on each loop using gravity as a force. By using orbital elements, we can instead leave the object at rest and have the engine keep track of time; updating the True Anomaly (θ) element only when the object is interacted with. This only works for stable orbits; if the orbit is either sub-orbital (intersecting the surface and/or the atmosphere of the primary) or have an orbital eccentricity (e) >= 1 (parabolic escape orbit or hyperbolic orbit) then the engine needs to keep track of when the object transitions reference frames.
We want all objects to default to and eventually reach a resting state that requires no updates by the engine. That is easier said than done, but we can get pretty far by setting objects as "hot" when they are subject to interactions such as forces, and "cold" when no forces act on the object. Math also comes to the rescue; in the simplified two-body Kepler orbit model it's simple and cheap to calculate if an orbit is stable, and if not, when it intersects surface or atmosphere.
Newtonian physics is great fun and can make for immersive, epic-scale player battles. Combining zero-g environments with varying degrees of universal damping can combine gameplay found in several space games into one game.
However, even in the very realistic and unforgiving physics of KSP, players can "time warp" to fast-forward up to 100,000x normal time. This allows players to quickly speed through very long orbits and trajectories such as flying from a planet close to a star to an ice giant that orbits the star much farther out. This works great in single-player but is not possible in a shared, continuous multi-player world.
Traversing space only through real-time orbits can be a great gameplay in multi-player worlds at smaller (but still fully realistic) scales. For example, flying from the surface of a small planet without atmosphere to a very small moon that orbits very close to the planet may be achievable in minutes. However, for larger systems like the Earth-Moon system, it would be tedious to, especially repeatedly, having to first ascend through the atmosphere and then complete a Lunar transfer orbit. An alternative would be to continuously accelerate halfway then decelerating halfway, but this might cost too much fuel and/or energy in a resource-focused game design.
To keep the underlying physics and feature real-world scale of star systems, planets, moons and their orbits, we need additional ways for players to bridge the vast distances of space. We need Faster-Than-Light (FTL) travel.
Space256 FTL travel is an opinionated variant of the classic sci-fi warp drive trope. The mechanism is fairly simple but has a number of hard constraints that ties into the underlying physics layers. This makes it more complex but also more immersive.
There are two types of warp drive; interplanetary and interstellar. For both types, warp can be engaged if and only if (iff) the starship is:
And:
There is one skill for interplanetary warp and one for interstellar warp. At least level 2 of the interplanetary warp skill is required to learn the interstellar warp skill. Interstellar warp has the following additional constraints:
Once warp is engaged, the starship enters an Alcubierre metric directionally locked towards the destination. To add a quasi-newtonian element to the warp, the ship is subjected to a strong dampening field, thus requiring continuous engine thrust to sustain forward momentum.
While the ship's orientation is locked towards the warp destination, thrust can be adjusted (or cease if e.g. fuel runs out). A minimum warp speed must be maintained to remain in warp, otherwise the ship exits warp into normal space.
Due to the dampening, warp speed is determined by ship mass and engine thrust same as it would be in classical mechanics in space with universal dampening. Players will thus see an immediate reduction in warp speed from loading up on heavy cargo. This creates a powerful gameplay; players can configure low-mass, high-thrust ship builds to warp at great speeds for exploration, whereas shipping significant mass within or between star systems requires a lot of time and/or a lot of engine power.
The base speed multiplier is 100c for interplanetary warp and 100,000c for interstellar warp.
There are five types of starship engines. Each type has unique mass, thrust, power requirement, fuel consumption, thrust and other properties.
Starships are modular and can fit as many engines as they have available engine slots. Most ships can also fit wings that have additional engine slots.
Engines have to be fit symmetrically so that the center of thrust is aligned with the ship's center of mass. A ship with three horizontal, rear, empty engine slots "S S S" can fit one engine (E) in each slot for a configuration of "E E E", or two engines "E S E" or a single engine "S E S".
Ion Engines accelerate ions using electricity. They achieve maximum thrust in vacuum and gradually loose thrust as atmospheric pressure increases.
Ion Engines use a lot of power and often requires a ship to fit either a nuclear reactor or a good amount of battery modules to sustain thrust through orbital ascent.
A ship operating only in vacuum need only ion engines, and they are often sufficient for takeoff from moons and planets with low atmospheric pressure. As atmospheric pressure increases, ships will increasingly have to fit air-breathing engines to power them to the altitude where their ion engines reach enough thrust to ascend to orbit.
Jet Engines are optimized for thick atmospheres and subsonic speed. They rapidly loose thrust as speeds go supersonic and/or atmospheric pressure drop. Static thrust is moderate.
Jet Engines have low mass and very high fuel efficiency. They need no power input after first ignition as they're then powered entirely by their fuel.
Afterburning turbofans are jet engines that can activate afterburners to increase thrust at the expense of much higher fuel consumption and lower fuel efficiency.
Optimized for low to moderate atmospheric pressures and supersonic speeds, they rapidly loose thrust as speeds go into high supersonic and/or atmospheric pressure drop. Static thrust is moderate without afterburner and high with afterburner.
On planets and moons with favorable gravity and atmospheric pressure, some ships of lower mass and sufficient aerodynamic lift can reach orbit using only afterburning turbofans and ion engines.
Ramjets have almost no moving parts and use the motion of incoming air to generate thrust. They require an airspeed of Mach 0.5 to generate thrust and are optimized for low atmospheric pressure and supersonic to low hypersonic speeds. They loose thrust as speeds go hypersonic and/or atmospheric pressure drop. Ramjets have no static thrust.
Scramjets have moderate mass and moderate fuel efficiency.
While ramjets require initial airspeed to produce thrust, they can be combined with other jet engines to allow heavier ships to ascend to orbit through thick atmospheres and high gravity.
Scramjets are an evolution of ramjets and can ignite fuel without slowing down the intake air. This vastly improves performance at high supersonic and hypersonic speeds. However, scramjets are heavier, more costly to build and require a higher initial speed to produce thrust.
Scramjets require at least Mach 1.2 airspeed to generate thrust and are optimized for low to very low atmospheric pressure and hypersonic speeds. They loose thrust as speeds go high hypersonic and atmospheric pressure approaches vacuum. Scramjets have no static thrust.
In this post we've introduced Space256 and the project's ideas around physics and physics-driven gameplay. We've discussed high level principles around the Space256 game design, its opinionated physics model and the prototype implementation. Through designing and building the base game engine layers of physics from scratch, tailored to the Space256 model, we can bring about new types of gameplay that are hard or even impossible to create in existing game engines.
Thank you for reading this far! Feel free to reach out to us at bW9jLjY1MmVjYXBzQG9mbmk=
Stay tuned for our next post: Exploration & Procedural Generation!