game design – engineering – narrative

Over the past few weeks I’ve been working on a project that started as an experiment around Unreal’s Chaos Modular Vehicles plugin.

Here is what I’ve got so far.

Gameplay Pillars

In this project I want to give players shifting emotional beats. Chill, relaxed moments leading to tense challenges the players choose for themselves.

The premise is simple:

Players fly a simplified, Arcade-y FireBoss AT-802 and put out fires by spraying them down with water. The systems I’m building are aimed towards the experience. That being said, the pillars of that experience are intended to bring meaning to that experience that goes deeper than that simple conceit.

The pillars:

  • Players choose their risk, but they are compelled to take some.
  • The danger is real, but it’s worth facing.
  • Players have the tools they need, but they’re also what they’re sacrificing.
  • Players are managing the situation, with valleys of low intensity tasks and peaks of heroic moments.
  • The sacrifices players make are worth it.
  • Chill vibes leading to tense moments, leading to rising elation.
  • Flying is a tactile experience.
  • Pursue emotion instead of realism.
  • This is a multiplayer, collaborative experience.
  • Players can have different roles that mesh with one another.

The whole project, at this point, is right at the very beginning, but I’ve already mapped out the technical problem space that I’m facing. I want to build a solid foundation so that I’m front-loading the hardest parts of the whole project as much as possible.

Technical Problem Space

This is what I’m trying to model:

  • Flight mechanics with cartoonish verisimilitude; it ‘feels’ right, even if it’s wholly inaccurate.
  • Fire that burns, spreading, and affecting the player whenever they fly through it.
  • Gameplay mechanics affect the physics behavior of objects without completely gamifying them.
  • … And everything is replicated.

Modular Vehicles

The tools I’m using speak to the needs laid out by the project. Unreal 5.8 with Chaos Modular Vehicles opens up the capacity to play with out-of-the-box physics interactions without having to reinvent (most of) the wheel. It’s natively networked, with the ability to go towards a push model, and potentially leverage Mass down the road.

Gameplay Ability System

Much like the Modular Vehicle plugin, GAS is also a network-native plugin. It does a lot out of the box to enable gameplay effects going from one entity to the next on the wire. It’s a system I’m fairly familiar with (but there’s always more to learn) so there’s a lot that I don’t have to build myself if I use it.

Interoperability

The first obstacle that comes from these choices is that they have no default means to communicate with each other. Physics events don’t have any inherent meaning to GAS, and the reverse is also true.

Physics World / Gameplay World

Getting them to talk to one another is a complicated issue; Chaos Physics operates in a completely different context than GAS, which can be oversimplified (but reasonably explained) thusly: GAS operates on the game thread on the CPU, and Chaos Physics operates on its own thread.

This means that communication between them would have to happen through a complex set of mechanisms that would likely have a significant performance impact.

But, there are ways.

This is (one of) the Way(s)

The Aircraft

First off, here’s the inheritance/components structure of my custom pawn:

  • ModularSkeletalVehiclePawn
    • VehicleBaseSimComponent
    • SkeletalMesh
    • NetworkPhysicsComponent
    • AircraftBase
      • AbilitySystemComponent
      • AircraftStateComponent

Breaking this down:

  • The physics state is produced by the pawn’s base class and sent over the wire by the network physics component.
  • The skeletal mesh is rotated and animated by reading two sources:
    • The physics state of the vehicle base sim component
    • The input state being fed to the pawn by the controller.
  • The Ability System Component gets the following granted to it at BeginPlay:
    • CatchFire Ability
    • SprayExtinguisher Ability
    • OverallDurability Gameplay Effect
    • AircraftBase Attribute Set.
  • AircraftStateComponent will read the GAS attribute set events and populate the vehicle state.

Communication between the physics simulation will happen via the VehicleBaseSimComponent’s Input containers, much like how it consumes player inputs. They also have a State container which holds the same kind of values, but is by default unused.

All of this sets us up for the following flow:

Annotated code screenshot showing damage values for fixed, elevator, rudder, and wing aerofoils affecting force calculations.

The “damage” value being injected here isn’t passed on raw by the AircraftStateComponent. Instead, it operates on the basis of thresholds.

Unreal Engine editor showing aircraft component health settings and C++ code for monitoring engine damage and disabled states.

The fact that we’re using gameplay effects means that we also have mechanisms to spawn VFX on the aircraft whenever it’s taking damage, and those VFX instances are managed over the network out of the box.

Blue aircraft flying over sandy desert dunes with flames trailing behind it.

The Fire

Fire is a notorious thing to build in games. I’m not tackling the majority of the challenges that come from trying to dance with that devil, but I am trying to set myself up for success.

Fire Manager, Fire Fields

Fires in my prototype are spawned by a fire manager, which controls the intensity of each “field”, and interprets gameplay events that each one causes/is affected by. The purpose of this structure is to keep each instance of the “fire class” to be as lightweight as possible, while also having a place for centralized control. This will enable pooling and tweaking later on, as well as facilitate the inevitable refactors.

Here’s how the entire flow is working for this part of the prototype

Diagram showing VFX and Player Pawn overlap sections with three color-coded hatched boxes.

The player’s extinguisher ability also hits fields, but the effect is dealt with by the fire manager’s ability system’s component (ASC). The result of this is a single ASC managing multiple distinct entities.

This is a very early stage of the system overall.

Gameplay Feel

This sets damage to components to be a series of “cliffs” so the player has a healthy margin to take risks, but they will immediately feel whenever they’ve been to pay a price.

The goal is to give immediate feedback when significant events happen, and being able to tie into those events in a discrete way. I want to be able to have the aircraft feel like it’s fighting to stay flying for the player, but it’s not a fight that it can win if the player keeps pushing it.

The damage model reflects that as well by splitting damage into two components: Integrity and Durability.

Code editor showing a C++ Unreal Engine gameplay effect execution class for calculating fire damage, integrity, and durability.

The above is a calculation class that’s used by gameplay effects that are targeted to discrete components of the aircraft, which have module counterparts on the physics simulation.

Bottom line of all of this:

  • Each component can take damage independently from the rest
  • The intensity of the fire the player flies through has a greater chance of burning their aircraft.
  • … And the damage it’ll do is multiplicatively greater.
  • The aircraft will burn, but keep flying.
  • Components will degrade, and burn easier, until they’re completely destroyed.
  • Players can limp home, but they’ll have to fight the aircraft to do it, if they’ve been too reckless.

Leave a Reply