Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124package sim
// Actors need stable handles once echoes, enemies, attacks, and corpses all start// referencing each other. Index plus generation lets us use cache-friendly arrays// later without letting stale handles silently point at recycled actors.Actor_Id :: struct { index: u32, generation: u32,}
Actor_Kind :: enum u8 { None, Player, Echo,}
Echo_Replay_Mode :: enum u8 { None, Following, Timeline_Ended,}
Echo_Replay_State :: struct { source_run_id: u32, replay_tick: u64, mode: Echo_Replay_Mode,}
Actor_State :: struct { id: Actor_Id, kind: Actor_Kind, position: Vec2_Fixed, echo: Echo_Replay_State,}
Arena_State :: struct { min: Vec2_Fixed, max: Vec2_Fixed,}
Initial_State_Descriptor :: struct { player_position: Vec2_Fixed,}
DEFAULT_INITIAL_STATE :: Initial_State_Descriptor { player_position = {Fixed(0), Fixed(0)},}
DEFAULT_ARENA :: Arena_State { min = {Fixed(-18 * (1 << FIXED_SHIFT)), Fixed(-10 * (1 << FIXED_SHIFT))}, max = {Fixed(18 * (1 << FIXED_SHIFT)), Fixed(10 * (1 << FIXED_SHIFT))},}
// World_State is the gameplay data owned by a single deterministic run.// It should stay free of renderer, asset, and platform concepts.World_State :: struct { seed: u64, actor_count: u32, arena: Arena_State, player_id: Actor_Id, actors: [MAX_WORLD_ACTORS]Actor_State,}
world_spawn_player :: proc(world: ^World_State, position: Vec2_Fixed) -> (Actor_Id, bool) { id, actor := world_spawn_actor(world, .Player, position) if actor == nil { return {}, false } world.player_id = id return id, true}
world_spawn_echo :: proc( world: ^World_State, source_run_id: u32, position: Vec2_Fixed,) -> (Actor_Id, bool) { id, actor := world_spawn_actor(world, .Echo, position) if actor == nil { return {}, false } actor.echo = Echo_Replay_State{ source_run_id = source_run_id, mode = .Following, } return id, true}
world_spawn_actor :: proc( world: ^World_State, kind: Actor_Kind, position: Vec2_Fixed,) -> (Actor_Id, ^Actor_State) { if world.actor_count >= MAX_WORLD_ACTORS { return {}, nil }
index := world.actor_count id := Actor_Id{index = index, generation = 1} world.actors[index] = Actor_State{ id = id, kind = kind, position = position, } world.actor_count += 1 return id, &world.actors[index]}
world_actor_by_id :: proc(world: ^World_State, id: Actor_Id) -> ^Actor_State { if id.index >= world.actor_count { return nil }
actor := &world.actors[id.index] if actor.id.generation != id.generation { return nil } return actor}
world_player :: proc(world: ^World_State) -> ^Actor_State { return world_actor_by_id(world, world.player_id)}