Files
security-game/src/core/rules.gd
T
zwitschi a3768c2ce4
Full build / Import + headless tests (push) Successful in 2m25s
Full build / Full desktop build + optional release (push) Skipped
Remove dialogue tone-of-voice system, add Gitea Actions full build, add venue cycling
- Delete Rules.Tone/TONE_NAMES, NpcProfile.tone_modifiers, tone params on
  NPCController.roll_reaction/apply_player_action; dialogue_lines flattened
  to Array[String]; HUD tone label, T binding, and hud.tone_prefix removed
- Docs updated everywhere (PLAN, README, DONE, MEMORY); PLAN section heading
  'Tone and Design Direction' -> 'Design Direction'
- Add .gitea/workflows/build.yml: checks job (import+tests) on push/PR; full
  build job (export templates, Linux/Windows/macOS exports, artifact upload,
  and tag-based Gitea release publish via GITEA_TOKEN) on tags/dispatch
- Remove old .github/workflows/ci.yml to avoid double runs
- Add venue cycling (V) across all three scenarios with hud.venue_switched
- Refresh README screenshots to match the new HUD
- 53/53 tests pass, boot smoke clean
2026-10-31 13:08:20 +01:00

128 lines
2.7 KiB
GDScript

class_name Rules
## Shared constants and helpers for the simulation rules.
func _init() -> void:
push_error("Rules is a static utility class and must not be instantiated.")
## Escalation levels (0..5). Names must stay in sync with PLAN.md.
enum Level {
OBSERVATION = 0,
SIMPLE_DETERRENCE = 1,
FORMAL_WARNING = 2,
BLOCKING = 3,
RADIO_ASSIST = 4,
EMERGENCY = 5,
}
const LEVEL_NAMES := {
Level.OBSERVATION: "Observation",
Level.SIMPLE_DETERRENCE: "Simple Deterrence",
Level.FORMAL_WARNING: "Formal Warning",
Level.BLOCKING: "Blocking",
Level.RADIO_ASSIST: "Radio Assist",
Level.EMERGENCY: "Emergency",
}
## NPC behavioral archetypes from PLAN.md.
enum NpcType {
TOURIST,
PERFORMER,
INFLUENCER,
CONFUSED_VISITOR,
INTOXICATED,
TRESPASSER,
VIOLENT_THREAT,
MENTAL_CRISIS, # "51/50" style mental-health crisis character
AUTHORIZED_STAFF,
AUTHORIZED_GUEST,
DELIVERY,
RESPONDER,
PROTESTER,
}
const NPC_TYPE_NAMES := {
NpcType.TOURIST: "Tourist",
NpcType.PERFORMER: "Street Performer",
NpcType.INFLUENCER: "Influencer",
NpcType.CONFUSED_VISITOR: "Confused Visitor",
NpcType.INTOXICATED: "Intoxicated Pedestrian",
NpcType.TRESPASSER: "Trespasser",
NpcType.VIOLENT_THREAT: "Violent Threat",
NpcType.MENTAL_CRISIS: "Mental Health Crisis",
NpcType.AUTHORIZED_STAFF: "Authorized Staff",
NpcType.AUTHORIZED_GUEST: "Authorized Guest",
NpcType.DELIVERY: "Delivery",
NpcType.RESPONDER: "Responder",
NpcType.PROTESTER: "Protester",
}
## Access artifact kinds used by AccessVerifier.
enum AccessKind {
NONE = -1,
RECOGNITION = 0,
WRISTBAND = 1,
ID = 2,
TICKET = 3,
CREDENTIAL = 4,
GUEST_LIST = 5,
}
const ACCESS_KIND_NAMES := {
AccessKind.RECOGNITION: "Recognition",
AccessKind.WRISTBAND: "Wristband",
AccessKind.ID: "ID",
AccessKind.TICKET: "Ticket",
AccessKind.CREDENTIAL: "Credential",
AccessKind.GUEST_LIST: "Guest List",
}
## Artifact validity states.
enum ArtifactStatus {
VALID = 0,
EXPIRED = 1,
COUNTERFEIT = 2,
MISMATCHED = 3,
MISSING = 4,
AMBIGUOUS = 5,
}
const ARTIFACT_STATUS_NAMES := {
ArtifactStatus.VALID: "Valid",
ArtifactStatus.EXPIRED: "Expired",
ArtifactStatus.COUNTERFEIT: "Counterfeit",
ArtifactStatus.MISMATCHED: "Mismatched",
ArtifactStatus.MISSING: "Missing",
ArtifactStatus.AMBIGUOUS: "Ambiguous",
}
## NPC reaction outcomes after player actions.
enum Reaction {
COMPLY = 0,
LEAVE = 1,
ARGUE = 2,
IGNORE = 3,
RECORD = 4,
THREATEN = 5,
RETURN_LATER = 6,
FORCE_ENTRY = 7,
CALL_SOMEONE = 8,
}
## Shift phases by time of day.
enum Phase {
EARLY = 0,
MIDDAY = 1,
EVENING = 2,
LATE = 3,
}
const PHASE_NAMES := {
Phase.EARLY: "Early",
Phase.MIDDAY: "Midday",
Phase.EVENING: "Evening",
Phase.LATE: "Late",
}
static func level_name(level: int) -> String:
return LEVEL_NAMES.get(level, "Unknown")