CI / headless-tests (push) Canceled after 49s
- Godot 4.3 project scaffold with first-person guard, procedural world, interaction HUD, access inspection, radio forms, debug overlay, shift review - Simulation core: ShiftCoordinator, VenueScenario, EventScheduler, NPCController/FSM, AccessVerifier, EscalationManager, RadioSystem, IncidentRecorder, ReputationEvaluator, CrowdSystem, EventBus - Three authored scenarios (Hollywood Blvd building, The Joke Shop, TV studio) - Custom headless test runner (25 tests) replacing editor-dependent GUT, plus GitHub Actions CI - Documentation workflow live: README, PLAN (tech stack), TODO/DONE, MEMORY
50 lines
1.7 KiB
GDScript
50 lines
1.7 KiB
GDScript
class_name VenueScenario
|
|
extends Resource
|
|
|
|
const Rules := preload("res://src/core/rules.gd")
|
|
const AccessPolicy := preload("res://src/core/access_policy.gd")
|
|
const NpcProfile := preload("res://src/core/npc_profile.gd")
|
|
## Data-driven venue definition (ADR-0001). Provides locations, rules,
|
|
## NPC pools, event pools, equipment, and shift phases.
|
|
|
|
@export var id: String = ""
|
|
@export var display_name: String = ""
|
|
@export_multiline var description: String = ""
|
|
|
|
@export var access_policy: AccessPolicy = AccessPolicy.new()
|
|
|
|
## Equipment available at this venue.
|
|
@export var equipment: Array[String] = [] # e.g. "wristband_policy", "id_check", "wand", "flashlight"
|
|
|
|
## Named spots: "guard_post", "entrance", "steps", "sidewalk", "queue_area".
|
|
@export var locations: Dictionary = {}
|
|
|
|
## NPC archetype definitions that appear in this scenario.
|
|
@export var npc_profiles: Array[NpcProfile] = []
|
|
|
|
## Event pool. Each event: { id, phase: Rules.Phase, kind: "routine"|"scripted",
|
|
## npc_type: int, intent: String, weight: float, probability: float,
|
|
## time_range_s: Vector2, requires_emergency: bool }
|
|
@export var event_pool: Array[Dictionary] = []
|
|
|
|
## Shift setup: phases map Rules.Phase -> { start_s, end_s, spawn_rate }.
|
|
@export var shift_phases: Dictionary = {}
|
|
|
|
## Default duration of one shift in seconds (PLAN.md: 10-15 minutes).
|
|
@export var shift_duration_s: float = 900.0
|
|
|
|
@export var policy_summary: String = ""
|
|
|
|
func profile_for(npc_type: int) -> NpcProfile:
|
|
for p in npc_profiles:
|
|
if p.npc_type == npc_type:
|
|
return p
|
|
return null
|
|
|
|
func events_in_phase(phase: int) -> Array[Dictionary]:
|
|
var result: Array[Dictionary] = []
|
|
for event in event_pool:
|
|
if event.get("phase", -1) == phase:
|
|
result.append(event)
|
|
return result
|