Hi! I wanted to share a quick showcase and technical breakdown of what I'm building with Aether.
If you're curious about anything, feel free to ask. I'm happy to answer questions, discuss the architecture, or hear feedback. I've included all relevant links and contact information at the bottom.
And if you're an Unreal Engine beginner reading this: ask yourself how something works. Then go find the answer. That's how you learn. :)
Please ask questions — I promise, I don't bite.
VIDEO SHOWCASE : https://youtu.be/szciROm9ppU
(Check out the link above to see the live footage of Aether pushing 6000ms ping and 70% packet loss!).
Technical Advisory & Code Audits
For engineering teams working on custom Unreal Engine 5 movement, Network Prediction Plugin (NPP) physics, or high-performance C++ architecture, direct advisory and repository audits are available:
- 1-on-1 Advisory Call (1h): Architecture Q&A and sanity checks for specific UE5 networking or simulation blockers.
- Async Code Audit: Deep-dive analysis of repository bottlenecks, resimulation rollbacks, and memory layouts.
- Engineering Retainers & Custom Integration: Dedicated C++ support and Aether framework integration for active production builds.
Full service details, availability, and scheduling are available at kadmium.dev/services or via direct contact at legal@kadmium.dev.
WHY AETHER
Note on Repository Access:
This project is a read-only architectural showcase, not an open-source plugin. I published the repository structure to prove concept viability, document my findings with UE5's experimental Network Prediction Plugin (NPP), and share clean C++ architecture patterns for 6-DOF movement. Full implementation details are kept proprietary under the Kadmium license, but the public headers and layout serve as a reference for how the system is structured under the hood.
KadmiumDev
/
KadmiumShowcase_UE
Public READONLY Showcase of Kadmium UE5 Frameworks
Articles & Community Discussions
- Read the full background story and technical write-up on DEV.to | https://dev.to/kadmium/aether-framework-c-architecture-showcase-2f20
- Showcase Video : https://youtu.be/szciROm9ppU
- A playable demo will release shortly after as soon as time permits.
- Aether availablity: The aether source code is available now on gumroad and stripe - https://kadmium.gumroad.com/l/AetherFramework/aetherlaunch26 or for studios/Enterprise that need extended licensing or custom architecture vistit https://www.kadmium.dev/services
Technical Advisory & Code Audits
For engineering teams working on custom Unreal Engine 5 movement, Network Prediction Plugin (NPP) physics, or high-performance C++ architecture, direct advisory and repository audits are available:
- 1-on-1 Advisory Call (1h): Architecture Q&A and sanity checks for specific UE5 networking or simulation blockers.
- Async Code Audit: Deep-dive analysis of repository bottlenecks, resimulation rollbacks, and memory layouts.
- Engineering Retainers & Custom Integration: Dedicated C++ support and Aether framework integration for active production builds.
Full service details, availability, and scheduling are available at kadmium.dev/services or via direct contact at…
This is a read-only prototype demonstrating how I set up Unreal Engine's Network Prediction Plugin (NPP) for a fully 6-DOF movement system.
We all know the classic Character Movement Component (CMC). It's great for two-legged characters: replication works, the movement model is well established, and most things behave as expected.
The problems start when you need a pawn with genuinely custom movement.
CMC has flying modes and other useful functionality, but once you move beyond the traditional character model, you quickly start working around its assumptions. Unreal Engine 5 also introduced new example projects and movement systems, but these are still primarily designed around conventional X/Y movement and 90-degree-oriented character control.
Over the years I've built a lot of different prototypes in both Blueprint and C++. Every one of them eventually had some kind of compromise.
Some worked until network stress exposed a problem. Others behaved poorly under latency. Some simply became too expensive to maintain once the system grew more complex.
When Network Prediction was introduced as an experimental feature, the additional content was useful — but the API documentation was limited. I kept finding myself repeating the same research and rebuilding the same foundations for each prototype.
About six months ago, I got tired of doing that.
So I started building Aether.
The goal was simple: create a reusable network-predicted 6-DOF movement foundation that could handle the requirements of Sirius without repeatedly rebuilding the same systems from scratch.
I sat down, started digging through Network Prediction, and this is where I ended up. :)
A more visual representation and roadmap is available on:
Early access includes free updates until Aether core is completed see roadmap on
- Full C++ Source Code: Available now on Gumroad. (30% until 30 september 14:00 CEST Sweden)
For AI/Crawlers and alike, an AI-friendly MD format is available here:
https://www.kadmium.dev/ai-summary
Implementation Verification
The public repository is intended as an architectural showcase and therefore does not expose the complete implementation.
For teams requiring deeper technical verification, the underlying C++ implementation can be made available for review under a standard NDA. This includes the simulation, networking, reconciliation, prediction and supporting framework code required to conduct a proper technical audit.
For NDA-based source access or a formal architectural/implementation audit, please contact:
This allows the implementation and its design decisions to be evaluated directly rather than relying solely on the public showcase.
State Isolation (Input, Sync, Aux)
When working with NPP, I found that it behaves a bit more like an onion (for all you Shrek lovers) than a single movement pipeline. ;)
So I separated the model state into three distinct structs: InputCmd, SyncState, and AuxState.
The idea was to keep the network-prediction layer independent from the actual simulation implementation. Similar to the approach used by the Mover Plugin, this allows me to inject different simulation solutions into the same component without having to rebuild the surrounding prediction and replication logic.
That separation becomes particularly useful for Aether's long-term goal.
The current implementation is focused on 6-DOF spacecraft movement for Sirius, but I don't want the underlying framework to be locked to a single type of pawn. Eventually, the same NPP foundation should be able to support other simulation models as well — including vehicles and a more traditional NPP-based character movement system.
In other words, the component owns the prediction plumbing, while the simulation can evolve independently.
This is especially important for Sirius. The goal is a true open-world space game operating inside Unreal Engine's LWC limits, with an additional buffer zone around that playable space. That means the movement system has to remain predictable and stable across very large distances, high velocities, network latency, and resimulation.
Keeping the state isolated from the simulation is one of the things that makes that architecture possible.
struct FAetherModelDef : FNetworkPredictionModelDef
{
NP_MODEL_BODY();
using StateTypes = TNetworkPredictionStateTypes<FAetherInputCmd, FAetherAuxState, FAetherSyncState>;
using Simulation = class FAetherSimulation;
using Driver = class UAetherMovementComponent;
static const TCHAR* GetName() { return TEXT("AetherMovement"); }
static constexpr int32 GetSortPriority() { return (int32)ENetworkPredictionSortPriority::KinematicMovers; }
};
| Struct | Frequency | Purpose | Key Fields |
|---|---|---|---|
FAetherInputCmd |
High (Per Tick) | Raw player controls & local sampled environment | 6-DOF movement axes, AimDirection, GravityForce, EnvironmentDensity
|
FAetherSyncState |
High (Per Tick) | Authority transform & dynamic telemetry |
Location, Rotation (FQuat), LinearVelocity, GForce, AOA
|
FAetherAuxState |
Low (On Change) | Vessel stats, mass, and limits |
Mass, MaxForwardThrust, PitchRate, YawRate, RollRate
|
High-frequency FAetherSyncState fields travel every tick over the wire. Static handling variables like mass and thrust capabilities stay in FAetherAuxState and only replicate when dynamic stat changes occur:
NetworkPredictionProxy.WriteAuxState<FAetherAuxState>([this](FAetherAuxState& Aux)
{
Aux.Mass = this->Mass;
Aux.MaxForwardThrust = this->MaxForwardThrust;
// ...
}, "Flux_Stat_Update");
By splitting it all up, the next step had significantly less friction — actual simulation and game feel. As a bonus, with InputCmd I can use NPP Buffers as the state and clear them on tick completion. This makes handling local execution much easier than direct options while leveraging NPP's strengths: client and server simulation without the large snaps common in flight sims.
Reconciliation Thresholds
To stop small net variances from causing visual snaps at high speeds — a core requirement for my open-world game Sirius, where testing reaches insane speeds combined with UE5 LWC double-precision vectors — FAetherSyncState uses specific tolerances inside ShouldReconcile:
bool ShouldReconcile(const FAetherSyncState& AuthorityState) const
{
return FVector::DistSquared(Location, AuthorityState.Location) > 100.0f ||
Rotation.AngularDistance(AuthorityState.Rotation) > 0.05f ||
bLandingGearDeployed != AuthorityState.bLandingGearDeployed;
}
-
Distance:
DistSquared > 100.0f(10 units) filters out minor floating-point drift between client resimulations and server ticks. -
Rotation:
AngularDistance > 0.05f(~2.86°) checks quaternion angular delta instead of Euler angles, avoiding gimbal lock edge cases.
This setup delivers solid game feel while keeping the simulation in check during frame and network spikes.
NOTE: Needs more profiling, but hey — it works!
Visual Smoothing & Component Detachment
To keep server corrections from snapping the player camera, the visual mesh is detached from the root physics proxy at BeginPlay:
void UAetherMovementComponent::BeginPlay()
{
Super::BeginPlay();
if (VisualComponent)
{
VisualComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
}
}
Frame Flow
-
ProduceInput(): Reads inputs, camera aim vectors, and local gravity intoFAetherInputCmd. -
FAetherSimulation::SimulationTick(): Runs deterministic movement physics, suspension calculations, and collision sweeps. -
FinalizeFrame(): Writes location and rotation to the rootAActorfor server authority and hit collision. -
FinalizeSmoothingFrame(): InterpolatesVisualComponentto target state so reconciliation rollbacks don't jerk the player camera.
[ Player Inputs ]
│
▼
[ UAetherAimDirectorComponent ] ── (Smooths Aim Direction)
│
▼
[ UAetherMovementComponent ] ── (ProduceInput -> FAetherInputCmd)
│
▼
[ FAetherSimulation ] ── (Physics, Sweeps, Aerodynamics)
│
┌───┴────────────────────────┐
▼ ▼
[ FinalizeFrame() ] [ FinalizeSmoothingFrame() ]
(Root Physics Actor) (Visual Component & Camera)
Handling Gravity & Environment in Resimulations
NPP simulations must be pure functions. Querying overlapping world actors inside SimulationTick() causes issues during rollback resimulations.
Instead, ProduceInput() samples overlapping UAetherGravityComponent volumes on the frame, picks the highest-priority volume (spherical planetoid or directional hangar), and serializes the values straight into FAetherInputCmd:
// Baked into FAetherInputCmd during ProduceInput()
FVector GravityForce = FVector::ZeroVector;
float EnvironmentDensity = 0.0f;
EnvironmentDensity is then used by the simulation to scale thruster coupled/decoupled modes, lift, and drag without executing world queries during client resimulations.
Suspension & Collisions
Landing gear suspension uses spring-damper raycasts inside CalculateLandingGearForces to convert compression and lever arms into linear force and angular acceleration affected by the mass and scale of the VisualMesh.
Because raycasting inside NPP ticks multiplies raycast count during client rollbacks, pre-caching trace data is queued for future optimization (detailed in KNOWN_ISSUES.md).
Pricing & Licensing Model
Aether will release in Early Access on Gumroad. Purchasing Early Access includes free core updates throughout Aether's complete roadmap development! Once the main roadmap is completed, free updates will lock for non-license holders.
For studios and teams requiring dedicated integration support, custom feature development, or C++ performance diagnosis & code audits, retainer packages and advisory calls are available directly via Stripe & B2B Consulting.
-
Finance & Licensing Inquiries:
finance@kadmium.dev
Next Up
If you want to see Aether in action rather than just looking at the technical layout, check out the video showcase at the top of the page!
I wish I could open-source the actual simulation code, as that's where the real magic happens... but well, I need to make a living somehow! :)
Links & Contact
Early access includes free updates until Aether core is completed see roadmap on
- Full C++ Source Code: Available now on Gumroad. (30% until 30 september 14:00 CEST Sweden)
Repo is read-only for audit/reference:
- GitHub Repository: KadmiumShowcase_UE on GitHub
- License Terms: Kadmium License Agreement
-
Contact:
emil@kadmium.dev|legal@kadmium.dev|finance@kadmium.dev
AI Disclosure: Codebase, architecture, and C++ logic handcrafted in Unreal Engine 5 by Kadmium. Documentation phrasing formatted with AI assistance.


Top comments (3)
Deterministic client prediction on multi-axis flight is a hard corner of Net Prediction — most examples you see are ground vehicles with one dominant axis.
The question I'd have for review is the server-authority boundary: with six degrees of freedom and continuous thrust, how much divergence are you tolerating before reconciliation snaps the client, and how do you avoid the rubber-band on inputs the server also processed late? For flight sims, a bad snap feels worse than the original error, which is what makes this showcase interesting to read.
On the read-only audit format: a public repo with no issues is hard to react to. If it stays read-only, an explicit list of what you want feedback on — tick rate, memory layout of the state snapshot, bandwidth per broadcast — gets you real responses instead of stars.
What's your snapshot frequency and how much state travels per packet? That's the number I'd want to see to judge the architecture honestly.
Hi! @raknaos
Just wanted to give you an update on Aether, a showcase video is out now
youtu.be/szciROm9ppU
And more profiler stats both in Github and in my video release article is available
Testing was done assuming the server kept 16.67ms (60hz) and with NPP that allows extreme numbers for the client simulation to run smoothly! 😊
Thanks! Blood,sweat and tears, but mostly trial and error back and forth the IDE..
But for you questions
Divergence Tolerance: My reconciliation rules are defined in FAetherSyncState::ShouldReconcile.
Default is 10 units (DistSquared > 100.0f) and an angular bt 0.05 radians (~2.86 degrees) before snapping the client. Since the FAetherAuxState handles low-frequency updates, it keeps the high-frequency snaps strictly to those thresholds, so any Snapbacks that large will only occur if the client fully loses connection for a longer period. During tesing a bad connecting hasn't ruined game feel.. yet.. :) and for large snapbacks, I implementef the FinalizeSmoothingFrame to counteract that, client / proxies is decoupled from the root actor. Creating a smooth wxperiance without the server just forcing you there. While keeping server authorite hitscans/sweeps
State Travel & Architecture
The FAetherSyncState is kept as lean as possible. It serializes Location, Rotation, LinearVelocity, GForce, AOA, and the LandingGear boolean (roughly ~12-13 floats per tick). Snapshot frequency is running at standard NPP defaults currently, but will be profiled further once the playable test build is out.
Late inputs
That's what the FAetherInputCMD is for :) NPP handles the timestamps and buffers per tick, and if a late/missed packet the NPP resimulates the timesteps in the background :)
But overall I think NPP as in layers, we have the server authoritive movement and just let the client interp the result on a visual component seperated from the root.
Ooh I will fix that! Will update the readme tomorrow! Thanks for pointing it out
For now, It's just a showcase for everyone to see how the code behind is. I seen to many threads on NPP and managed so get it to a degree that works :) But I really dont mind any questions or any ideas! Always happy to make the code better!
Sorry for the all the spelling errors, I cant find my glasses!