stage function

Staged stage(
  1. Level level,
  2. CollisionWorld world, {
  3. required InputState input,
})

Turns a level document into a run, given a world it has already been added to.

Promoted from flutter3d_sim_mcp's own staging.dart (ai-00), which could not depend on apps/flutter3d_demo_dungeon for the original — tool/structure.dart's no package depends on an application rule sees to that — and so carried a trimmed copy instead. Living here instead of there is the fix that copy's own doc comment already asked for: this is a package flutter3d_sim_mcp already depends on for the genre itself, so the composition can be named once rather than copied.

Deliberately smaller than apps/flutter3d_demo_dungeon's own stage(): no mechanisms, no breaches, no automap, no onActorSpawned/onFixture hooks — none of which an agent's own tools read back, and each one is a further place this copy could drift from the shipped game if it carried something nothing here uses. Not a replacement for that function; a second, smaller one for a caller with smaller needs.

Implementation

Staged stage(Level level, CollisionWorld world, {required InputState input}) {
  final entities = EcsWorld();
  final dice = GameRandom(1);
  final projectiles = ProjectileSystem(world: world, entities: entities);
  final actors = ActorSystem(world: world, entities: entities, random: dice);

  final navIssues = <LevelIssue>[];
  final navigation = Navigation.bake(level, cellSize: 0.25, issues: navIssues);
  actors.navigation = navigation;

  final hitscan = Hitscan(world: world, random: dice);
  final shot = WeaponShot(
    world: world,
    hitscan: hitscan,
    projectiles: projectiles,
  );
  final mechanisms = MechanismWorld(world);

  final registry = sampleRegistry();
  (registry[ShooterEntities.monster] as MonsterKind?)?.bestiary = Bestiary(
    actors: actors,
    shot: shot,
    catalog: Monsters.byName,
  );

  level.spawnInto(
    SpawnContext(world: world, actors: actors, mechanisms: mechanisms),
    registry: registry,
  );

  final spawn = level.playerStart;
  final start = spawn?.position ?? Vector3.zero();
  final player = Player(
    body: CharacterController(
      world: world,
      position: start + Vector3(0.0, 0.9, 0.0),
    ),
    inventory: agentStartingInventory(),
  )..yaw = spawn?.yaw ?? 0.0;

  return Staged(
    actors: actors,
    player: player,
    sim: GameSimulation(
      random: dice,
      player: player,
      collision: world,
      input: input,
      actors: actors,
      mechanisms: mechanisms,
      projectiles: projectiles,
      shot: shot,
      levelNext: level.next,
    ),
  );
}