Skip to content

Commit 48a6577

Browse files
committed
readme update
1 parent 3514b97 commit 48a6577

2 files changed

Lines changed: 275 additions & 197 deletions

File tree

README.md

Lines changed: 135 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -6,117 +6,120 @@
66
<img alt="platform" src="https://img.shields.io/badge/platform-SCP%3ASecret%20Laboratory-6f42c1">
77
<img alt="api" src="https://img.shields.io/badge/api-LabAPI-2ea44f">
88
<img alt="runtime" src="https://img.shields.io/badge/runtime-.NET%20Framework%204.8.1-512bd4">
9-
<img alt="protocol" src="https://img.shields.io/badge/protocol-.c0%20V9-0a7ea4">
9+
<img alt="protocol" src="https://img.shields.io/badge/protocol-.c0%20V13-0a7ea4">
1010
<img alt="timeline" src="https://img.shields.io/badge/timeline-deterministic-1f6feb">
11-
<img alt="fps" src="https://img.shields.io/badge/fps-dynamic-ffb000">
12-
<img alt="downloads" src="https://img.shields.io/github/downloads/MiaoMiao4567/Causality-0/total">
11+
<img alt="status" src="https://img.shields.io/badge/status-pre--release-orange">
1312
<img alt="license" src="https://img.shields.io/badge/license-AGPL--3.0-red">
14-
<img alt="status" src="https://img.shields.io/badge/status-experimental-orange">
1513
</p>
1614

1715
<p align="center">
18-
<strong>A deterministic replay engine for SCP:SL rounds.</strong>
16+
<strong>A deterministic replay engine for SCP:SL rounds</strong>
1917
</p>
2018

2119
<p align="center">
22-
<em>What vanishes from the server should still remain readable in time.</em>
20+
<em>Rounds should remain replayable after they end</em>
2321
</p>
2422

25-
> A multiplayer round should not disappear the moment it ends.
26-
2723
---
2824

2925
## Overview
3026

3127
Causality-0 is a LabAPI-based replay plugin for SCP: Secret Laboratory.
32-
It records server-side player state into a deterministic timeline, serializes it as a `.c0` replay file, and later reconstructs that round in-game with dummy actors, preserved timing, and seed-aware playback rules.
28+
It records server-side round state into a deterministic timeline, stores it as a `.c0` binary replay, and reconstructs that round in-game with dummy actors, preserved timing, world-state restoration, and seed-aware playback rules.
3329

34-
It is built less as a spectacle system and more as a way to leave a round behind in a form that can still be revisited.
30+
The project is focused on reproducibility rather than cinematic approximation.
31+
Whenever possible, playback restores recorded results directly instead of re-simulating fragile live runtime behavior.
3532

3633
---
3734

38-
## Current architecture
35+
## Current capabilities
3936

40-
### ⏱️ Deterministic timeline
37+
### Deterministic timeline playback
4138

42-
Replay time is driven by frame index and step size instead of wall-clock drift.
43-
That keeps:
39+
Replay time is driven by frame index and per-file FPS metadata.
40+
That keeps actor movement, interactions, projectiles, and optional voice packets aligned to the same timeline.
4441

45-
- actor movement
46-
- voice packets
47-
- interaction events
48-
- projectile motion
42+
### Actor lifecycle support
4943

50-
bound to the same timeline.
44+
The replay pipeline now supports:
5145

52-
### 🧟 Native actor playback
46+
- players who join after recording started
47+
- players who leave or disconnect before round end
48+
- role changes during the round
49+
- death lifecycle events
50+
- delayed dummy spawning based on track start frame
51+
- playback despawn on recorded leave
5352

54-
The project does not treat replay as pure transform theater.
55-
Where possible, it reuses native SCP:SL systems so movement, state, and side effects stay closer to the game’s own rules.
53+
### World-state persistence
5654

57-
### 💾 `.c0` binary protocol
55+
The replay format now persists world state beyond actor tracks.
56+
Current world reconstruction covers:
5857

59-
Current replay protocol version is **V9**.
58+
- map pickups present at recording start
59+
- pickup create and remove events
60+
- pickup movement persistence
61+
- locker and chamber contents
62+
- locker/chamber open state restoration on load
6063

61-
It stores:
64+
### Projectile persistence
6265

63-
| Field | Notes |
64-
| --- | --- |
65-
| Map seed | Used to validate world correctness |
66-
| Replay FPS | Embedded in the file for playback speed |
67-
| Actor frames | Position, rotation, item state, stats |
68-
| Audio packets | Timestamped raw voice payloads |
69-
| Interaction frames | Door interaction timing |
70-
| Lifecycle events | Role changes and death events |
66+
Projectile tracks are now written into `.c0` files together with owner information.
67+
Loaded replays can restore projectile playback without relying on the original live runtime state.
68+
69+
### Deterministic door playback
7170

72-
### 🌍 Seed-aware playback
71+
Door replay now restores the recorded interaction result directly.
72+
It no longer depends on re-running live permission checks during playback, which improves stability and avoids common pass-through issues.
7373

74-
Replay is world-sensitive.
75-
If the replay seed does not match the current map, playback can be blocked or the next round can be scheduled to regenerate with the replay seed.
74+
### Optional voice recording
7675

77-
### ♻️ Lifecycle event stream
76+
Voice packet capture is available but now configurable.
77+
Voice playback still works for replays that already contain saved audio data.
7878

79-
An actor track no longer means a single uninterrupted life.
80-
The replay format now supports:
79+
### Seed-aware replay loading
8180

82-
- role changes
83-
- death events
84-
- spectator phases
85-
- later respawn / reassignment playback
81+
Replay files embed the recording map seed.
82+
If the loaded replay seed does not match the current round seed, the plugin can force a restart so the replay can be loaded on the correct map seed next round.
8683

8784
---
8885

89-
## Replay lifecycle
90-
91-
```mermaid
92-
flowchart LR
93-
A[Live round] --> B[Record frames and events]
94-
B --> C[Deterministic timeline]
95-
C --> D[Serialize .c0]
96-
D --> E[Load replay]
97-
E --> F{Seed matches?}
98-
F -- No --> G[Schedule restart with replay seed]
99-
F -- Yes --> H[Spawn dummy actors]
100-
G --> H
101-
H --> I[Apply lifecycle and movement]
102-
I --> J[Replay items voice doors projectiles]
103-
```
86+
## `.c0` protocol
87+
88+
Current replay protocol version is **V13**.
89+
90+
It currently stores:
91+
92+
| Field | Notes |
93+
| --- | --- |
94+
| Map seed | Used to validate world correctness |
95+
| Replay FPS | Saved in the file and restored on load |
96+
| Actor tracks | Position, view rotation, movement state, held item, stats |
97+
| Audio packets | Optional raw voice payloads with timestamps |
98+
| Interaction frames | Door interaction timing and result |
99+
| Lifecycle events | Role changes, death, leave/disconnect |
100+
| World pickups | Initial world pickup snapshot |
101+
| Pickup ops | Add, move, remove |
102+
| Locker states | Chamber contents and open state |
103+
| Locker ops | Recorded locker interaction results |
104+
| Projectile tracks | Projectile frames and owner id |
104105

105106
---
106107

107108
## What is currently recorded
108109

109-
- player position and rotation
110+
- player position and view rotation
110111
- movement state and grounded state
111-
- held item and firearm attachments
112-
- shooting and reloading intent
113-
- usable item start / cancel intent
114-
- health and armor-like values
115-
- voice packets
116-
- door interaction timing
117-
- projectile tracks
118-
- role-change events
119-
- death events
112+
- held item and firearm attachment code
113+
- shooting and reload intent
114+
- usable item start and cancel intent
115+
- HP and AHP-like values
116+
- optional raw voice packets
117+
- door interaction timing and result
118+
- late join and leave lifecycle changes
119+
- projectile tracks and owner ids
120+
- world pickups and pickup movement
121+
- locker/chamber contents and state
122+
- role changes and death lifecycle events
120123

121124
---
122125

@@ -142,46 +145,90 @@ c0 play
142145

143146
### Behavior notes
144147

145-
- `load` reads `.c0` metadata, including seed and replay FPS
146-
- old replay files fall back to a compatibility FPS path
147-
- playback is blocked if actors are missing
148-
- playback can be blocked or deferred if the current map seed does not match the replay seed
148+
- `start` begins a new recording from the current state
149+
- `save` writes the current replay into `CausalityRecords/<name>.c0`
150+
- `load` reads seed and FPS metadata before playback
151+
- `load` rebuilds world state when the replay seed matches the current round
152+
- if the replay seed does not match the current round, the plugin schedules a restart with the replay seed
153+
- `play` starts deterministic playback of the loaded or recorded timeline
154+
- `spawn` can still be used for manual dummy spawning workflows
155+
156+
---
157+
158+
## Configuration
159+
160+
The plugin now supports configuration through `config.yml` in the LabAPI plugin config directory.
161+
162+
Current config entries:
163+
164+
```yml
165+
default_record_fps: 60
166+
record_voice: false
167+
```
168+
169+
### Current config behavior
170+
171+
- `default_record_fps`
172+
- sets the default FPS for new recordings
173+
- affects new recordings only
174+
- does not change the FPS embedded in existing replay files
175+
176+
- `record_voice`
177+
- enables or disables saving player voice packets during new recordings
178+
- when disabled, replay files still record all non-voice data normally
179+
- loading and playing older voice-enabled replays still works
149180

150181
---
151182

152183
## Core files
153184

154185
- [Causality0.cs](Causality0.cs)
186+
- [Causality0Config.cs](Causality0Config.cs)
155187
- [Core/Timeline.cs](Core/Timeline.cs)
156188
- [Core/Serializer.cs](Core/Serializer.cs)
157189
- [Core/ActorTrack.cs](Core/ActorTrack.cs)
190+
- [Core/ProjectileTrack.cs](Core/ProjectileTrack.cs)
158191
- [Core/LifecycleEvent.cs](Core/LifecycleEvent.cs)
159-
- [Core/DamageData.cs](Core/DamageData.cs)
160-
- [Core/DummyInputWrapper.cs](Core/DummyInputWrapper.cs)
161-
- [Core/DummyMotorWrapper.cs](Core/DummyMotorWrapper.cs)
192+
- [Core/WorldData.cs](Core/WorldData.cs)
162193
- [Command/RemoteAdmin/Causality.cs](Command/RemoteAdmin/Causality.cs)
163-
- [Event/ServerEvent/MapGenerating.cs](Event/ServerEvent/MapGenerating.cs)
194+
- [Event/PlayerEvent/Verified.cs](Event/PlayerEvent/Verified.cs)
195+
- [Event/PlayerEvent/Lifecycle.cs](Event/PlayerEvent/Lifecycle.cs)
164196
- [Event/PlayerEvent/VoiceChat.cs](Event/PlayerEvent/VoiceChat.cs)
165197
- [Event/PlayerEvent/Interacting.cs](Event/PlayerEvent/Interacting.cs)
166-
- [Event/PlayerEvent/Lifecycle.cs](Event/PlayerEvent/Lifecycle.cs)
198+
- [Event/PlayerEvent/Lockers.cs](Event/PlayerEvent/Lockers.cs)
199+
- [Event/ServerEvent/Pickups.cs](Event/ServerEvent/Pickups.cs)
200+
- [Event/ServerEvent/MapGenerating.cs](Event/ServerEvent/MapGenerating.cs)
167201

168202
---
169203

170-
## Roadmap
204+
## Current limitations
171205

172-
The next steps should feel like a continuation of the same timeline, not a promise made too far ahead of the code.
206+
The project is still pre-release and some systems are still being refined.
207+
Current known gaps or ongoing work include:
208+
209+
- ragdoll / corpse / death-scene ecosystem persistence
210+
- some structure-specific restoration edge cases for special lockers and display structures
211+
- automatic round recording policy and autosave workflow
212+
- broader interaction replay coverage beyond the current implemented set
213+
214+
---
215+
216+
## Roadmap
173217

174218
- [x] Deterministic replay timing
175-
- [x] Dynamic replay FPS metadata
219+
- [x] Replay FPS embedded in replay files
176220
- [x] Seed-aware replay loading
177-
- [x] Voice packet capture and playback
178-
- [x] Door interaction recording and playback
179-
- [x] Projectile replay path
180-
- [x] Actor lifecycle event stream
181-
- [ ] Broaden interaction replay beyond doors
182-
- [ ] Stabilize death and ragdoll playback edge cases
183-
- [ ] Improve replay inspection and debugging tools
184-
- [ ] Add configuration-driven replay policy
221+
- [x] Late join actor recording and playback
222+
- [x] Leave/disconnect playback removal
223+
- [x] Optional voice recording configuration
224+
- [x] Door interaction recording and deterministic playback
225+
- [x] Projectile persistence and playback
226+
- [x] World pickup snapshot and movement persistence
227+
- [x] Locker/chamber state persistence
228+
- [ ] Automatic round recording and autosave policy
229+
- [ ] Ragdoll / corpse persistence
230+
- [ ] Broader structure-specific world restoration fixes
231+
- [ ] Replay inspection and debugging tools
185232

186233
---
187234

@@ -194,11 +241,3 @@ The next steps should feel like a continuation of the same timeline, not a promi
194241
## License
195242

196243
This project is distributed under the terms of [GNU AGPL v3](LICENSE.txt).
197-
198-
---
199-
200-
## Final note
201-
202-
Causality-0 is still experimental.
203-
But a round may end at the scoreboard, and its causality does not have to end with it.
204-
This project exists to leave that causality on the server, waiting to be called back in the correct world.

0 commit comments

Comments
 (0)