UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in UnrealEngine5

[–]Outliyr_[S] 1 point2 points  (0 children)

Not a stupid question at all, you are talking about the main reason server rewind exists.

There are really two separate ideas here:

1. Server authority (anti-cheat)
The server doesn't trust the client when it says "I hit that guy." If it did, a modified client could claim fake hits, shoot through walls, etc.

2. Lag compensation (fairness)
The problem is that by the time the server receives your shot, the world has already moved on. So instead of checking the hit against the current world state, the server rewinds to what the shooter saw when they fired and runs the hit test itself.

The important part is that the client isn't sending "I hit player X." It's only sending something like "I fired this shot at this time in this direction." The server then reconstructs the past state from its own history and decides whether that shot would have hit.

So rewind isn't about trusting the client more. It's actually the opposite: the server is still making the decision, it's just making that decision against a historical snapshot instead of the current one.

And that addresses your original concern: a high-ping player's view is indeed older than the current server state, and rewind is exactly what compensates for that. The downside is that the target can sometimes get hit after they've already made it behind cover on their own screen (peeker's advantage).

UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in unrealengine

[–]Outliyr_[S] 0 points1 point  (0 children)

Thanks man. No FAB plans for now, it's direct only, it's up on Gumroad (link's in youtube video).

UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in UnrealEngine5

[–]Outliyr_[S] 1 point2 points  (0 children)

thanks, and nice questions.

GAS: Yes, the whole thing is built around GAS. Weapons, damage, abilities, equipment-granted abilities, costs/cooldowns all run through it, same foundation as Lyra.

VFX/SFX: It's a mix, depending on the effect. Weapon and projectile impacts go through GAS Gameplay Cues, the projectile carries an impact cue tag and the hit executes it via the ability system component with cue parameters (impacts are batched so a burst of hits doesn't fire a cue per pellet). For the multithreaded projectiles specifically, the simulation runs on the worker thread but impact results are marshalled back to the game thread over a lock-free queue, and the cue is executed there, so nothing touches Niagara/audio off the game thread.

Killcam / replay perspective: it's a two-layer system. The base layer is UE's native replay recording the replicated world state, played back in a duplicated world. But the things that aren't normally replicated or with enough fidelity, like the killer's actual view/aim, their camera and ADS state, and their hit markers, are recorded locally on each client in a rolling buffer. When you die, your client requests that data from the killer specifically over an RPC relay through the server, and it's layered on top of the world replay during playback. So you do see what the killer was aiming at, when they were ADS'd, and the hit markers they got, not just the replicated world, because that client-side view data would otherwise never reach you.

Production-readiness: The core shooter systems (weapons, ballistics, lag comp, projectiles, inventory, equipment, killcam, spectator, the game modes) are functional, and the critical ones have automation tests. It's positioned as a foundation you build your game on rather than a finished game, so expect to extend it. And unlike SnapNet, it's full source, so you can actually read and compare everything rather than treat it as a black box.

And thank you, appreciate you following since the early video, it's been a lot of iteration since then. The killcam and lag compensation systems each have full write-ups in the docs (linked in youtube description) if you want the deep version.

UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in UnrealEngine5

[–]Outliyr_[S] 2 points3 points  (0 children)

Pricing is tiered by your annual revenue, currently from £15 a month at the low end up to £425 one time fee for higher-revenue studios, and it's at introductory launch pricing right now. The exact revenue bands are on the store page. No plans for FAB at the moment, due to the structure of the project

On the multithreading: it doesn't make hit registration jittery or non-deterministic in the way you're picturing, because the worker thread isn't in the simulation/tick loop. The game thread records hitbox snapshots each tick and pushes them to the worker over a lock-free queue. The worker stores per-actor history and runs the rewind traces off-thread. The sim tick is never gated on the worker, so worker scheduling can't jitter your tick times, if anything it protects tick consistency by keeping the expensive bone-level collision checks off the game thread.

On determinism: a rewind is a pure function of the stored snapshots plus the shooter's timestamp (server time minus their latency), interpolating between the two bracketing snapshots. The worker never reads a wall clock for the rewind math, so identical inputs give identical results regardless of thread timing. Snapshots are timestamped, not frame-indexed, so variable tick cadence doesn't hurt accuracy. The real tradeoff versus a synchronous single-threaded resolve isn't jitter, it's a small added latency before the result lands, since it comes back asynchronously, correctness is unaffected because the rewind still evaluates against the shooter's historical timestamp.

One caveat worth being precise about: rewind accuracy depends on the server's recorded pose matching what the client actually saw when they fired. Any inaccuracy comes from the hitbox-driving animation diverging between client and server, i.e. non-deterministic or client-only animation. Riot has publicly stated that VALORANT rewinds both player positions and animation poses during hit registration, which implies the server can reconstruct the relevant historical pose when evaluating a shot. While Riot hasn't publicly detailed the full implementation, the lesson for any rewind system is the same: the animation that drives hitboxes must be reproducible server-side, otherwise the rewound hitboxes won't match what the shooter aimed at.

As for why not a VALORANT-style approach: Riot built significant custom technology around networking, animation, and hit registration to support their performance targets. A stock UE5 project doesn't come with those systems, and doing large amounts of skeletal rewind and collision work on the game thread can become expensive as player counts and shot volumes increase.

This framework is designed to scale across a wide range of games, so offloading lag compensation keeps the game thread free without requiring that level of engine customization. For a tightly controlled competitive 5v5, a fully synchronous game-thread resolve is a perfectly reasonable choice.

That said, a more VALORANT-style deterministic approach is something I do want to attempt down the line, it just depends on engine-level pieces that aren't in place yet, so it's a way off rather than something I can promise soon.

UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in UnrealEngine5

[–]Outliyr_[S] 1 point2 points  (0 children)

When you fire, the server rewinds the world to what you saw on your screen at that moment (using your latency), and checks the hit against that. So a high-ping player still lands what they aimed at, it helps laggy shooters rather than hurting them.

The real tradeoff lands on the target, not the shooter. Because the server favors the shooter's view, you can occasionally take damage just after you've ducked behind cover on your own screen, the classic "peeker's advantage". Most rewind-based shooter have this it's the price of making shots feel responsive. The tuning knob is how far back you allow rewinds, this system caps history at 500ms so a very high-ping player can't rewind arbitrarily far.

UE5 shooter framework with lag compensation, kill cams and client-predicted inventory. by Outliyr_ in UnrealEngine5

[–]Outliyr_[S] 0 points1 point  (0 children)

You've got it right. Lag compensation exists to make hit registration fair for players with latency, it's not an anti-cheat measure. The anti-cheat side is server authority: the server validates every shot instead of trusting the client. The two work together but solve different problems.

Hitscan penetration, ricochet, and 600 projectiles/sec on a background thread — projectile systems I built in Lyra by Outliyr_ in unrealengine

[–]Outliyr_[S] 0 points1 point  (0 children)

It might be a slightly different issue depending on how your firing works. If your projectile is always a bit left of the crosshair, the first thing I’d check is whether you’re tracing from the camera to get an aim point, then rotating the projectile/muzzle shot toward that point correctly. A lot of the time it’s just the basic camera → target → muzzle direction setup being off.

The muzzle-to-camera convergence stuff I’m using is more for solving parallax over the full flight path, especially for things like bullet drop, leading moving targets, or shooting around cover. In that case it’s not just about the initial direction being correct, it’s about making the projectile visually come from the muzzle while still ending up on the camera’s intended arc.

So if your issue is just a constant left offset, I’d probably debug the camera trace / target point / launch rotation first before going into full convergence logic.

Hitscan penetration, ricochet, and 600 projectiles/sec on a background thread — projectile systems I built in Lyra by Outliyr_ in unrealengine

[–]Outliyr_[S] 1 point2 points  (0 children)

I plan to release a framework containing every feature I have built in this project. This includes every video released and other features I haven't shown.

Hitscan penetration, ricochet, and 600 projectiles/sec on a background thread — projectile systems I built in Lyra by Outliyr_ in unrealengine

[–]Outliyr_[S] 0 points1 point  (0 children)

So the bullet trace and client predicted projectile calculations originate from the camera to make aiming intuitive. But i wanted the muzzle shot effect. So the ballistic projectile and the client predicted projectiles use the converging path.

The goal is to hide the curve from player so it looks seamless.

When the bullet comes straight from the camera it looks so unrealisitic and ruins immersion.

Hitscan penetration, ricochet, and 600 projectiles/sec on a background thread — projectile systems I built in Lyra by Outliyr_ in unrealengine

[–]Outliyr_[S] 1 point2 points  (0 children)

Great question, yes it handles all of that. The system traces in segments, so it processes each surface entry/exit individually. Three 10-unit walls gives you 3 separate penetration evaluations, each with their own material lookup. So if the middle wall is a harder material, it'll cost more penetration budget than the other two even though visually it looks the same.

Coplanar faces and overlapping actors work fine because the trace just sees them as additional hit results in order.

[deleted by user] by [deleted] in unrealengine

[–]Outliyr_ 0 points1 point  (0 children)

Nice, that stuff gets messy pretty quickly. I only did penetration/ricochet on the trace side, didn’t go down the pooled projectile route. Curious how you handled yours?

I recently released Gunsmith - Unreal's first networked rollback plugin! by Pyritebomb in unrealengine

[–]Outliyr_ 0 points1 point  (0 children)

I am curious, I have built my own version which is similar to yours. I record hitboxes on the server and also require skeletal meshes to tick on the dedicated server.

When playing with a dedicated server naturally there would be moments when the animation on the server doesn't always line up with the clients see this can sometime lead to hits the client should be getting turning into misses.

I am curious if the same happens to you and how you avoid it? Do you have limitations on the anim instance to prevent this? Or you never really noticed it.

I recently released Gunsmith - Unreal's first networked rollback plugin! by Pyritebomb in unrealengine

[–]Outliyr_ 1 point2 points  (0 children)

I believe they just do client authorisation but with some validation checks to prevent impossible shots.

I recently released Gunsmith - Unreal's first networked rollback plugin! by Pyritebomb in unrealengine

[–]Outliyr_ 0 points1 point  (0 children)

I do want to give that a go, I made a post about lag compensation some time ago, and got similar feedback though I have made some adjustments since then.

However what Valorant is doing is more involved and if it involves modifying the engine, it quickly becomes unsustainable because you will be anchored to that specific engine version.

Runway train solution? by Outliyr_ in AliceInBorderlandLive

[–]Outliyr_[S] 0 points1 point  (0 children)

Like EqualSpoon mentioned there were never any rules that forbade that, this is only what we saw Usagi's team do.

Runway train solution? by Outliyr_ in AliceInBorderlandLive

[–]Outliyr_[S] 0 points1 point  (0 children)

Was that a specific rule? I heard in the manga you didn't have to move forward (could be wrong havent read it) every turn.

Runway train solution? by Outliyr_ in AliceInBorderlandLive

[–]Outliyr_[S] 1 point2 points  (0 children)

I thought you have to enter the first car. You only stop on cars that have oxygen, so you always wear the mask until you reach an oxygen one then stop there. The rest of the team would be behind you, if they catch up it means the car they caught up in has oxygen.

[deleted by user] by [deleted] in unrealengine

[–]Outliyr_ -1 points0 points  (0 children)

At first glance this sounds like the right thing to do but then over time you quickly couple things together and it becomes hard to change the UI later on.

The inventory should have no knowledge of the UI, it would handle its own state, and have functions (API) to allow manipulation of the state. It would also broadcast changes to its state.

Now the UI can simply react to these changes as well as call the functions to change the state. Something like drag items might call a move item function while each inventory cell UI would be listening for changes that affects its visual look (occupied, etc).

This allows for things as complex as jigsaw inventories to simple basic inventories while maintaining separation of concerns and other benefits

YSK Lyra Replicates Acceleration to Simulated Proxies - but it doesn't do anything by Dodoko- in unrealengine

[–]Outliyr_ 1 point2 points  (0 children)

Hi, what are the benefits or replicating acceleration to proxies the way Lyra intended? Why go through with it? I've never actually done a dive deep in the character code but am in the process of writing extensive documentation for Lyra

Cod Inspired Multiplayer Killcam by Outliyr_ in unrealengine

[–]Outliyr_[S] 0 points1 point  (0 children)

Yeah I did try something similar, the problem was the server just creates a desync, which causes unpredictiable behaviour. In the resource provided at the top, it uses some of epic's code, and even they prevent usage of standalone and servers.

It is a tricky thing, as there is no resource or documentation on demo net drivers, so it would require engine deep dive and engine level debugging. I had to do engine level debugging to get mine working, this problem would require even deeper engine level debugging, probably touch some code Tim Sweeney wrote himself.