format_version: 1
key: orion.space_rescue
version: 2
name: Space Rescue Beacon
description: The same console activates a rescue beacon and scans for stranded explorers.
characters:
  orion:
    name: Commander Orion
    personality: Calm, curious, and encouraging under pressure.
    prompt: You coordinate a friendly space rescue. Let the child choose who to help and how to explore.
    voice: orion_voice
    initial_presence: rescue_bridge
story_rules:
  - A beacon button activates the beacon immediately. It does not prove that anybody has received the signal or been rescued.
  - Keep each dialogue segment to one short semantic unit, attaching its consequences to that segment's completion.
  - Remember exact player quotes about names and companions. Speak only from accepted player input, durable state, and confirmed heard dialogue.
initial_state:
  facts:
    beacon.active: false
    explorers.rescued: false
  knowledge:
    captain: {}
    orion: {}
  relationships:
    orion:
      captain:
        trust: 0.7
  device:
    map_key: rescue
    map_revision: 1
    presentation:
      beacon: { enabled: false }
allowed_effects:
  - fact_set
  - knowledge_set
  - presentation_set
inputs:
  beacon_requested:
    mode: effects
    effects:
      - { type: fact_set, key: beacon.active, value: true }
      - { type: presentation_set, key: beacon, value: { enabled: true } }
device:
  requires:
    primary_action: button
    push_to_talk: button
    status_indicator: light
    main_audio: speaker
    microphone: microphone
  media:
    narration: main_audio
    capture: microphone
  local_state:
    ready: { type: boolean, default: true }
  events:
    beacon_requested:
      direction: device_to_server
      payload: {}
    beacon_changed:
      direction: server_to_device
      presentation_key: beacon
      payload: { enabled: boolean }
    beacon_sync:
      direction: server_to_device
      payload: { enabled: boolean }
  maps:
    rescue:
      playable: true
      routes:
        - id: activate_beacon
          on: primary_action.pressed
          when:
            - { path: state.ready, op: eq, value: true }
          actions:
            - state.set: { path: ready, value: false }
            - light.set: { target: status_indicator, value: true }
            - sound.play: { asset: rescue_scan, key: scan }
            - timer.start: { timer: cooldown, delay_ms: 7000 }
            - server.emit: { event: beacon_requested }
        - id: scan_finished
          on: sound.completed
          when:
            - { path: event.key, op: eq, value: scan }
          actions:
            - sound.play: { asset: beacon_chirp, key: confirmation }
        - id: cooldown_finished
          on: timer.cooldown
          actions:
            - state.set: { path: ready, value: true }
        - id: beacon_live
          on: server.beacon_changed
          actions:
            - light.set: { target: status_indicator, value_from: event.enabled }
        - id: beacon_restored
          on: server.beacon_sync
          actions:
            - light.set: { target: status_indicator, value_from: event.enabled }
        - id: reconnect_controls
          on: connection.ready
          actions:
            - timer.cancel: { timer: cooldown }
            - state.set: { path: ready, value: true }
        - id: capture_begin
          on: push_to_talk.pressed
          actions:
            - timer.cancel: { timer: cooldown }
            - state.set: { path: ready, value: true }
            - capture.begin: {}
        - id: capture_stop
          on: push_to_talk.released
          actions:
            - capture.stop: {}
  state_sync:
    - id: restore_beacon
      from: device.presentation.beacon.enabled
      event: beacon_sync
assets:
  rescue_scan:
    sha256: 79702b4710f37597a1bc7adb28d853592620a81625725f563dca6ed7267952c0
    required: true
  beacon_chirp:
    sha256: 99f045eeb622510dad2943b91adacc18307b04b73cf92752ac8d8718f9ac1850
    required: true
