ajhahn.de
← Theria
GDScript 48 lines
class_name SimState
extends RefCounted
## The full authoritative world state at one tick.
##
## A pure data container: the simulation reads and advances it, nothing else.

## Monotonic simulation tick counter (starts at 0).
var tick: int = 0

## Entities keyed by their integer id. Insertion order is stable, which keeps
## iteration over the world deterministic.
var entities: Dictionary = {}

## The team that has won, or -1 while the match is ongoing. Set when a team's
## nexus is destroyed; once set, the simulation freezes (`step` no-ops).
var winner: int = -1

## Presentation-only record of the casts resolved this tick — one entry per cast, each
## carrying its origin, landing point, area radius, effect, target kind, and status, for
## the renderer to flash a skillshot line or an area zone. Cleared at the top of every
## `step` (so it never carries a stale cast) and never serialized onto the wire, so it
## stays a pure LOCAL/HOST render hint: a snapshot-fed CLIENT simply draws no cast FX,
## exactly as it shows no statuses. Read by the presenter, ignored by the simulation.
var fx_events: Array = []

## Presentation-only record of the damage dealt this tick — one entry per hp loss (an
## auto-attack, an ability hit, a venom tick), each `{position, amount}`, for the renderer to
## pop a floating damage number over the struck unit. Same lifecycle as `fx_events`: cleared
## at the top of every `step` and never serialized, so it stays a LOCAL/HOST render hint.
var hit_events: Array = []

## Presentation-only record of the auto-attacks that landed this tick — one entry per strike,
## each `{origin, target, ranged}`, so the renderer flies a projectile from a ranged attacker
## or flashes a close-in impact for a melee one. Same lifecycle as `fx_events`.
var attack_events: Array = []


func add_entity(entity: SimEntity) -> void:
	entities[entity.id] = entity


func get_entity(id: int) -> SimEntity:
	return entities.get(id, null)


func is_match_over() -> bool:
	return winner != -1