diff --git a/app/views/break_escape/games/show.html.erb b/app/views/break_escape/games/show.html.erb index c1d7f3d4..2a0c2f68 100644 --- a/app/views/break_escape/games/show.html.erb +++ b/app/views/break_escape/games/show.html.erb @@ -44,6 +44,7 @@ + diff --git a/index.html b/index.html index a2452022..29982fea 100644 --- a/index.html +++ b/index.html @@ -51,6 +51,7 @@ + diff --git a/planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md b/planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md new file mode 100644 index 00000000..3254e989 --- /dev/null +++ b/planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md @@ -0,0 +1,247 @@ +# SIS Configuration Threshold Display (Scenario 2) Implementation Plan + +Date: 2026-04-11 +Owner: Break Escape engineering +Scope: Implement the Scenario 2 SIS configuration threshold minigame with minimal code changes and full narrative/state integration. + +## 1. Source Alignment and Scope + +This plan is aligned to: + +- planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md +- planning_notes/sis_scenarios/case_2_energy_game_design/development_tasks.csv +- planning_notes/sis_scenarios/case_2_energy_game_design/case_2_energy_gdd.md +- planning_notes/sis_scenarios/case_2_energy_game_design/new_objects_planning.md +- planning_notes/sis_scenarios/case_2_energy_information_pack/requirements/claims.md +- scenarios/sis02_energy/scenario.json.erb +- scenarios/sis02_energy/mission.json +- scenarios/sis02_energy/ink/INK_DEVELOPMENT_SUMMARY.md + +Note on path request: + +- scenarios/sis02_healthcare does not exist in this repo. +- Scenario 2 implementation target is scenarios/sis02_energy. + +## 2. Canonical Feature Definition + +Feature name: SIS Configuration Threshold Display + +Intended behavior: + +- Interactive minigame opened from the Engineering Workshop SIS panel object. +- Shows a setpoint table: parameter, current value, certified baseline, deviation status, last-modified, modified-by. +- Deviation rows are highlighted and expandable for explanatory detail. +- Compare workflow is delivered in a stub-compatible way in phase 1 (no new globals), with stricter certification gating deferred to phase 2 if needed. +- Confirm action records tamper confirmation and advances narrative logic. + +Core teaching moment: + +- THERMAL_RUNAWAY_THRESHOLD changed from 55C certified baseline to 85C current value. + +## 3. Known Naming Drift (Must Resolve Before Coding) + +There is MG ID drift across docs: + +- minigame_planning labels SIS display as MG-03. +- development_tasks labels SIS display as MG-02. + +Implementation rule: + +- Use feature/object identity, not MG number: + - object id: sis_config_panel + - behavior: SIS Configuration Threshold Display + +There is variable naming drift across docs: + +- sis_certification_seen +- sis_cert_reviewed +- current scenario uses sis_config_seen and sets sis_tamper_confirmed from document read. + +Scenario 2 stub precedence rule (source of truth for implementation phase 1): + +- Keep existing globals and placeholder flow already defined in scenarios/sis02_energy/scenario.json.erb. +- Do not introduce new global variable names in phase 1. +- Use current globals as implemented in scenario stub: + - sis_config_seen + - sis_tamper_confirmed + - en002_claim_assessed + +Variable governance rule (authoritative for implementation): + +- planning_notes/sis_scenarios/case_2_energy_game_design defines intended gameplay concepts. +- scenarios/sis02_energy/scenario.json.erb defines authoritative current variable names for implementation. +- If a new global variable becomes necessary, request user approval before adding it. + +Optional phase 2 cleanup: + +- Add a dedicated certification-reviewed global only if needed after phase 1 is stable. + +## 4. Dependency Map + +Scenario objects: + +- sis_config_panel (engineering workshop): launch point for minigame +- SIS certification document object (filing cabinet): enables compare workflow + +Global variables read: + +- sis_config_seen (existing open/read marker) +- sis_tamper_confirmed (existing progression marker; also for reopen idempotency) + +Global variables written: + +- sis_config_seen +- sis_tamper_confirmed +- en002_claim_assessed + +Narrative and progression dependencies: + +- Priya branch unlocks on sis_tamper_confirmed +- Dr Bashir debrief logic references sis_tamper_confirmed +- Alarm panel state logic references sis_tamper_confirmed (current or future engine behavior) +- Objectives/tasks tied to SIS investigation complete through existing event mappings and globals + +Claims linkage: + +- EN-002 is the primary claim teaching link for this minigame. + +## 5. Minimal Technical Implementation Plan + +### 5.1 Files to Add + +1. public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js + +- New minigame class extending MinigameScene. +- Render table UI in DOM/CSS (consistent with existing HTML/CSS minigame patterns). +- Read scenario params for table rows and labels. +- Emit state updates through existing global variable update pathway. + +2. public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold.css (optional) + +- Keep inline styles only if consistent with local minigame style patterns. +- Prefer scoped CSS class names if using style injection in JS. + +### 5.2 Files to Update + +1. public/break_escape/js/minigames/index.js + +- Import/export/register scene name: sis-config-threshold. + +2. public/break_escape/js/systems/interactions.js + +- Add object type handler for sis_config_panel (or explicit id fallback). +- Start minigame via MinigameFramework.startMinigame with scenarioData payload. + +3. scenarios/sis02_energy/scenario.json.erb + +- Convert current readable placeholder for sis_config_panel into minigame-backed object config. +- Preserve existing stub globals and placeholder naming. +- Build minigame behavior from existing sis_config_panel stub content (same setpoints, same narrative text intent). +- Keep certification-document interaction compatible with current scenario flow in phase 1. +- Only adjust global writes when required to avoid bypassing the minigame, and keep objective/NPC behavior unchanged. + +### 5.3 Data Contract (scenarioData) + +Suggested shape: + +- type: sis_config_panel +- title: SIS CONFIGURATION - BATTERY HALL SIS +- rows: [] + - parameter + - currentValue + - certifiedValue + - status (GREEN/AMBER/RED) + - lastModified + - modifiedBy + - detailText +- compare: + - requiresGlobal: sis_tamper_confirmed (phase 1 fallback to existing globals only) + - disabledHint +- actions: + - confirmSets: + - sis_tamper_confirmed: true + - en002_claim_assessed: true + - openSets: + - sis_config_seen: true + +## 6. UI/Visual Design Specification + +Style direction: + +- Industrial SIS panel UI, small-control-system feel, no rounded corners. +- Use strong table hierarchy and high-contrast status highlights. + +Visual requirements: + +- Header: SIS configuration title bar. +- Main: tabular setpoint grid with clear certified vs current columns. +- Deviation rows: amber/red emphasis with warning glyph. +- Expanded explanation panel/modal for clicked deviation row. +- Compare button: + - phase 1: use existing stub-compatible behavior (no new certification-reviewed global) + - phase 2 (optional): add strict certification-reviewed gating +- Confirm button: + - explicit irreversible confirmation dialog + - completion state shown before close + +Animation/motion (minimal): + +- subtle row highlight pulse for deviated row +- panel slide/fade for compare overlay +- no excessive animation + +Accessibility/readability: + +- ensure legible type size for desktop and wall-monitor use +- color is not the sole signal; include status text labels + +## 7. Integration Behavior (End-to-End) + +1. Player opens sis_config_panel. +2. Minigame opens and sets sis_config_seen=true. +3. Player inspects rows and can expand deviation details. +4. Compare feature follows phase 1 stub-compatible behavior (strict cert-review gating deferred unless a dedicated global is introduced later). +5. Player confirms tamper. +6. System sets sis_tamper_confirmed=true and en002_claim_assessed=true. +7. Existing event mappings/dialogue/objective logic progress without additional custom engine work. + +Implementation note for phase 1: + +- Since no dedicated certification-reviewed global currently exists in scenario stub, comparison gating must be implemented without adding new globals (or deferred while keeping the rest of the minigame fully functional). + +## 8. Acceptance Criteria + +Functional: + +- Minigame launches from sis_config_panel interaction. +- Correct setpoint values are displayed, including 55C vs 85C thermal threshold mismatch. +- Compare workflow behaves consistently with phase 1 stub constraints and does not require new globals. +- Confirm action updates required globals once, idempotently. +- Existing scenario placeholder globals remain the authority for progression. + +Narrative/system: + +- Priya and Dr Bashir SIS branches unlock as expected after confirm. +- No regression to objective progression. +- Alarm panel/SIS status references remain coherent with sis_tamper_confirmed. + +Quality/minimality: + +- No new engine subsystem introduced. +- Changes limited to minigame registration, interaction routing, and scenario object/global wiring. + +## 9. Implementation Order + +1. Build minigame scene directly from current sis_config_panel placeholder values/content. +2. Register and wire interaction handler. +3. Update scenario object to launch minigame while preserving existing Scenario 2 globals. +4. Remove or narrow only the minimum placeholder bypass logic necessary. +5. Run targeted Scenario 2 SIS progression test (objectives + Priya/Dr Bashir branches). + +## 10. Out of Scope for This Implementation + +- New timer engines, alarm panel driver engines, or hardware GPIO behavior. +- Reworking unrelated MG IDs across all planning docs. +- Large UI framework introduction. + +This keeps implementation minimal while fully delivering the SIS threshold discovery teaching objective for Scenario 2. diff --git a/planning_notes/sis-configuration-threshold/sis_configuration_threshold_review.md b/planning_notes/sis-configuration-threshold/sis_configuration_threshold_review.md new file mode 100644 index 00000000..1cc860dc --- /dev/null +++ b/planning_notes/sis-configuration-threshold/sis_configuration_threshold_review.md @@ -0,0 +1,116 @@ +# SIS Configuration Threshold Review (2026-04-12) + +## Scope + +Review current SIS configuration threshold implementation against planning sources under `planning_notes/sis_scenarios`. + +## Planning Sources Reviewed + +- `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md` +- `planning_notes/sis_scenarios/case_2_energy_game_design/development_tasks.csv` +- Supplemental implementation alignment notes: + - `planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md` + +## Implementation Files Reviewed + +- `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js` +- `public/break_escape/css/sis-config-threshold-minigame.css` +- `public/break_escape/js/minigames/index.js` +- `public/break_escape/js/systems/interactions.js` +- `scenarios/sis02_energy/scenario.json.erb` + +## Executive Summary + +Implementation is mostly in place and wired end-to-end (scene registration, object routing, UI, row-detail modal, compare overlay, and confirm flow). The prior certification-document bypass has been removed, and the progression now follows an explicit two-step model: review certification evidence, then confirm tamper. + +## Matches + +1. Minigame implemented as HTML/CSS interactive panel (planned MG-03/MG-02 equivalent). + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js` + - Evidence: `public/break_escape/css/sis-config-threshold-minigame.css` + - Planning: `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md:87-99` + +2. Panel interaction is wired from `sis_config_panel` object and launches the SIS minigame. + - Evidence: `public/break_escape/js/systems/interactions.js:969-975` + - Evidence: `public/break_escape/js/minigames/index.js:137,155` + - Planning: `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md:90` + +3. Scenario object carries minigame data contract (title, rows, compareTitle, confirmLabel). + - Evidence: `scenarios/sis02_energy/scenario.json.erb:1021-1029` + - Planning: `planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md:146-166` + +4. Row-level detail expansion for non-GREEN rows is implemented. + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:68-85,112-119,152-170` + - Planning: `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md:102` + +5. Compare overlay exists and is disabled when certification evidence is missing. + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:65,99,124-128,171-201` + - Planning: `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md:103,116` + +6. Confirm action exists and sets `sis_tamper_confirmed = true`. + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:229-231` + - Planning: `planning_notes/sis_scenarios/case_2_energy_game_design/minigame_planning.md:104` + +7. `sis_config_seen` is set when panel opens; objective task completion wiring is present. + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:56` + - Evidence: `scenarios/sis02_energy/scenario.json.erb:517-521` + - Planning: `planning_notes/sis-configuration-threshold/sis_configuration_threshold_implementation_plan.md:88,93,177-179` + +## Mismatches + +No active functional mismatches identified for the implemented SIS minigame flow after the latest changes. + +### Resolved During Review + +1. Certification document read no longer bypasses tamper confirmation. + - Current behavior: cert document now sets `sis_certification_seen`, not `sis_tamper_confirmed`. + - Evidence: `scenarios/sis02_energy/scenario.json.erb:93,526,1098` + - Confirm remains explicit in minigame action: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:234` + +2. Comparison gate now supports global-variable gating via `sis_certification_seen`. + - Evidence: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:139` + - Compare gating now uses the global-variable check directly. + +3. `en002_claim_assessed` is intentionally mapped from confirmed tamper (`sis_tamper_confirmed`) via scenario event wiring. + - Evidence: `scenarios/sis02_energy/scenario.json.erb:533-536` + - Decision: accepted implementation approach. + +## Accepted Design Deviation + +1. Main table intentionally omits a visible "certified baseline" column so the certification document and compare action retain investigative value. + - Current behavior: certified values are shown in compare overlay, not in the default table. + - Evidence (current columns): `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:89-91` + - Evidence (certified values in compare overlay): `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:181` + - Status: accepted by design decision; no change required unless design intent changes. + +## Recommended Next Changes (Priority Order) + +1. Run end-to-end in-game validation of the intended sequence. + - Sequence to verify: `sis_config_seen` (panel read) -> `sis_certification_seen` (cert doc read) -> compare enabled -> `sis_tamper_confirmed` (confirm action) -> `en002_claim_assessed` event mapping. + - Evidence wiring: `scenarios/sis02_energy/scenario.json.erb:519,526,533-536`; `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:56,138,234`. + +## Follow-up Q&A Verification (2026-04-12) + +1. Is the cert-doc bypass still in place? + - No. Cert doc read now sets `sis_certification_seen` and no longer sets `sis_tamper_confirmed`: `scenarios/sis02_energy/scenario.json.erb:1098`. + +2. Why not show certified values in the base table? + - Accepted design rationale: keeping certified values in compare mode preserves the purpose of retrieving the certification document. + +3. Does `en002_claim_assessed` get set at all? + - Yes, indirectly. Event mapping on `global_variable_changed:sis_tamper_confirmed` sets `en002_claim_assessed = true`: `scenarios/sis02_energy/scenario.json.erb:533-536`. + - It is not set directly in `applyConfirm()`: `public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js:234`. + +4. Is there a `sis_certification_seen` or `sis_cert_reviewed` global set on cert-doc view? + - Yes. `sis_certification_seen` now exists in scenario globals and is set on cert-doc read. + - Evidence: `scenarios/sis02_energy/scenario.json.erb:93,1098`. + +## Current Assessment + +- Functional readiness: Good +- Design/spec conformance: Good +- Progression integrity risk: Low (pending final in-game validation) + +## Validation Status + +- End-to-end playthrough verification: Pending user run diff --git a/public/break_escape/css/sis-config-threshold-minigame.css b/public/break_escape/css/sis-config-threshold-minigame.css new file mode 100644 index 00000000..83faba21 --- /dev/null +++ b/public/break_escape/css/sis-config-threshold-minigame.css @@ -0,0 +1,265 @@ +/* SIS Config Threshold Minigame Styles */ + +.sis-threshold-minigame-container { + background: rgba(13, 20, 32, 0.72); + border: 2px solid #2b3446; +} + +.sis-threshold-minigame-game-container { + max-width: 620px; + margin: 20px auto; + width: 100%; + background: rgba(17, 26, 40, 0.78) !important; + border: 2px solid #263246; + box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.5); + padding: 12px; + height: 50vh; + box-sizing: border-box; + display: flex; + align-items: center; +} + +.sis-threshold { + font-family: 'VT323', 'Courier New', monospace; + color: #e9edf5; + padding: 8px; + width: 100%; + min-height: 100%; + position: relative; + box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: center; +} + +.sis-threshold-header { + background: #133f73; + border: 2px solid #2b5d93; + padding: 10px 12px; + font-size: 18px; + letter-spacing: 0.4px; +} + +.sis-threshold-table { + width: 100%; + border-collapse: collapse; + margin-top: 10px; + font-size: 16px; +} + +.sis-threshold-table th, +.sis-threshold-table td { + border: 2px solid #2a2f3b; + padding: 8px; + text-align: left; + vertical-align: top; +} + +.sis-threshold-table th { + background: #1f2b3f; + color: #e9edf5; +} + +.sis-row { + background: #212733; + cursor: default; +} + +.sis-row-clickable { + cursor: pointer; +} + +.sis-row-clickable:hover { + background: #313744; +} + +.sis-status-green { + color: #84d78a; + font-weight: 700; +} + +.sis-status-amber { + color: #ffd14b; + font-weight: 700; +} + +.sis-status-red { + color: #ff6a6a; + font-weight: 700; +} + +.sis-row-meta { + color: #9ea7b7; + font-size: 14px; + margin-top: 4px; +} + +.sis-actions { + display: flex; + gap: 10px; + margin-top: 14px; + flex-wrap: wrap; +} + +.sis-btn { + border: 4px solid #2980b9; + border-radius: 0; + padding: 10px 20px; + font-family: 'VT323', monospace; + font-size: 18px; + cursor: pointer; + background: #3498db; + color: #fff; + transition: background 0.3s, box-shadow 0.2s ease, transform 0.15s ease, filter 0.2s ease; +} + +.sis-btn-compare { + background: #b88d21; + color: #fff; + border-color: #8d6f1c; +} + +.sis-btn-compare[disabled] { + background: #5d5d5d; + color: #cfcfcf; + cursor: not-allowed; +} + +.sis-btn-confirm { + background: #b32424; + color: #fff; + border-color: #7e1a1a; +} + +.sis-btn-compare:hover { + box-shadow: 0 0 12px rgba(255, 209, 75, 0.45); + filter: brightness(1.08); + transform: translateY(-1px); +} + +.sis-btn-confirm:hover { + background: #8f1f1f; + border-color: #6d1616; + box-shadow: none; + filter: none; + transform: none; +} + +.sis-btn:active { + transform: translateY(0); + background: #21618c; +} + +.sis-btn-confirm:active { + background: #731818; + border-color: #5d1212; +} + +.sis-help { + margin-top: 8px; + color: #c9cfd9; + font-size: 14px; +} + +.sis-overlay { + position: absolute; + inset: 0; + background: rgba(6, 10, 18, 0.32); + display: none; + align-items: center; + justify-content: center; + padding: 8px; + z-index: 5; + box-sizing: border-box; +} + +.sis-overlay.show { + display: flex; +} + +.sis-modal { + background: #161c26; + border: 2px solid #3c4d68; + max-width: 100%; + width: 100%; + padding: 14px; + box-sizing: border-box; + margin: 0 auto; +} + +.sis-modal h4 { + margin: 0 0 8px 0; + color: #f4f7fb; + font-size: 20px; +} + +.sis-modal p { + margin: 0; + color: #d3dae5; + font-size: 16px; + line-height: 1.35; +} + +.sis-modal-actions { + margin-top: 12px; + display: flex; + gap: 8px; + justify-content: flex-end; +} + +/* Match popup action buttons to framework minigame-button style exactly */ +.sis-modal-actions .sis-btn:not(.sis-btn-compare):not(.sis-btn-confirm) { + background: #3498db; + color: white; + border: 4px solid #2980b9; + padding: 10px 20px; + font-family: 'VT323', monospace; + font-size: 18px; +} + +.sis-modal-actions .sis-btn:not(.sis-btn-compare):not(.sis-btn-confirm):hover { + background: #2980b9; + box-shadow: none; + filter: none; + transform: none; +} + +.sis-modal-actions .sis-btn:not(.sis-btn-compare):not(.sis-btn-confirm):active { + background: #21618c; + transform: none; +} + +.sis-compare-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 8px; + align-items: stretch; +} + +.sis-compare-card { + border: 2px solid #2b3443; + background: #202735; + padding: 10px; + min-height: 132px; + box-sizing: border-box; +} + +.sis-compare-card h5 { + margin: 0 0 6px 0; + font-size: 18px; + color: #f4f7fb; +} + +.sis-compare-item { + margin: 0 0 6px 0; + font-size: 17px; + line-height: 1.35; + color: #eef3ff; + word-break: break-word; +} + +.sis-compare-item-alert { + color: #ffd46b; + font-weight: 700; +} diff --git a/public/break_escape/js/minigames/index.js b/public/break_escape/js/minigames/index.js index 2896de0f..81152bb7 100644 --- a/public/break_escape/js/minigames/index.js +++ b/public/break_escape/js/minigames/index.js @@ -26,6 +26,7 @@ export { BackupRecoveryMinigame } from './backup-recovery/backup-recovery-miniga export { CommandBoardMinigame } from './command-board/command-board-minigame.js'; export { EsdPushbuttonMinigame } from './esd-pushbutton/esd-pushbutton-minigame.js'; export { InfusionPumpMinigame } from './infusion-pump/infusion-pump-minigame.js'; +export { SisConfigThresholdMinigame, startSisConfigThresholdMinigame } from './sis-config-threshold/sis-config-threshold-minigame.js'; export { NetworkArchitectureMinigame } from './network-architecture/network-architecture-minigame.js'; // Initialize the global minigame framework for backward compatibility @@ -97,6 +98,7 @@ import { SiemDashboardMinigame } from './siem/siem-dashboard-minigame.js'; import { EhrTerminalMinigame } from './ehr-terminal/ehr-terminal-minigame.js'; import { CommandBoardMinigame } from './command-board/command-board-minigame.js'; import { InfusionPumpMinigame } from './infusion-pump/infusion-pump-minigame.js'; +import { SisConfigThresholdMinigame, startSisConfigThresholdMinigame } from './sis-config-threshold/sis-config-threshold-minigame.js'; import { NetworkArchitectureMinigame } from './network-architecture/network-architecture-minigame.js'; // Import ransomware display minigame @@ -132,6 +134,7 @@ MinigameFramework.registerScene('backup-recovery', BackupRecoveryMinigame); MinigameFramework.registerScene('command-board', CommandBoardMinigame); MinigameFramework.registerScene('esd-pushbutton', EsdPushbuttonMinigame); MinigameFramework.registerScene('infusion-pump', InfusionPumpMinigame); +MinigameFramework.registerScene('sis-config-threshold', SisConfigThresholdMinigame); MinigameFramework.registerScene('network-architecture', NetworkArchitectureMinigame); // Make minigame functions available globally @@ -149,3 +152,4 @@ window.startTitleScreenMinigame = startTitleScreenMinigame; window.startRFIDMinigame = startRFIDMinigame; window.returnToConversationAfterRFID = returnToConversationAfterRFID; window.startNetworkSegmentationMapMinigame = startNetworkSegmentationMapMinigame; +window.startSisConfigThresholdMinigame = startSisConfigThresholdMinigame; diff --git a/public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js b/public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js new file mode 100644 index 00000000..55d55b48 --- /dev/null +++ b/public/break_escape/js/minigames/sis-config-threshold/sis-config-threshold-minigame.js @@ -0,0 +1,289 @@ +import { MinigameScene } from '../framework/base-minigame.js'; + +const DEFAULT_ROWS = [ + { + parameter: 'THERMAL_RUNAWAY_THRESHOLD', + currentValue: '85C', + certifiedValue: '55C', + status: 'AMBER', + lastModified: '03:22 (today)', + modifiedBy: 'engineering_access', + detailText: 'This value deviates from the IEC 61511 certified baseline. Possible causes: (1) authorised maintenance change requiring recertification, (2) unauthorised modification.' + }, + { + parameter: 'H2_ALARM_THRESHOLD', + currentValue: '1.2% LEL', + certifiedValue: '1.0% LEL', + status: 'AMBER', + lastModified: '03:22 (today)', + modifiedBy: 'engineering_access', + detailText: 'Hydrogen trip threshold has been raised above certified baseline, reducing early-warning margin.' + }, + { + parameter: 'MAX_CHARGE_VOLTAGE', + currentValue: '4.32 V/cell', + certifiedValue: '4.25 V/cell', + status: 'AMBER', + lastModified: '03:22 (today)', + modifiedBy: 'engineering_access', + detailText: 'Overcharge protection limit exceeds certified value, increasing thermal risk during charging.' + } +]; + +function normalizeStatus(status) { + return String(status || 'GREEN').toUpperCase(); +} + +export class SisConfigThresholdMinigame extends MinigameScene { + constructor(container, params = {}) { + super(container, params); + this.rows = Array.isArray(params.rows) && params.rows.length > 0 ? params.rows : DEFAULT_ROWS; + this.compareTitle = params.compareTitle || 'Certification Comparison'; + this.confirmLabel = params.confirmLabel || 'Confirm SIS Tamper - Report to Security'; + } + + init() { + this.params.title = this.params.title || 'SIS Configuration - Battery Hall SIS'; + this.params.cancelText = this.params.cancelText || 'Close'; + super.init(); + + // Keep SIS panel footprint similar to PIN minigame and style as translucent panel. + this.container.className += ' sis-threshold-minigame-container'; + this.gameContainer.className += ' sis-threshold-minigame-game-container'; + + this.setScenarioGlobal('sis_config_seen', true); + this.render(); + this.bindEvents(); + } + + render() { + const container = document.createElement('div'); + container.className = 'sis-threshold'; + + const canCompare = this.hasCertificationDoc(); + + const tableRows = this.rows.map((row, index) => { + const status = normalizeStatus(row.status); + const statusClass = status === 'RED' ? 'sis-status-red' : status === 'AMBER' ? 'sis-status-amber' : 'sis-status-green'; + const clickableClass = status === 'GREEN' ? '' : 'sis-row-clickable'; + + return ` +
| Parameter | +Current Value | +Status | +
|---|
${detailText}
+Report detected SIS setpoint deviations to security operations?
+