|
| 1 | +# Scenario Review Guide |
| 2 | + |
| 3 | +This guide covers key areas to review when creating or modifying scenario files, based on lessons learned from scenario4 development. |
| 4 | + |
| 5 | +## File Structure |
| 6 | + |
| 7 | +Scenario files are located in `src/campaigns/<campaign>/scenario<N>.ts` and export a `ScenarioData` object containing: |
| 8 | + |
| 9 | +- Metadata (id, title, description, difficulty) |
| 10 | +- Settings (ground stations, satellites, equipment layout) |
| 11 | +- Objectives array |
| 12 | +- Dialog clips |
| 13 | + |
| 14 | +## Review Checklist |
| 15 | + |
| 16 | +### 1. Frequency Calculations |
| 17 | + |
| 18 | +Verify all RF-to-IF conversions are correct. Common formulas: |
| 19 | + |
| 20 | +| Signal Type | Conversion | Example | |
| 21 | +|-------------|------------|---------| |
| 22 | +| Downlink (high-side LNB) | IF = LO - RF | LO 5250 MHz, RF 4180 MHz → IF 1070 MHz | |
| 23 | +| Uplink (low-side BUC) | RF = IF + LO | IF 1020 MHz, LO 7000 MHz → RF 8020 MHz | |
| 24 | + |
| 25 | +**Check these match across:** |
| 26 | + |
| 27 | +- Objective condition params (e.g., `frequency: 1070e6`) |
| 28 | +- Objective descriptions (e.g., "Set to 1070 MHz") |
| 29 | +- Dialog text (e.g., "1,070 megahertz") |
| 30 | +- Equipment initial state in settings |
| 31 | + |
| 32 | +### 2. Objective Sequencing |
| 33 | + |
| 34 | +Review the prerequisite chain: |
| 35 | + |
| 36 | +```typescript |
| 37 | +prerequisiteObjectiveIds: ['previous-objective-id'] |
| 38 | +``` |
| 39 | + |
| 40 | +- Each objective should reference the correct predecessor |
| 41 | +- First objective should have empty prerequisites: `[]` |
| 42 | +- Verify the logical flow makes sense operationally |
| 43 | + |
| 44 | +### 3. Timer Configuration |
| 45 | + |
| 46 | +Per-objective timers require two fields: |
| 47 | + |
| 48 | +```typescript |
| 49 | +timeLimitSeconds: 3 * 60, // Duration in seconds |
| 50 | +timerStartTrigger: 'on-activate' // When timer starts |
| 51 | +``` |
| 52 | + |
| 53 | +Guidelines: |
| 54 | + |
| 55 | +- Simple tasks (quizzes, toggles): 2 minutes |
| 56 | +- Configuration tasks (frequency, modulation): 2-3 minutes |
| 57 | +- Multi-step tasks (antenna slew + verify): 3 minutes |
| 58 | +- Mission brief review: No timer (omit both fields) |
| 59 | + |
| 60 | +### 4. Condition Parameters |
| 61 | + |
| 62 | +Verify condition params match expected types from `objectives-manager.ts`: |
| 63 | + |
| 64 | +```typescript |
| 65 | +// Frequencies should be in Hz |
| 66 | +{ type: 'speca-center-frequency', params: { centerFrequency: 1070e6, ... } } |
| 67 | + |
| 68 | +// Angles need type casting |
| 69 | +{ type: 'antenna-position', params: { azimuth: 219.7 as Degrees, ... } } |
| 70 | + |
| 71 | +// Power levels in dBm |
| 72 | +{ type: 'signal-detected', params: { minPower: -95 as dBm, ... } } |
| 73 | +``` |
| 74 | + |
| 75 | +Common mistakes: |
| 76 | + |
| 77 | +- Using MHz instead of Hz for frequency params |
| 78 | +- Missing tolerance values |
| 79 | +- Forgetting `as Degrees` or `as dBm` casts |
| 80 | + |
| 81 | +### 5. Maintain Flags |
| 82 | + |
| 83 | +Choose the appropriate maintain behavior: |
| 84 | + |
| 85 | +| Flag | Use Case | |
| 86 | +|------|----------| |
| 87 | +| `mustMaintain: false` | One-time actions (open brief, answer quiz) | |
| 88 | +| `mustMaintain: true` | Continuous conditions during objective | |
| 89 | +| `maintainUntilObjectiveComplete: true` | Settings that must persist across multi-step objectives | |
| 90 | +| `maintainDuration: 30` | Stability check (hold for N seconds) | |
| 91 | + |
| 92 | +### 6. Dialog Consistency |
| 93 | + |
| 94 | +**Character voice:** |
| 95 | + |
| 96 | +- Each character has a defined role and speech pattern |
| 97 | +- Check `character-enum.ts` for character descriptions |
| 98 | +- Instructors give commands; observers report status |
| 99 | + |
| 100 | +**Technical accuracy:** |
| 101 | + |
| 102 | +- Dialog should match what the player actually did |
| 103 | +- Don't reference information the character wouldn't have |
| 104 | +- Example: A remote operator can't see local telemetry unless transmitted |
| 105 | + |
| 106 | +**Frequency mentions:** |
| 107 | + |
| 108 | +- Spell out frequencies: "1,070 megahertz" not "1070MHz" |
| 109 | +- Must match the objective's actual parameters |
| 110 | + |
| 111 | +### 7. Equipment Initial State |
| 112 | + |
| 113 | +Review the `settings.groundStations` overrides: |
| 114 | + |
| 115 | +```typescript |
| 116 | +settings: { |
| 117 | + groundStations: [ |
| 118 | + { |
| 119 | + ...vermontGroundStation, |
| 120 | + rfFrontEnds: [ |
| 121 | + createRfFrontEnd(vermontGroundStation.rfFrontEnds[0], { |
| 122 | + buc: { isMuted: true }, |
| 123 | + hpa: { isHpaEnabled: false }, |
| 124 | + }), |
| 125 | + ], |
| 126 | + }, |
| 127 | + ], |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +Verify: |
| 132 | + |
| 133 | +- Initial state matches scenario premise (e.g., safe state before switchover) |
| 134 | +- Player has something to do (don't pre-configure everything) |
| 135 | +- State is achievable from objectives (e.g., if objective requires beacon lock, antenna must be pointable at satellite) |
| 136 | + |
| 137 | +### 8. Ground Station Assignment |
| 138 | + |
| 139 | +Every objective needs `groundStation` set: |
| 140 | + |
| 141 | +```typescript |
| 142 | +{ |
| 143 | + id: 'configure-antenna', |
| 144 | + groundStation: 'VT-01', // Must match a configured station ID |
| 145 | + ... |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +### 9. Points Distribution |
| 150 | + |
| 151 | +Review point allocation makes sense: |
| 152 | + |
| 153 | +- Simple tasks: 5-10 points |
| 154 | +- Configuration tasks: 10-15 points |
| 155 | +- Verification/lock tasks: 15-25 points |
| 156 | +- Quiz penalties: typically 5 points per wrong answer |
| 157 | + |
| 158 | +### 10. TypeScript Compilation |
| 159 | + |
| 160 | +After changes, verify no type errors: |
| 161 | + |
| 162 | +```bash |
| 163 | +npx tsc --noEmit src/campaigns/<campaign>/scenario<N>.ts |
| 164 | +``` |
| 165 | + |
| 166 | +Common issues: |
| 167 | + |
| 168 | +- Unused imports after refactoring |
| 169 | +- Missing type casts on branded types |
| 170 | +- Incorrect condition type names |
| 171 | + |
| 172 | +## Quick Reference: Satellite Frequencies |
| 173 | + |
| 174 | +| Satellite | Beacon RF | Downlink RF | Uplink RF | |
| 175 | +|-----------|-----------|-------------|-----------| |
| 176 | +| TIDEMARK-1 | 4175.5 MHz | 3718 MHz | 5943 MHz | |
| 177 | +| TIDEMARK-2 | 4180 MHz | 3792 MHz | 6017 MHz | |
| 178 | +| SES-10 | 4178 MHz | 3644 MHz | 5869 MHz | |
| 179 | + |
| 180 | +## Quick Reference: VT-01 IF Frequencies (LNB LO = 5250 MHz) |
| 181 | + |
| 182 | +| Satellite | Beacon IF | Downlink IF | |
| 183 | +|-----------|-----------|-------------| |
| 184 | +| TIDEMARK-1 | 1074.5 MHz | 1532 MHz | |
| 185 | +| TIDEMARK-2 | 1070 MHz | 1458 MHz | |
| 186 | +| SES-10 | 1072 MHz | 1606 MHz | |
0 commit comments