Valhalla Rumble: one of the sample multiplayer games shipped with 0.7.0:
[0.8.0] update, 2026-10-10

Legend:
demos ·
fix ·
act on this in your own project ·
behaviour change ·
covered by tests ·
soak harness ·
docs ·
new
Animation montages now roll back, an offline match can rewind, and components can own rollback
state. A second sample game, Rewind Arena, shows all three in 3D, and shows two peers playing
over the UDP transport after finding each other through an OnlineSubsystem Null LAN session.
Supported engines are unchanged (5.5, 5.6, 5.7, 5.8; 5.8 primary) and so is the wire protocol
(v6): a 0.8.0 peer plays a 0.7.0 peer as long as both run the same game.
Added — runtime
-
URollbackAnimationComponent— montages as rollback state. Each character’s montage
timeline (which montage, from which simulation frame, at which integer play rate, from which
section and offset, blending from what) lives inAnimState, which the component contributes to
the actor’s snapshot. A rollback, a rewind or a determinism audit restores the pose exactly —
mid-swing, mid-blend — because the pose shown is evaluated from the state for the frame being
presented (URollbackAnimInstance,Nativedrive mode), not advanced by an animation clock.- Simulation API, all taking the frame being simulated:
PlayMontage/PlayMontageAsset,
JumpToSection,StopMontage,DelayTimeline(hit-stop that also holds the windows and root
motion),IsInNotifyWindow,WasNotifyFired,GetSectionAt,GetMontageFrame,
GetRootMotionDelta(actor space;RootMotionAxeshandles the UE mannequin’s −90° mesh). MontageSyncdrive mode keeps your own Anim Blueprint: the component holds the montage paused
and sets its position every frame.- Corrections you can see:
AnimationCorrectionCountandOnAnimationCorrected(Frame, Before, After)report every rollback that changed what a character was playing. PresentationFrameOverridescrubs the pose to any frame the timeline covers.
RollbackCorePro.Animation.*. - Simulation API, all taking the frame being simulated:
-
URollbackMontageData,URollbackNotifyWindow, Bake Rollback Montage Data. Gameplay never
asks the animation system anything. Each montage carries a baked per-frame table (animation
metadata, so it cooks with the asset): length, sections and links, notify windows, blend times and
cumulative root translation at the project’s fixed tick rate. Rollback Window notify states
(URollbackNotifyWindow) let designers place hit / cancel / invulnerability windows on the
animation. Bake from the Content Browser (right-click montages) or
URollbackMontageBakeLibrary::BakeMontages;IsMontageBakeCurrentreports a stale bake. Montages
without data are baked at first use, with a warning, whenbAllowRuntimeBakeis on.
RollbackCoreProEditor.BakeLibrary.RejectsUnusableMontages,RollbackCorePro.Animation.BakedMontageLookups. -
IRollbackStateContributor— state that lives on a component. A component that implements it
names its own properties; the actor’sURollbackStateComponentsaves, restores, checksums and diffs
them after the actor’s own (ordered by component name, then property), names them
Component.Propertyin desync reports, and callsOnRollbackStateRestored(Frame)after a load.
New on the state component:GetTrackedPropertyNames()andRefreshTrackedProperties().
RollbackCorePro.State.*Contributor*. -
URollbackManager::RewindToFrame(Frame)— offline rewind without replay. Every entity is
restored to the frame, which becomes the present; the nextAdvanceFrame()continues on a new
branch, and each entity’s history after the frame is discarded
(IRollbackEntity::DiscardRollbackHistoryAfter, a new virtual with an empty default). Refused while
a peer is connected, during a rollback, and for a frame without a complete snapshot. Plus
CanRewindToFrame,GetOldestRewindFrameandRewindCount(rewinds are not rollbacks).
RollbackCorePro.Rewind.*. -
URollbackManager::OnRollbackBegin/OnRollbackEnd(native multicast,(RollbackFrame, CurrentFrame)): fired by every accepted rollback before state is restored and after the replay
caught up, never by a rewind. Presentation that wants to know what a rollback changed records its
view on Begin and compares on End — the animation component detects corrections this way.
Fixed
-
Struct members without SaveGamewere silently not rolled back. Snapshots serialize with
the SaveGame flag, and the engine then skips any member of a tracked struct that is not
UPROPERTY(SaveGame)— on save and on restore, so no checksum ever disagreed. The state component
now logs a warning naming each such member when it builds its schema. Natively serialized structs
(FVector,FQuat, …) are written whole and are unaffected. If the warning names one of your
members, mark itSaveGame(or confirm it is meant to stay out).
RollbackCorePro.State.StructMembersWithoutSaveGameAreReported. -
An empty UDP datagram stopped the transport reading for the rest of that pump. PumpSocket
treated a zero-length datagram like “nothing to read” and stopped, so every packet queued behind
it waited for the next pump — and the empty datagram itself was never counted. It is now counted,
rejected and skipped. Found by the new malformed-packet test;RecvFromreturns false for “no
data” on both the BSD and EOS socket subsystems, so a successful zero-byte read is always a real
empty packet.
RollbackCorePro.Network.MalformedPacketsAreRejected— 53 hostile datagrams
(empty, truncated, oversized and negative counts, NaN axes, negative frames, unknown types and
flags, zero nonce, foreign magic, seeded random bytes): every one rejected exactly once in a single
pump, no peer created, no input buffered, and a real peer still connects afterwards.
Added — Rewind Arena, a 3D sample game
-
Rewind Arena (RollbackArenaGame, a non-ShippingDeveloperToolmodule; content in
/RollbackCorePro/ArenaGame). OpenMap_RewindArenaand press Play, or runRollback.PlayArena.
Two UE5 mannequins, Ember and Frost, fight on a rune-lit platform at sunset, animated only by
montages that roll back.- Modes: Versus CPU (three difficulties), Local Versus, Training with hold-to-rewind (
R/
left trigger runs fighters, montages and clock backwards; let go to play on), Netplay Lab,
Online, Showcase, Options, About. - Fighting from the montage: a Jab → Cross → Hook chain that may continue only inside its
RB_Cancelwindows, a Roundhouse, a meter-powered Rush carried by baked root motion, block with
chip, sidesteps invulnerable insideRB_Invuln, knockdowns, hit-stop viaDelayTimeline. Every
hit window is a notify state on the animation. - Rollback Lens: a ghost of every mispredicted pose, drawn from the correction’s Before
timeline, and a panel with rollbacks, resimulation depth, montage corrections, ghosts drawn,
replayed effects skipped, mispredicted inputs or desyncs, and the link. - Online, two peers: Host LAN Match advertises a Null OSS session through the plugin’s
HostRollbackSessionnode; Find LAN Matches lists sessions (FindRollbackSessions); joining
one (JoinRollbackSession) handshakes the UDP transport and both machines start the fight — host
seat 0, joiner seat 1. Direct IP is the fallback. Match rules are rollback state, ticked after
both fighters, so trades and rounds replay together; rematch needs both players. If the rival
disconnects, the match stops cleanly and says so instead of stalling. - Presentation reads the simulation and never writes it: an orbit / fight camera, impact
sparks and rings deduplicated byFRollbackCosmeticEventFilter, a rewind grade, a glyph halo
above the arena that spins backwards while rewinding, flickering braziers, CC0 audio reused from
Valhalla Rumble. HUD and menus are UMG widgets painted inNativePaint, so Movie Render Queue
records them. - Content (~47 MB): the UE5 mannequins from Unreal Engine’s templates (Epic Games), 19 original
animations and 17 baked montages authored in Blender by script, an original procedural arena, all
authored in UE 5.5 (Tools/ArenaArt/Author-ArenaAssets.ps1) so it loads on every supported
engine.
20 tests under RollbackArenaGame.*:Combat,Assets,Animation,Fighter,
Rewind,Online,Flow,Presentation. - Modes: Versus CPU (three difficulties), Local Versus, Training with hold-to-rewind (
-
Demo/Run-ArenaP2PDemo.ps1— host and joiner side by side on one machine (-Auto: the AI
plays both seats;-Packaged: a packaged build). -
Tools/Verify-ArenaOnline.ps1— the same two processes headless, CI-safe: fails unless the
joiner finds the session through Null, both peers start and keep simulating, neither reports a
desync and at least one rolled back. First run on UE 5.8: 4,560 frames per peer, 2,223 rollbacks,
483 montage corrections, 0 desyncs. -
Console commands Rollback.PlayArena,ArenaVsAI,ArenaLocal2P,ArenaTraining,ArenaLab,
ArenaShowcase([ember|frost] [auto]),ArenaRewind,ArenaNetHost,ArenaNetJoin,
ArenaDirectHost,ArenaDirectJoin,ArenaMenu.
Changed
The Setup Wizard’s Package The Sample packages both samples: it adds
/RollbackCorePro/VikingGameand/RollbackCorePro/ArenaGameto Directories To Always Cook and
both maps to Maps To Cook. A project that packaged only the Viking sample with 0.7 is offered the
button again.
RollbackCoreProEditor.Wizard.PackageTheSampleCooksContentAndMap.
RollbackCorePro.upluginlists theRollbackArenaGamemodule (DeveloperTool, Win64 / Linux /
Android).
Soak harness: §12.13 and §12.14 closed
§12.14, the soak’s intermittent permanent divergence, was the harness. It set the local
pawn’s input once per loop iteration, so when oneTick()caught up several frames the same input
was scheduled for all of them while the send loop put the correct per-frame inputs on the wire. This
machine never produced a multi-frame Tick on its own (0 in 8 full soak runs, with and without the
harness’s repair), so the soak now forces them:RCPSoak.Hitch.CatchUpAdvancesStayInSync
stalls peer A’s process for 3 frames every 90 and requires zero divergence across 13 catch-up
advances;RCPSoak.Hitch.ControlWithoutRepairDivergesruns the same hitches with the repair off and
requires the worlds to diverge (first desync 13 frames after the first catch-up; 61 and 73
steady-state desyncs). An integration that sends what its state component scheduled
(GetInputForFrame(Frame), as both samples do) cannot diverge this way.
§12.13, BurstLoss’s window: bursts are now scheduled (the link goes dark both ways for 13
frames at 6 s and 13 s) instead of Poisson-distributed, and the window of 32 carries its
derivation (13 + 2 round trips + input delay = 25, + jitter margin). Six standalone runs: peak
confirmation lag 20–22 every time (the random model ranged 26–46), deepest rollback 30.
Tools/Soak-Pacing.ps1expects 9 tests.
Verification
207 automation tests pass on each of UE 5.5.4, 5.6.1, 5.7.4 and 5.8.3 (clean build per engine,
counted from the engine’s JSON report): 106RollbackCorePro.*(30 new), 4RollbackCoreProEditor.*,
77RollbackVikingGame.*, 20RollbackArenaGame.*.Tools/Run-AutomationTests.ps1now includes
RollbackArenaGameby default and fails below 200 tests.
RunUAT BuildPlugin -StrictIncludes(no PCH, no unity): UE 5.8 and 5.7 for Win64 and Android
(NDK Clang, arm64 + x64), 5.6 for Win64 and Android, 5.5 for Win64 (no Android support installed
for 5.5). The strict build found one include a unity build had hidden, in a test file; fixed.
Linux game target on UE 5.8 with Clang 20.1.8: every module, 0 warnings.
Pacing soak 9/9 on UE 5.8; BurstLoss6/6 more on its own.
Tools/Verify-Matchmaking.ps1andTools/Verify-ArenaOnline.ps1(two processes each) pass.
Every shipped asset loads on UE 5.5 (Check-AssetEngineCompat.ps1: 276 assets ≤ package version
1013).
Looked at, not just logged: Rewind Arena’s title, menus, online page, Versus / Showcase fights,
the Netplay Lab with ghosts, Training’s rewind on UE 5.8; the Showcase and Netplay Lab on UE 5.5; and
the two-window online demo with both windows on the same frame and 0 desyncs. Looking found three
things no test had: impact rings three times too large, fighters lit by their own rim term at
dusk exposure, and HUD / ghost colours that followed the seat instead of the fighter (now pinned by
RollbackArenaGame.Flow.MenuStartsTheChosenModeAndFighter).
Docs
New Docs/arena-demo.md. Manual: new sections Animation Rollback and Rewind (later sections
renumbered), component state and the SaveGame-member rule under State Capture, API and console
tables. QuickStart: State that lives on a component, Montages that roll back, Rewind
(offline). FAQ: montages, component state, rewind.credits.mdcovers Rewind Arena.