Skip to main content

fforge_core/
event.rs

1//! The event log โ€” the game state *is* this append-only stream.
2//!
3//! Two principles from DESIGN.md ยง6 shape what gets recorded:
4//!
5//! 1. **Record resolved values, not raw inputs.** `GameStarted` carries the
6//!    *generated world snapshot*, not just the seed: if only the seed were
7//!    stored and the world re-derived on load, any improvement to worldgen
8//!    would silently corrupt every old save โ€” the same failure mode as
9//!    re-parsing raw LLM text. Worldgen is an edge producer whose *output* is
10//!    the recorded input.
11//! 2. **Record outcomes the fold consumes without re-running engines.**
12//!    `MatchPlayed` carries the result; replay folds over it and never
13//!    re-simulates, so upgrading the match engine (Phase 2) can never rewrite
14//!    history. Live play produces these events via `step`; replay just eats
15//!    them. This is exactly how recorded agent `Decision`s will enter in
16//!    Phase 5 โ€” human lineups (`LineupSubmitted`) already follow the pattern.
17
18use fforge_domain::{ClubId, Fixture, FixtureId, GameDate, Lineup, World};
19use serde::{Deserialize, Serialize};
20
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22pub enum Event {
23    /// Opening event: seed, generated world, schedule, and which club the
24    /// human manages. Everything the fold needs, self-contained.
25    GameStarted {
26        seed: u64,
27        start_date: GameDate,
28        player_club: ClubId,
29        world: World,
30        schedule: Vec<Fixture>,
31    },
32    /// The human manager's resolved, validated team-sheet decision for the
33    /// upcoming matchday.
34    LineupSubmitted { matchday: u8, lineup: Lineup },
35    /// A simulated result. (The rich minute-by-minute match event stream is
36    /// the Phase 2 artifact; this scoreline is the walking-skeleton stub.)
37    MatchPlayed {
38        fixture: FixtureId,
39        matchday: u8,
40        home_goals: u8,
41        away_goals: u8,
42    },
43    /// The calendar advanced past a matchday.
44    MatchdayAdvanced { matchday: u8, new_date: GameDate },
45    /// Season complete.
46    SeasonEnded { champion: ClubId },
47}