# Game Extension Workflow Use this workflow whenever adding, renaming, removing, or substantially changing a game. ## Add a New Game 1. Create installer script: - Path: `.install/.sh` - Keep first line active (do not start with `#//`). - Reuse manager helpers (`check_architecture`, `check_dependencies`, `download`, `download_named`, `get_installer`, `ui_*`). - Install into a deterministic path under `${installPath}`. 2. Create launcher definition: - Path: `.launch/.game` - Keep base filename identical to installer (``). - Include an explicit install-path variable based on `installPath`, for example: ```bash gamePath="${installPath}/MyGame" ``` - Run the game from that path. 3. Optional update script: - Path: `.update/.sh` - Implement `run_update()` (required by update flow). 4. Let installer create runnable launcher entry: - The manager auto-creates `.launch/.sh` symlink when installer completes and `.game` exists. ## Rename a Game Safely 1. Rename `.install/.sh` to `.install/.sh`. 2. Rename `.launch/.game` to `.launch/.game`. 3. Rename `.update/.sh` if present. 4. Remove stale `.launch/.sh` if still present. 5. Re-run catalog audit and manual checks. ## Remove a Game From Repo 1. Delete `.install/.sh`. 2. Delete `.launch/.game`. 3. Delete `.launch/.sh` if tracked. 4. Delete `.update/.sh` if present. 5. Run catalog audit to confirm no orphan entries remain. ## Disable Policy (Important) When a request says "disable " without more detail: 1. Default behavior: disable installs only. - Add `#//` to first line of `.install/.sh`. - Do not disable `.launch/.game` by default. - This preserves playability for users who already have the game installed. 2. If user explicitly requests complete disable: - Add `#//` to first line of both: - `.install/.sh` - `.launch/.game` 3. If wording is ambiguous but could imply full disable/removal: - Ask a short clarification question before changing launcher/removal behavior. ## Manual Validation Checklist 1. Run installer flow: ```bash ./linux-game-manager.sh -i ``` 2. Confirm launcher files exist: ```bash ls ".launch/.game" ".launch/.sh" ``` 3. Run launcher flow: ```bash ./linux-game-manager.sh ``` 4. Run removal flow: ```bash ./linux-game-manager.sh -r ``` 5. If updater exists, run update flow: ```bash ./linux-game-manager.sh -u ``` 6. Run consistency audit: ```bash python3 .codex/skills/linux-game-manager-dev/scripts/audit_game_catalog.py ``` ## Script Authoring Rules - Use camelCase variable names. - Use snake_case for function names. - Keep scripts robust when sourced in the manager shell. - Avoid introducing unnecessary colorized output. - For edited bash scripts, run shellcheck and fix all errors. - If `shellcheck` is not installed, prompt the user to install it first (see `references/tooling-prereqs.md`). ## Pattern: uv + Host Python speechd Bindings Use this pattern for Python games installed with `uv` when runtime speech support depends on `import speechd`. 1. In installer script: - Check dependencies: `git`, `uv`, and host python binding import (`python-speechd:speechd`). - Clone game repository into `${installPath}/`. - Run `uv sync` in the project directory that contains `pyproject.toml`. - Resolve speechd source path from host Python via: - `python3 -c 'import pathlib,speechd; print(pathlib.Path(speechd.__file__).resolve())'` - Copy the module/package into a game-local directory such as: - `${installPath}///.host-python/` - Fail with a clear message if import or copy fails. 2. In launcher script: - Export `PYTHONPATH` with the game-local `.host-python` directory prepended. - Launch via `uv run ...` from the same directory used for `uv sync`. 3. Removal safety: - Ensure first `installPath` line in launcher points to a path that lets `game_removal` infer the game root correctly. - Do not put `installPath` in comments above that path line, because removal currently grabs the first matching line.