Astral Productions - Technical Gameplay Design

Want to read something specific? Jump to…

Storm Reavers

What is storm Reavers?

The plan is dead. The guards are closing in. You flip gravity and the floor becomes a wall, flying sideways toward the exit with the loot in your arms. Storm Reavers is a co-op heist game where every job falls apart and every player can save the run. Plans may fail, but gravity doesn’t.

Storm Reavers is ultimately a co-op heist game driven by gravity. My goal was to create a replayable co-op experience like recent hits ala R.E.P.O or Lethal Company but with more mechanical depth and combat — so less horror and more combat.

Design Details

Version 1 and the pitfalls.

Version 1 of Storm Reavers began around January 2026 with Gravity and PCG-based Island Generation as the two centerpieces of the game.

The idea was to build replayability around procedural island generation as the backbone of the experience. Points of Interest would spawn across the map, and players would gradually work their way toward an objective — get in, get out, heist-style. In isolation, this worked. Gravity was an excellent way to move through the world. The PCG islands held up on their own. The problem was putting them together.

How do you stop players from using gravity to skip the on-foot exploration the islands were built around? I tried the obvious answers:

  • A cooldown on gravity usage

  • A distance limit

  • A mana cost, paid for as long as gravity was active

  • A duration limit — gravity cuts out after some fixed time

  • Some mix of all of the above

I landed on a mix: a mana cost via GAS, ticking down for as long as gravity stayed active. It worked, but only barely. Players could still cross the map faster than the island design accounted for. Gravity wasn't complementing island generation, it was actively opposed to it. Gravity wanted to be a fun, fast way to move. Island generation needed players to slow down and explore on foot, to find things naturally instead of skipping to them.

That's the wall I kept hitting: nerf gravity enough to protect the exploration loop, and I'd be sanding down the best part of the game, the thing Storm Reavers was actually about. Don't nerf it, and island generation, the pillar the whole loop was built on, couldn't do its job. Neither side could give. That's the pivot.

Version 2 - Bernal Spheres

Ever heard of a Bernal Sphere? That's the core of version 2.

Instead of islands, I went full steam ahead on a true 3D generator — a mix of custom C++ generation for the sphere itself, plus a PCG pass for the procedural POIs layered inside it. This solves a few problems at once:

  • Generation is genuinely three-dimensional, not scattered across a 2D plane and called "explorable"

  • Enemies get real space to operate in, instead of being pinned to a single walkable layer

  • The core fantasy gets sharper — true omnidirectional movement, not movement that's fast but still secretly flat

Original Bernal Sphere concept via Wikipedia

A couple of questions worth answering directly:

Why not do this sooner? Generating a sphere/planet seems obvious.

Because it's dramatically more work. Unreal — and most of its built-in systems — isn't built for omnidirectional space by default. NavMesh breaks. PCG breaks. A long list of calculations that assume "up" means one fixed direction need to be reworked from the ground up. It essentially takes a few months of work total and scales the tech dev time alone (no gameplay) to a month or so.

What's the biggest challenge?

NavMesh, easily. AI pathing on walls, ceilings, anywhere that isn't a flat floor needs a custom voxel-based pathfinding solution. Generating the voxel space is its own challenge. Rethinking how AI actually moves through that space is a bigger one. AI needs to have comprehensive information to figure out not just which direction to go, but when and how to change gravity.

That decision shapes a lot of what's below.

The loop, inside a sphere:

Each sphere is a self-contained heist. You drop in, you scavenge, you get out, and the clock is not a suggestion. Difficulty escalates the longer you stay: enemy spawn rate climbs, and so do their stats becoming more aggressive, more accurate, tougher to put down. Eventually the exit itself starts to close, and getting caught in that closure is lethal. There's no backing out once you're committed. You finish the run or you don't.

The one lever you have against that clock is risk. Small, frequent objectives buy you a little time each. Rarer, harder ones, a high-value kill, a hidden cache, buy you a lot. The sphere is daring you to stay just a little longer.

Combat is ranged-first, melee as a backup when something gets in your face. Gravity is fully manual - point anywhere, and you're falling straight away. This is a derelict structure full of things that want to kill you, not a tranquil floating-puzzle box. And the enemies aren't blind to it, they read your gravity orientation and react to it, so reorienting isn't just traversal, it's a tell you're giving away every time you do it.

Loot follows the same risk logic as the clock. Baseline salvage is quiet, grab it, move on, nobody notices. The good stuff is loud. Cracking it open draws attention, and that attention doesn't stay put, it starts local and spreads outward the longer it goes unanswered. Whatever you scavenge and actually carry out the door is yours for good, which is the real hook keeping you in a sphere past the point where leaving would be the smart move.

Between spheres:

Each sphere connects to the next via a bridge, locked behind a puzzle or key objective found somewhere inside that run. Those objectives are varied and semi-procedural, one run might mean infiltrating a tower to activate a power source, another might drop you in front of a field boss that means business. Different enough to feel fresh each time, not so different that you lose your bearings. This is the throughline that replaces the old island-to-island pacing: progression isn't "explore until the map's done," it's "survive this sphere, unlock the next one."

There's a lot more to get into, how the spheres themselves actually get generated, but that's its own section, further down.

Bernal Sphere Generation from the outside, ~~~~ 50,000 units radius

25 Spheres generated with connecting bridges and directional aware outcomes.

Gravity - design + Tech

Gravity was initially an experimental idea for me, as Epic had exposed their gravity logic to blueprints only a version or two prior. With that I dove into the idea with a handful of gravity types:

  1. Directional Gravity - Gravity that causes you to fall exactly towards your hit direction.

  2. Plane Gravity - Gravity that causes you to fall towards the normal (or plane) of the hit surface. This is closer to the six cardinal directions. Less percise, but much faster to use.

  3. Tethered Gravity - Very similar to planetary gravity where you will continue to fall towards the hit location even if you go past it. This creates a sort of slingshot effect.

  4. Gravity Flip - A single input press that swaps your gravity to the inverse of your current gravity (e.g. 0,0,-1 swaps to 0,0,1). It does require a valid surface above you to work however.

  5. Gravity on Run/Move - This is effectively foot based gravity as it checks your foot location, velocity, and determines the best gravity based on those values. This allows players to run on/across a surface with varied normals such as a sphere.

Gameplay Ability + Replication

The core logic for the gravity mechanics relies primarily on normals, traces, and a mix of GAS and RPC logic.

Gravity was initially an experimental idea for me, as Epic had only exposed their gravity logic a version or two prior. With that I dove in with a handful of gravity types: Directional, which falls exactly toward your hit location; Plane, which snaps to the nearest cardinal direction of the hit surface normal for faster less precise shifts; Tethered, which anchors to a world position and continuously recalculates the pull vector even after you pass it, creating a slingshot effect; Gravity Flip, a single input that inverts your current gravity vector gated behind a ceiling trace so it cannot be used in open air; and Gravity on Run, which samples your foot position and velocity each tick to compute gravity from the surface beneath you, allowing players to run across geometry with varied normals like the outside of a sphere.

Under the hood, each gravity type resolves to a direction vector which gets fed into Epic's exposed gravity override on the Character Movement Component. The heavier lifting is in how each type arrives at that vector. Directional and Plane both fire a single trace on activation and derive the vector from the hit result, with Plane adding a quantization step to snap to the nearest cardinal. Tethered stores the hit location as a persistent anchor and recalculates toward it every frame, which required careful handling to avoid fighting the CMC during transitions. Gravity on Run is the most involved, running a multi-trace sample from the foot each tick and blending normals to smooth out transitions across uneven geometry. GAS handles activation and state signaling, while the actual vector math and CMC overrides are driven from the Character Blueprint with manual RPC calls to keep replication clean.

Ragdoll

One of the goals I had for the gravity mechanic was a high opportunity cost. You could traverse distances quickly, sure, but there needed to be a risk. As such I opted for a sort of quick time event. Right before the player lands they can press their dodge input to gain momentary Iframes from fall damage. This has other effects as well, but if they fail they take fall damage and get ragdolled.

Having never (personally) made a replicated ragdoll I didn't quite estimate just how challenging this would be.

My first approach relied on Gameplay Abilities using existing logic to activate/deactivate logic. However this proved unreliable as the GA didn't properly replicate across clients. It looked great on server, but clients would often get bad desync as Gameplay Abilities aren't designed to work on Tick.

The next approach was a Hybrid, using GAS to activate/signal to activate the ragdoll, but driving the core logic via the character blueprint. This approach proved much more reliable as GAS replicates organically, then any additional RPC calls can be handled manually.

The hybrid approach works by having the Gameplay Ability fire an RPC to the Character Blueprint the moment the ragdoll condition is met, which then sets the mesh to simulate physics and applies the custom gravity override locally on each client. Because physics simulation state is inherently non-deterministic across the network, the server acts as the authority on when ragdoll begins and ends, broadcasting those events via multicast RPCs rather than trying to sync the raw physics frames themselves.

Recovery works on a timer driven from the server, and once the recovery window opens, the Character Blueprint blends back from physics to the AnimGraph using a Get Bone Transform snapshot, snapping the capsule to the mesh's current pelvis position before re-enabling movement. This prevents the jarring teleport you get when the capsule and mesh diverge during a long ragdoll.

The custom gravity component presented its own wrinkle here since standard Character Movement gravity is bypassed during physics simulation, meaning the gravity had to be re-applied as a direct impulse or force on the physics body rather than through CMC. This was handled via a tick-driven force application on the mesh's root body, scoped to only run while the ragdoll state is active, and disabled immediately on recovery to avoid fighting the CMC on re-enable. Just to be clear about what would happen here: if the ragdoll activated on, say, the roof the capsule of the character would properly be on the roof, but the mesh itself would fall onto the ground. This made for horrible desync as it seemed like the player was on the ground, not the roof, then they'd snap and tp back to the roof.

The Problem

Storm Reavers takes place on a Bernal sphere — a hollow celestial body where actors walk on the interior shell with gravity pointing radially outward from the center. That single design decision breaks every assumption Unreal's built-in navigation makes. NavMesh is flat. Gravity is global. "Up" is always world-Z. None of that holds when a skeleton can walk on the floor, rotate to the ceiling, and cross to a wall as three equally valid movement states.

The first question wasn't how to build the system. It was whether an existing plugin could be used or adapted at all.

Evaluating Existing Solutions

Two plugins were evaluated: Nav3D and CPathfinding. Nav3D looked promising but its voxelization assumed axis-aligned chunks placed at known positions — which broke immediately on a procedurally generated sphere where the shell location isn't known at build time. Covering only the thin walkable shell was impossible without voxelizing the entire interior volume. At any useful resolution, generation crashed or took minutes. It was shelved.


CPathfinding was an abandoned plugin with only an older version available, but its core approach — wrapping the entire region in a single volume and only voxelizing what's inside managed to avoided the chunk placement problem entirely. Fast generation, clean architecture. It became the foundation.

Tech Notes

Extending CPathfinding to become OmniNav

Air Voxel Pruning
Ground-bound enemies should never path through open air. CPathfinding has no concept of surface adjacency, so a post-generation pass was added to flag air voxels and skip them during pathfinding for non-flying actors.

Gravity-Aware Path Annotation
The biggest gap in CPathfinding was that it had no concept of gravity direction. A flat sequence of waypoints is useless if the AI doesn't know that waypoint 12 requires rotating to a wall. The solution was annotating the path itself — walking every waypoint and detecting where gravity needs to change before the AI starts moving.


The first attempt at this failed in an instructive way. Using a one-shot gravity check before path execution, the system would detect the wrong surface through walls and switch gravity immediately — leaving the AI walking to a destination that was now above them. The fix was evolving the gravity state across the entire path upfront, so each transition is correct relative to what came before it.

Runtime Auto-Partitioning
The Bernal sphere's scale blew past CPathfinding's hard node count limit. Rather than manually placing volumes the volume now detects at runtime when it would exceed the limit and automatically spawns a grid of smaller sibling volumes covering the same bounds with no editor pre-baking, no manual setup, all handled at generation time. Coupled with proximity-based scheduling, nearby navigable space is ready almost immediately while distant regions fill in progressively.

Tech Notes

nnotated paths don't move anyone. A custom movement component consumes the path and per tick decides: skip ahead to the farthest visible waypoint, compute the correct movement direction relative to current gravity, and at each transition point decide whether to walk through the gravity change or teleport past it.

This component simultaneously acts as the bridge between the character movement component and path data, and as the decision-maker for when and how transitions actually happen. Path annotation tells us where a transition might occur — but AI and players move in unorthodox ways, and annotation alone isn't foolproof. To handle this, a series of cheap line traces run continuously using three pieces of data:

  • Down vector — lets the AI walk alongside curved surfaces like the sphere seamlessly, hugging the shell rather than drifting off it.

  • Movement vector — detects when the AI has hit a wall or surface it should transition onto, catching transitions the annotation missed.

  • Gravity direction — checks whether the AI is genuinely ready to commit to new gravity independent of where it's currently moving.

In practice, the combination of these three traces provides enough spatial awareness at low cost to handle the messy reality of how AI actually moves through the world.

Edge Cases

AI falling into the sky

Gravity switches that fired before the actor was physically on the new surface caused AI to fall away from the sphere entirely. A surface verification guard now runs before committing any gravity switch to prevent this. But prevention isn't enough on its own, since knockback, edge cases, and unexpected geometry can still send an AI into open space. As a fallback, the AI periodically checks whether it has fallen off a surface entirely and, if so, converts its gravity toward the player's direction. Combined with the line trace system, the AI will work its way back to the player despite the initial error rather than falling forever.

Teleport fallback

Some transitions simply can't be walked. If the AI determines the transition point isn't reachable from its current stance, the component nudges the actor past the ambiguous boundary rather than forcing an awkward walk. This is particularly relevant for cubic or hard-edged geometry, since an enemy moving from one face of a cube to an adjacent face has no smooth arc to follow around the edge at any reasonable cost. Teleporting is the honest solution: it's cheaper, more reliable, and invisible to the player at the distances it typically occurs.

Air-voxel ambiguity

Voxels in open air return no surface normal, which caused the annotation pass to drift through air gaps assuming stale gravity, only catching the real transition once a waypoint happened to land close enough to the new surface, often too late. The fix was treating a missing normal not as nothing to act on, but as a signal itself. At the first ambiguous waypoint, the system adopts the destination's gravity directly rather than waiting for a valid probe to come back. The absence of information becomes the trigger rather than a reason to stall.

Island Generation

Proof of concept island generation taken around Feb 2026.

Enemies that can use Gravity too…

Coming soonTM - This section will contain information on how I approached practical AI design in 3D space using the Voxel system detailed above.


About

Gameplay Designer

B.S. Interactive Design

3+ Years Exp.

Resume

Location

Columbus, Georgia

Will relocate

All content on this site was designed and developed by Cole Andrews, unless otherwise noted. Any third-party tools, assets, or references are credited where applicable.

About

Gameplay Designer

B.S. Interactive Design

3+ Years Exp.

Resume

Location

Columbus, Georgia

Will relocate

All content on this site was designed and developed by Cole Andrews, unless otherwise noted. Any third-party tools, assets, or references are credited where applicable.