Implement prototype: venue-driven simulation core, scenarios, tests, and playable entrance scene
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:
zwitschi committed 2026-10-31 11:37:54 +01:00
1 parent e23f284ad4
commit 439e0a4281
45 files changed
+4368 -7

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
class_name CrowdSystem
extends RefCounted
## Models crowd mood and public reaction (PLAN.md: Public Crowd Reaction).
const EventBus := preload("res://src/core/event_bus.gd")
## mood: 0.0 (calm) .. 1.0 (panic). attention: how many people are watching.
signal changed(payload: Dictionary)
var event_bus: EventBus = null
var mood: float = 0.05
var attention: float = 0.0
var crowd_panic := false
func set_event_bus(bus: EventBus) -> void:
event_bus = bus
## Apply a crowd event. type: "calm_professionalism", "aggressive_behavior",
## "visible_weapon", "emergency_responder", "de_escalation".
func apply_event(event_type: String) -> void:
match event_type:
"calm_professionalism":
attention = maxf(0.0, attention - 0.05)
mood = maxf(0.0, mood - 0.02)
"de_escalation":
mood = maxf(0.0, mood - 0.06)
attention = clampf(attention + 0.05, 0.0, 1.0)
"aggressive_behavior":
attention = clampf(attention + 0.20, 0.0, 1.0)
mood = clampf(mood + 0.12, 0.0, 1.0)
"visible_weapon":
attention = 1.0
mood = clampf(mood + 0.35, 0.0, 1.0)
"emergency_responder":
attention = 1.0
mood = clampf(mood + 0.25, 0.0, 1.0)
_:
pass
crowd_panic = mood >= 0.75
if event_bus:
event_bus.crowd_changed.emit({
"mood": mood,
"attention": attention,
"panic": crowd_panic,
"event": event_type,
})
func summary() -> Dictionary:
return {
"mood": mood,
"attention": attention,
"panic": crowd_panic,
}