.... I didn't forget to commit for a while... You can't tell
This commit is contained in:
+51
-3
@@ -49,6 +49,55 @@ Runtime state includes:
|
||||
|
||||
`DefaultMinigameService` handles definition-level actions and delegates live actions to the runtime service.
|
||||
|
||||
## Lifecycle Contract
|
||||
|
||||
The built-in lifecycle is intentionally minimal — most progression is **volume-driven**
|
||||
so map designers control exactly when things happen:
|
||||
|
||||
```text
|
||||
WAITING_FOR_PLAYERS set automatically on start; countdown runs (CountdownSeconds)
|
||||
|
|
||||
v
|
||||
STARTING set automatically when the countdown finishes
|
||||
|
|
||||
v
|
||||
ACTIVE set by a volume: SetMinigamePhase(ACTIVE) <-- REQUIRED
|
||||
|
|
||||
v (rounds: a SetRound effect starts round 1 and the $round timer)
|
||||
OVERTIME / SUDDEN_DEATH automatic after the final round, when enabled (timed)
|
||||
|
|
||||
v
|
||||
ENDING -> RESETTING via EndMinigame effect, /minigame stop, or round completion
|
||||
```
|
||||
|
||||
Hard rules:
|
||||
|
||||
- **A game refuses to start when no trigger volume carries a `SetMinigamePhase(ACTIVE)`
|
||||
effect for its minigame/map/variant ids.** Queued players are told why. This catches
|
||||
maps whose lifecycle wiring is incomplete instead of leaving the game stuck in `STARTING`.
|
||||
- The round system only runs after a `SetRound` effect fires (typically from the
|
||||
`SignalPhaseStart=ACTIVE` volume). `TotalRounds`/`RoundLengthSeconds` alone do nothing.
|
||||
- `SetMinigamePhase(ENDING)` and `(RESETTING)` route through the full end/reset lifecycle
|
||||
(cleanup, rewards, inventory restore) — they are equivalent to `EndMinigame`/`ResetMinigame`.
|
||||
- With `MapSelectionMode: VOTE` and more than one voteable map, reaching `MinPlayers`
|
||||
opens a 30-second vote window. The game starts when every queued player has voted or
|
||||
the window expires.
|
||||
|
||||
## Threading Model
|
||||
|
||||
Each Hytale world ticks on its own thread. The rules this module follows:
|
||||
|
||||
- Every `MinigameRuntime` records a **home world** at start (adopted on first pregame
|
||||
tick if unknown). All mutation of runtime state happens on that world's thread.
|
||||
- Ticking systems (pregame, HUD, queue UI, menu) run per world and only touch runtimes
|
||||
homed in their world.
|
||||
- The signal-service scheduler thread never mutates state directly — it hops onto the
|
||||
home world via `world.execute(...)`.
|
||||
- Queue sessions are shared across worlds and synchronized internally.
|
||||
- Adapter calls that need a result (`saveInventory`) only run on the player's own world
|
||||
thread; cross-world void calls (give item, teleport, restore) are forwarded with
|
||||
`world.execute` and never block the calling thread.
|
||||
|
||||
## Events
|
||||
|
||||
`MinigameEvent` implements Hytale's `IEvent<String>`.
|
||||
@@ -94,10 +143,9 @@ Current effect type IDs:
|
||||
- `ResetMinigame`
|
||||
- `SetMinigamePhase`
|
||||
- `ResetScores`
|
||||
- `ModifyPlayerScore`
|
||||
- `ModifyTeamScore`
|
||||
- `ModifyScore`
|
||||
- `ModifyCounter`
|
||||
- `ModifyPlayerLives`
|
||||
- `ModifyLives`
|
||||
- `SetPlayerStatus`
|
||||
- `JoinMinigameQueue`
|
||||
- `LeaveMinigameQueue`
|
||||
|
||||
Reference in New Issue
Block a user