Files
Jeff Luke c1b2195834 Expand Glitch operations hub, cabinet authoring, deployment, and RFID support
Operator hub
- Introduce Escape Gallery branding and Glitch: the Dark Machine room views
- Add cabinet illustrations, Pac-Man marquee/gameplay artwork, and waiting states
- Add device feedback panels with RFID readings, input/output states, and stale status
- Add logged operator hardware interventions with request deduplication

Room and cabinet authoring
- Add a visual custom-PCB connection editor with per-cabinet device inventory
- Support device IDs, bindings, wiring notes, input polarity, and validation
- Add physical-room label/dimension toggles and editable doorway annotations
- Preserve doorway changes through undo, save, and revert
- Expand cabinet profiles, room layout, and Glitch scenario resources

Scenarios and gameplay
- Add per-assignment game configuration and runtime feature validation
- Add timed test wins and Frogger individual-home objectives
- Add the three-cabinet timed/score/Frogger test scenario
- Add Cabinet 1 Pac-Man RFID credits, credit sound, and CREDIT 0/1 display
- Require physical Start after an accepted scan and prevent duplicate credits

Pi hardware and deployment
- Add GPIO feedback sampling and a separate multiplexed RFID helper
- Validate reader pin ownership and input/output conflicts
- Add SSH cabinet startup and Pi desktop-session service support
- Add master packaging, site setup, SSH enrollment, and staged cabinet releases
- Verify deployment manifests and support explicit activation/status/log commands

Documentation and verification
- Consolidate the root README around the current architecture and setup workflow
- Add the complete master/Pi/RFID export and deployment walkthrough
- Document network isolation, credentials, card identification, and rollback
- Add PCB, room-editor, feedback, credit, deployment, and controller tests
- Isolate protocol tests from designer-edited cabinet configurations

Known limitations
- RFID helper compilation and physical Pi commissioning remain unverified
- Fleet provisioning does not yet configure RFID-only installations completely
- Broader Pac-Man tests retain a ghost-capture assertion failure
- Staged exports must be rebuilt and checked before deploying runtime 2.3
2026-10-17 14:53:54 -07:00

188 lines
3.1 KiB
GDScript

@tool
extends EditorPlugin
const WORKSPACE_SCENE := preload(
"res://editor/workspace/EscapeRoomWorkspace.tscn"
)
const DATABASE_SETTING := (
"arcade_escape/project_database"
)
const ROOM_SETTING := (
"arcade_escape/default_room"
)
var pcb_inspector: EditorInspectorPlugin
var workspace: EscapeRoomWorkspace
func _enter_tree() -> void:
pcb_inspector = preload("res://addons/escape_room/pcb_inspector.gd").new()
add_inspector_plugin(pcb_inspector)
_ensure_project_settings()
_create_workspace()
func _exit_tree() -> void:
remove_inspector_plugin(pcb_inspector)
pcb_inspector = null
_destroy_workspace()
func _has_main_screen() -> bool:
return true
func _make_visible(visible: bool) -> void:
if workspace != null:
workspace.visible = visible
func _get_plugin_name() -> String:
return "Escape Room"
func _get_plugin_icon() -> Texture2D:
return EditorInterface.get_editor_theme().get_icon(
"Node2D",
"EditorIcons"
)
func _create_workspace() -> void:
if workspace != null:
return
var database := _load_project_database()
var room := _load_default_room()
if database == null:
return
if room == null:
return
workspace = WORKSPACE_SCENE.instantiate()
workspace.set_undo_redo_manager(
get_undo_redo()
)
EditorInterface.get_editor_main_screen().add_child(
workspace
)
workspace.set_anchors_and_offsets_preset(
Control.PRESET_FULL_RECT
)
if not workspace.configure(
database,
room
):
push_error(
"Arcade Escape editor workspace failed to configure."
)
_make_visible(false)
func _destroy_workspace() -> void:
if workspace == null:
return
if is_instance_valid(workspace):
workspace.queue_free()
workspace = null
func _ensure_project_settings() -> void:
if not ProjectSettings.has_setting(
DATABASE_SETTING
):
ProjectSettings.set_setting(
DATABASE_SETTING,
"res://data/project_database.tres"
)
ProjectSettings.set_initial_value(
DATABASE_SETTING,
"res://data/project_database.tres"
)
if not ProjectSettings.has_setting(
ROOM_SETTING
):
ProjectSettings.set_setting(
ROOM_SETTING,
"res://data/rooms/arcade_room.tres"
)
ProjectSettings.set_initial_value(
ROOM_SETTING,
"res://data/rooms/arcade_room.tres"
)
ProjectSettings.save()
func _load_project_database() -> ProjectDatabase:
var path := String(
ProjectSettings.get_setting(
DATABASE_SETTING,
""
)
)
if path.is_empty():
push_error(
"Arcade Escape project database path is empty."
)
return null
var resource := ResourceLoader.load(
path
)
if not resource is ProjectDatabase:
push_error(
"Arcade Escape expected ProjectDatabase at '%s'."
% path
)
return null
return resource as ProjectDatabase
func _load_default_room() -> RoomDefinition:
var path := String(
ProjectSettings.get_setting(
ROOM_SETTING,
""
)
)
if path.is_empty():
push_error(
"Arcade Escape default room path is empty."
)
return null
var resource := ResourceLoader.load(
path
)
if not resource is RoomDefinition:
push_error(
"Arcade Escape expected RoomDefinition at '%s'."
% path
)
return null
return resource as RoomDefinition