Implement prototype: venue-driven simulation core, scenarios, tests, and playable entrance scene
CI / headless-tests (push) Canceled after 49s
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
This commit is contained in:
1 parent
e23f284ad4
commit
439e0a4281
45 files changed
+4368
-7
No files matched your search
@@ -0,0 +1,67 @@
|
||||
extends RefCounted
|
||||
## Headless tests for venue scenario data (Plan: Venues and Scenarios).
|
||||
|
||||
const Rules := preload("res://src/core/rules.gd")
|
||||
const VenueScenario := preload("res://src/core/venue_scenario.gd")
|
||||
const ScenarioFactory := preload("res://src/content/scenario_factory.gd")
|
||||
const ShiftCoordinator := preload("res://src/core/shift_coordinator.gd")
|
||||
|
||||
|
||||
func test_hollywood_building_loads() -> bool:
|
||||
var scenario: VenueScenario = ScenarioFactory.hollywood_building()
|
||||
var a := TestUtils.check_eq(scenario.id, "hollywood_building", "scenario id")
|
||||
var b := TestUtils.check(scenario.npc_profiles.size() > 0, "has profiles")
|
||||
var c := TestUtils.check(scenario.access_policy.requires(Rules.AccessKind.WRISTBAND), "requires wristband")
|
||||
return a and b and c
|
||||
|
||||
func test_joke_shop_rules() -> bool:
|
||||
var scenario: VenueScenario = ScenarioFactory.joke_shop()
|
||||
var a := TestUtils.check_eq(scenario.access_policy.minimum_age, 21, "21+ club")
|
||||
var b := TestUtils.check(scenario.access_policy.require_id, "ID required")
|
||||
var c := TestUtils.check(scenario.access_policy.wand_screening_required, "wand screening required")
|
||||
var d := TestUtils.check(scenario.equipment.has("wand"), "wand in equipment")
|
||||
return a and b and c and d
|
||||
|
||||
func test_tv_studio_has_all_npc_types() -> bool:
|
||||
var scenario: VenueScenario = ScenarioFactory.tv_studio()
|
||||
var all_types := [Rules.NpcType.TOURIST, Rules.NpcType.PERFORMER, Rules.NpcType.INFLUENCER,
|
||||
Rules.NpcType.CONFUSED_VISITOR, Rules.NpcType.INTOXICATED, Rules.NpcType.TRESPASSER,
|
||||
Rules.NpcType.MENTAL_CRISIS, Rules.NpcType.VIOLENT_THREAT,
|
||||
Rules.NpcType.AUTHORIZED_GUEST, Rules.NpcType.AUTHORIZED_STAFF, Rules.NpcType.DELIVERY]
|
||||
var profile_types: Array = []
|
||||
for p in scenario.npc_profiles:
|
||||
profile_types.append(p.npc_type)
|
||||
for npc_type in all_types:
|
||||
if not profile_types.has(npc_type):
|
||||
return TestUtils.fail("TV studio missing npc type %s" % Rules.NPC_TYPE_NAMES[npc_type])
|
||||
return true
|
||||
|
||||
var _spawn_count := 0
|
||||
|
||||
func _on_spawn(_profile: NpcProfile, _intent: String, _id: String) -> void:
|
||||
_spawn_count += 1
|
||||
|
||||
func test_shift_coordinator_runs_a_shift() -> bool:
|
||||
var scenario: VenueScenario = ScenarioFactory.hollywood_building()
|
||||
var coordinator := ShiftCoordinator.new()
|
||||
coordinator.setup(scenario, 60.0, 1234)
|
||||
_spawn_count = 0
|
||||
coordinator.npc_spawn_requested.connect(_on_spawn)
|
||||
coordinator.start()
|
||||
for i in 60:
|
||||
coordinator.tick(1.0)
|
||||
if not coordinator.running:
|
||||
break
|
||||
var a := TestUtils.check(coordinator.elapsed_s > 0.0, "time advanced")
|
||||
var b := TestUtils.check(_spawn_count > 0, "NPCs spawned during shift")
|
||||
var review := coordinator.build_review()
|
||||
var c := TestUtils.check_dict_has(review, "reputation", "review has reputation")
|
||||
return a and b and c
|
||||
|
||||
func test_emergency_event_requires_emergency() -> bool:
|
||||
var scenario: VenueScenario = ScenarioFactory.hollywood_building()
|
||||
var found := false
|
||||
for event in scenario.event_pool:
|
||||
if event.get("requires_emergency", false):
|
||||
found = true
|
||||
return TestUtils.check(found, "scenario contains a scripted emergency event")
|
||||
Reference in new issue
Block a user