Session shell - Startup venue menu (src/game/ui/start_menu.gd): keyboard + mouse, replaces the live-shift boot and V as the player-facing venue path (V stays a debug bind). - Pause overlay on Esc (src/game/ui/pause_overlay.gd): resume, restart shift, settings, quit to menu. - Settings panel (src/game/ui/settings_panel.gd): mouse look sensitivity and HUD font scale, persisted via Save into user://settings.json and loaded on boot. - Shift review "Run another shift" now returns to the venue menu. - New smoke: src/test/smoke_session_shell.gd (menu -> shift -> pause -> settings -> menu), passes headless and windowed. World and presentation - Skyline backdrop restored with a transparent asset and an alpha-scissor unshaded material; fixes the opaque black slab from the earlier attempt and the unimported texture path. - Steps and landing are a StaticBody3D with per-tread colliders, so the guard and NPCs walk up instead of clipping through. - Marquee Label3D scaled up (72 -> 160) so STEP LINE reads from the sidewalk. - Focus torus and name tag enlarged for 2-3 m readability. - Routine traffic despawns after an idle lifetime (NpcAvatar.ephemeral), so the 16-NPC cap no longer fills with standers; authored events stay for the shift. Docs and tests - PLAN.md test/CI section corrected to the custom headless runner and Gitea Actions. - README controls table, smoke checklist, test count, and status lists refreshed. - TODO/DONE/MEMORY updated; completed sections moved to DONE.md. - Headless suite 77 -> 88 passing (settings round-trip, step colliders, skyline alpha, session-shell UI behavior, traffic lifetime).
21 KiB
Step Line
Step Line is a workplace security simulation about observation, communication, access verification, and proportionate escalation. The player works security at public-facing venues around Hollywood Boulevard, managing stairs, entrances, crowds, guests, staff, and occasional serious threats.
The central design goal is simple:
The player wins by choosing the lowest level of escalation that keeps everyone safe.
Screenshots
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Screenshots are generated by src/test/capture_screenshots.gd from the current build — day and late-night shifts.
⬇️ Downloads
| Platform | Package |
|---|---|
| Windows — installer | step-line-setup-<ver>.exe · contains all game data, shortcuts + uninstaller |
| Windows — portable | step-line-windows-<ver>.exe · 64-bit, no install needed |
| Linux — AppImage | step-line-<ver>-x86_64.AppImage · single file, chmod +x and run |
| Linux — portable | step-line-linux-<ver>.x86_64 · 64-bit, chmod +x and run |
| macOS | step-line-macos-<ver>.zip · unsigned build, quarantine note below |
All releases: https://git.allucanget.biz/zwitschi/security-game/releases
Latest: v0.2.1 (2026-10-31) — built and published by Gitea Actions from the
v0.2.1tag, including the Windows installer and Linux AppImage. Releases are built automatically when avX.Y.Ztag is pushed (seedocs/RELEASING.md); manual builds use./tools/build_releases.sh. Installer/AppImage packaging runs in the same pipeline (NSIS + appimagetool) and uploads with the portable binaries.Note: on this host, downloading release files currently requires sign-in; the page and tag URLs are public.
macOS builds are unsigned: right-click → Open, or clear the quarantine with
xattr -dr com.apple.quarantine step-line-macos.zip. Build instructions and the release pipeline live indocs/RELEASING.md.
If you are here to develop or test locally instead of downloading, jump to Run and Test below.
The project is under active development. The design and architecture are documented, and a playable prototype vertical slice exists (Godot 4.3 + GDScript): a procedural Hollywood Boulevard entrance, a first-person guard, simulated NPCs with intents and reactions, the six-level escalation model, access inspection and admission decisions, radio calls with credibility checks, reputation, crowd mood, and an end-of-shift review.
Game Overview
A typical shift lasts 10–15 minutes. The player:
- Watches the entrance, steps, queue, and surrounding sidewalk.
- Determines why each person is approaching.
- Uses simple gestures or polite directions first.
- Verifies authorized access using recognition, wristbands, credentials, tickets, or guest lists.
- Escalates only when a person refuses directions, attempts unauthorized entry, or presents a genuine threat.
- Records the incident through body-camera and radio systems.
- Finishes the shift with a performance review based on safety, judgment, and professionalism.
The game rewards calm resolutions rather than aggressive behavior. Emergency assistance and armed responders are rare last-resort systems with meaningful consequences.
Planned Venues
Hollywood Boulevard Building
The original scenario places the guard at the top of the steps outside a fictional building. Tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats may approach the entrance.
Authorized people must either be recognized by the guard or present a valid wristband. Wristbands can have different colors, patterns, dates, or event markings. They may be valid, expired, counterfeit, or missing.
The Joke Shop
The Joke Shop is a comedy-club scenario. The door person checks IDs, tickets, reservations, and guest-list status, then uses a handheld security wand according to venue policy. The player must interpret wand alerts rather than treating every alert as proof of a weapon; keys, belts, phones, and other harmless objects can trigger false alarms.
Hollywood Boulevard Late Night TV Studio
This scenario combines the previously defined NPC types with a busy television-studio entrance. The player manages audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats.
The studio uses wristbands, credentials, tickets, guest-list confirmation, and personal recognition to authorize entry. Crowd control, filming boundaries, following authorized guests through the door, and counterfeit credentials are key events.
Escalation Model
The common escalation model has six levels:
- Observation — Decide whether intervention is necessary.
- Simple deterrence and polite direction — Raise an open hand, make eye contact, point toward the sidewalk or check-in area, shake the head, or give a short instruction.
- Formal warning — Clearly explain the rule and request compliance.
- Blocking and physical positioning — Secure the entrance, maintain distance, preserve an escape route, and deny access without starting a fight.
- Radio for security assistance — Request a supervisor, second guard, building management, or other appropriate support.
- Emergency response — Hold the emergency-radio button and confirm only when there is an immediate threat, such as a weapon, assault, forced entry, or serious threat to occupants.
An off-duty law-enforcement officer or armed emergency responder may arrive during a valid emergency. This character is not intended to be a routine stronger attack. Their role is crisis control, evacuation, restraint, arrest, or other appropriate intervention, with force governed by the situation and meaningful consequences for unjustified calls.
Core Systems
- NPC behavior: NPCs have different motivations, temperaments, compliance levels, and reactions to the player’s approach.
- Access verification: Recognition, wristbands, IDs, tickets, credentials, and guest lists determine who may enter.
- Nonverbal deterrence: Small actions such as raising a hand can resolve low-risk situations without dialogue or force.
- Dialogue: Polite directions and warnings affect outcomes; simple gestures can resolve low-risk situations without dialogue.
- Escalation: The player chooses the lowest effective response.
- Radio assistance: Calls require useful information and may take time to arrive.
- Evidence: Body-camera records support shift review and accountability.
- Crowd reaction: Aggressive behavior, visible weapons, and emergency response can create panic or attract a crowd.
- Reputation: Peaceful resolutions, accurate reports, low property damage, and justified calls improve performance; unnecessary confrontations and false reports reduce it.
- Shift review: The player receives feedback on access decisions, escalation choices, public complaints, injuries, and security outcomes.
Architecture Overview
The planned solution uses a venue-driven simulation architecture. Venue configuration supplies rules, access types, NPC pools, equipment, events, and escalation policies. Shared simulation systems provide movement, perception, interactions, dialogue, access verification, escalation, radio calls, crowds, reputation, evidence, and shift review.
Venue Scenario / Rules
|
v
Shift Coordinator -----> Event Scheduler
| |
v v
NPC Simulation <---------- Interaction System
| |
v v
Access Verification ----> Escalation / Response
| |
+-------------> Reputation / Evidence
|
v
Shift Review
The architecture maps onto Godot 4 nodes, scenes, and custom resources as described in Tech Stack. See the full arc42-style outline in docs/architecture.md and the decisions in docs/adr/.
Tech Stack
- Engine: Godot Engine 4.x
- Language: GDScript
- Architecture: Venue-driven simulation using nodes, scenes, and custom
Resource-based scenario data - Navigation:
NavigationRegion3DandNavigationAgent3D - NPC behavior: Custom lightweight finite state machines driven by
NpcProfileresources - UI and audio: Godot
Controlnodes, themes, audio buses, andAudioStreamPlayernodes - Art assets: authored PNGs and the in-game generated set in
assets/textures/ai/game_ready/; structural geometry stays procedural (WorldBuilder). The legacytools/generate_textures.py --aibatch remains available. - Asset tooling:
tools/asset_pipeline.pygenerates role-aware assets through OpenRouter and provides crop, resize, seamless-tile, and image-audit commands, including gameplay screenshot checks. - Testing: GUT (Godot Unit Test) in headless mode
- Source control: git on a Gitea host with Gitea Actions (
.gitea/workflows/build.yml) for headless tests and desktop release builds - Targets: Windows, Linux, and macOS desktop first; web later
Image Asset Tools
Install the Pillow dependency used by the existing texture generator and the asset tools:
python3 -m pip install -r requirements-tools.txt
Generate a role-sized image (generation requires OPENROUTER_API_KEY):
python3 tools/asset_pipeline.py generate --prompt "weathered red brick" --role tile --output assets/textures/brick_extra.png
Generated images are resized to the selected role profile. Non-square requests use
the validated openai/gpt-5-image-mini source ratio and crop to the final role dimensions.
Transparent glyphs can be recolored while preserving their alpha mask with
--foreground '#ffffff'.
Crop uses the image center by default; --x and --y select an explicit crop origin. Resize defaults to aspect-preserving contain; use --fit cover to crop or --fit stretch to distort to the exact dimensions.
python3 tools/asset_pipeline.py crop assets/textures/source.png assets/textures/crop.png --width 256 --height 128
python3 tools/asset_pipeline.py resize assets/textures/source.png assets/images/backgrounds/scene.png --width 1920 --height 1080 --fit cover
python3 tools/asset_pipeline.py seamless assets/textures/rough_tile.png assets/textures/tile.png
Audit accepts image files or directories. --role auto infers common roles from paths and filenames; explicit roles include tile, texture, icon, card, banner, backdrop, background, overlay, app_icon, and screenshot.
python3 tools/asset_pipeline.py audit assets/textures
python3 tools/asset_pipeline.py audit assets/images/backgrounds --role background --json
python3 -m unittest discover -s tools -p 'test_*.py'
The audit classifies measurable fit issues as good or bad based on role-specific dimensions, aspect ratio, alpha requirements, and tile-edge continuity. It lists perspective/projection as a visual review item because image semantics cannot be judged reliably by these deterministic checks.
Setup
- Download the Godot 4.3 editor (official build) and put
godoton your PATH. - Open or run the project from this directory.
Run and Test
# Open in the editor
godot --editor --path .
# Run the game
godot --path .
# Headless smoke boot (120 frames then exit)
godot --headless --path . --quit-after 120
# Run all unit tests headlessly (exit code 0 = pass)
godot --headless --path . --script res://src/test/test_runner.gd
# Save a screenshot to user:// (windowed)
godot --path . --script res://src/test/take_screenshot.gd
# Windowed control smoke: focus ring + action wheel, saves PNGs, exits 1 on failure
godot --path . --script res://src/test/smoke_focus_radial.gd
# Session-shell smoke: menu → shift → pause → settings → menu (headless or windowed)
godot --headless --path . --script res://src/test/smoke_session_shell.gd
The unit test runner is the project's own lightweight harness (no editor plugin required) so CI can run it without the editor.
Controls
| Input | Action |
|---|---|
| W/A/S/D + mouse | Move and look |
| Space / left click | Action wheel for the focused person |
| A / D or ←/→ | Step through the action wheel (while it is open) |
| Space / left click | Confirm the highlighted action (while the wheel is open) |
| Esc / right click | Close the top panel; Esc with nothing open pauses the shift (Esc again resumes) |
| ← / → or ↑ / ↓ | Navigate the venue menu and the pause / settings panels |
| Enter | Start the highlighted venue from the menu, or confirm in a panel |
| 1 / 2 / 3 | Quick gestures without the wheel: raise hand, point, head shake (Level 1) |
| Q | Polite direction (Level 1) |
| 4 | Formal warning (Level 2) |
| 5 | Blocking and positioning (Level 3) |
| 6 | Security assistance radio (Level 4) |
| R | Emergency radio, hold on-screen button ~1.6s (Level 5) |
| E | Inspect access artifacts / close inspection |
| C | Handheld wand screening (wand venues only) |
| A / D | Allow / deny entry during inspection or wand check |
| V | Cycle venue (debug shortcut; restart via V restarts the current shift) |
| Tab | Cycle target among nearby NPCs (aim-free alternative) |
| G | Toggle flashlight (widens NPC perception at night) |
| L | Lock / unlock the restricted door (thwarts forced entry) |
| F | Toggle debug overlay |
Architecture
The full arc42-style architecture documentation lives in docs/architecture.md. It covers goals, constraints, context, solution strategy, building blocks, runtime views, deployment, cross-cutting concepts, quality requirements, risks, a glossary, the CI/CD build pipeline, semantic versioning, and release management.
Project Documentation
PLAN.md— Game design plan and scenario details.AGENTS.md— Development and collaboration workflow.TODO.md— Active checkbox task list.DONE.md— Completed task sections.MEMORY.md— Persistent session notes.docs/architecture.md— arc42-style architecture documentation.docs/adr/— Architecture Decision Records.
Development Status
Implemented so far:
- Godot 4.3 project scaffold, input map, procedural world builder
- Venue-driven simulation core:
ShiftCoordinator,VenueScenario,EventScheduler,NPCController+ FSM,AccessVerifier,EscalationManager,RadioSystem,IncidentRecorder,ReputationEvaluator,CrowdSystem - Three authored scenarios (Hollywood Boulevard building, The Joke Shop, Late Night TV Studio) with access policies, NPC archetypes, and event pools
- Headless unit tests: 88 passing (access rules and venue-correct access loadout, escalation, radio cooldown/battery, NPC reaction determinism, door lock, flashlight perception, persistence round-trip, settings round-trip, navmesh, step colliders, skyline alpha, scenario data, full-shift simulation, wand screening, responder dispatch, localization strings, focus cone, action wheel, session shell)
- Simulation extras: protester archetype, CALL_SOMEONE reaction, door lock/secure mechanic (visual indicator), flashlight with night perception bonus, LATE shift phase reaching the violent-threat event
- First-person prototype with interaction HUD, access inspection, wand screening, radio report form (incl. emergency hold-to-confirm), dispatched responder avatars, aim-free targeting, venue cycling between all three scenarios, color-coded escalation feedback, procedural audio cues, navigation-mesh NPC paths, JSON-backed localized strings, persisted shift history, debug overlay, and shift review
- Control pass: focus cone on NPC heads with a billboarded gold ring and name, action wheel (LMB/Space) with de-escalation-first slices, mouse-look freeze while a panel is open, acceleration-based walking, and named input actions (
action_menu,confirm,cancel,inspect,wand) - Session shell: venue start menu (keyboard + mouse), Esc pause overlay (resume / restart / settings / quit to menu), settings panel with mouse-look sensitivity and HUD font scale persisted to
user://settings.json, and "Run another shift" returning to the venue menu - World presentation: skyline backdrop rendered with an alpha material, walkable step and landing colliders, larger marquee text, and larger focus ring / name tag
- Routine traffic despawns after a while at its waypoint so the crowd cap no longer fills with idle standers
- Visual polish pass (v0.2.0): phase-based lighting (sun/sky/ambient per shift phase), street lamps with night-mode bulbs and omni lights, glowing marquee signage, crosswalk, planters and low-poly street trees, NPC height/brightness variety, denser routine traffic — day and late-night screenshot sets
- Assets pass: authored textures in
assets/textures/(brick facade, concrete, asphalt, awning, skyline, vignette, HUD icons, access-card art) generated bytools/generate_textures.py, soft sun shadows, humanoid NPC rigs with archetype props + procedural walk bob and attention head-turn, inspection artifact cards, escalation vignette, mode icons, and a body-camera overlay (REC + shift clock)
Not yet implemented: body-camera replay timeline, eye-contact and request-reason verbs, crowd rubbernecking, emergency aftermath, editor-based GUT integration, and crowd performance profiling/LOD (see TODO.md).
Smoke Test Checklist
godot --path .starts the game on the venue menu without script errors.- Choosing a venue (click or ↑/↓ + Enter) starts that venue's shift and hides the menu.
- The guard moves and looks around; the building, steps, and sidewalk are visible.
- The guard's camera sits at eye height and the guard stands on the landing, not inside the building.
- Walking into the steps carries the guard up onto the landing (steps have colliders).
- The skyline backdrop shows silhouettes against the sky, not an opaque black slab.
- The
STEP LINEmarquee is readable from the sidewalk. - NPCs spawn and approach the entrance during the first minutes.
- Looking at an NPC inside the focus cone shows a gold head ring, the person's name, and the HUD target line.
Spaceor left click opens the action wheel;A/Dhighlight a slice,Spaceconfirms it,Esc/right click cancels without a log entry.E/Copen the inspection/wand panels from the wheel and freeze movement until they close; walking never fires the wand.- Pressing
Qproduces a reaction log entry and reputation feedback. Eopens access inspection showing venue-correct artifacts and policy result;A/Drecord a decision.6opens the assistance form; submitting shows dispatch feedback.Ropens the emergency form; the button must be held ~1.6s or the call cancels.Gtoggles the flashlight (indicator appears in the HUD);Ltoggles the door lock (indicator turns red when locked).Ftoggles the debug overlay with NPC states and shift stats.Escwith nothing open pauses the shift; resume / restart / settings / quit-to-menu all work, and settings changes persist across a restart.- NPCs route around the building using the navigation mesh (no stuck-at-wall behavior during a smoke run).
- When the shift timer reaches 0, the shift review screen shows grade, incident summary, and persisted shift history; "Run another shift" returns to the venue menu.
Development Workflow
Follow AGENTS.md: inspect the repository first, record work as checkbox tasks in TODO.md, move completed sections to DONE.md, update MEMORY.md with durable context, and keep this README synchronized with setup and architecture changes.





