Hi, it’s Hopfel writing for a change! I will try to also contribute to this Patreon page from now on, giving an insight into our base systems implemented in C++.
Our game needs to accommodate for multiple species of different sizes, body makeup and movement capabilities. We’ve opted to implement our own physics based movement to fit the resulting requirements. In this series of articles I will give a technical overview over what we ended up implementing for our game.
The Unreal Engine comes with a powerful, highly optimised built-in movement system (See UCharacterMovementComponent) which I will often compare our system to.
Like the Unreal default, our movement system relies on a capsule for collision. A capsule is defined by a radius and half-height, spanning a pill-like volume. Due to its elongated shape it can sufficiently approximate the shape of a character while still being very efficient for collision detection. Due to its hemispheres at each end it also reliably computes the surface direction (normal) on collisions with the floor and ceiling (where for example a box would often report undesired results).
Where our system differs from the Unreal default is that the capsule does not engulf the whole character but only their minimal shape (meaning, the smallest volume the character can reasonably be compressed into without clipping or taking damage). While the Unreal default movement needs to change the capsule size (e.g. on crouching), this allows our capsule to remain constant. This constant shape mitigates a lot of problems connected to getting stuck when un-crouching and allows us to physically simulate the core as a rigid body.
Notice how this means the capsule needs to be hovering in mid-air for movement on the ground. This is achieved with a “mass on a spring”-like system, making crouching a continuous activity that can model recovery after landing or running into a steep slope.
The movement core is always physically simulated using Symplectic Euler Integration. Physics simulation allows us to accurately define external forces like gravity, drag and buoyancy which depend on character properties like mass, volume and surface area which differ for each species and can even change during gameplay. For example, heavier species (or characters that hold heavy objects) will not just be slower like it is usually implemented in games, they will properly feel heavier.
(60kg on the left, 120kg in the middle, 180kg to the right)
These properties are partially inherent to the species. Heaviness is one example, but also imagine slim lizard characters being able to slip through water faster than chubby dragons due to their smaller surface area. Opposite to that, chubby dragons will be harder to push off a platform. All of these properties are not explicitly defined on these characters but are an outcome of their physical properties. If the slim lizard suddenly carries a giant flat board under water they become as slow as the chubby dragon. If the chubby dragon is tied to helium balloons they become easier to push off platforms.
(characters with higher surface area experience more drag)
All of this becomes very exciting once you add physics volumes to the mix that also have properties such as density and gravity. Imagine micro-planets with spherical gravity, similar to Super Mario Galaxy. Add to that influences like centrifugal forces and acceleration of your frame of reference. This system lends itself to creating gravity puzzles and weird world settings (for example a planet spinning so fast the centrifugal force on the character noticeably counteracts gravity).
(Centrifugal and acceleration forces make the character “lean” towards artificial gravity)
For all of this to make sense we need to be able to rotate the characters. Very often (which is also the case for the Unreal default movement system) gravity is always applied from top down and the only rotation is yaw (around the up-axis), but since we wanted to rotate an object around all axis we needed to look into angular momentum and torque.
Angular momentum and torque are properly implemented with the bounding box approximating the character’s mass distribution. The inertia tensor makes it so certain axis of rotation are harder to rotate than others. This will especially come into play when swimming or flying, where rolling goes faster than tilting.
Especially for fluids but also for high velocities (e.g. when flying) drag becomes very important. It dampens movements in viscous fluids and gives characters a natural terminal velocity. Drag is computed with the current physics volume density, the character’s velocity and an approximation of the character’s surface area in movement direction. Here we cannot only use the boundary box for approximation since most characters have a relatively sparse surface. To get a reasonable guess we only consider the total surface area of each axis (stored as percentage for each bounding box face) and average over the desired movement direction to get the final surface area.
(counting white pixels and compare with total amount of pixels)
(comparison in differently viscous fluids)
We have planned very light and very heavy creatures of very different volumes. Here it makes sense that those react differently to fluids. For example, chubby dragons might not be able to dive down because of their low mass/volume ratio. Very small and heavy characters might not be able to swim at all but instead walk underwater (or for example by holding something very heavy like a metal ball). All of these effects are about buoyancy. Buoyancy measures the displacement of matter in your surroundings. Since the surrounding density and the character’s volume is known, the total buoyancy can be computed accurately. We do also account for depth since characters usually get compressed the deeper they dive. They might even start falling and be able to walk on the ocean floor (and possibly start taking damage without protection due to their organs being highly compressed).
(air to the left, very thick atmosphere in the middle, water to the right)
There are a lot of exciting features already implemented in TGOR that use physics simulation (as outlined above), and there are endless possibilities to add to that. There are however serious problems with this approach (some intrinsic to movement systems in general), requiring a balance to be struck between features, usability and visuals.
Visual glitch using our custom IK system that adapts to step-height.
(Naive movement replication with 90% synthetic package loss, would be unplayable for people with e.g. mobile connection.)
(Comparison between 30 fps and 5 fps)
There are a lot of internal systems we’ve so far kept from writing Patreon posts about since they tend to be technical in nature. As the game is coming together however these systems become visible and progress can be shown.
More is to come soon, let us know what you think!
Cheers,
Hopfel
Furry Lover
2019-04-11 13:24:53 +0000 UTCMud Dog
2019-04-11 03:05:01 +0000 UTCJonathan Brown
2019-04-10 22:14:39 +0000 UTC