Files
gamewrap/docs/roadmap.md
T
44r0n7 f984acf0e3 feat: hook reliability, hook-errors setting, sparse config, and logging
Hook reliability:
- Add hook-errors = "warn" | "fail" setting (default: warn); in fail
  mode, abort launch when pre-launch hook exits nonzero or can't execute
- Ensure post-launch hook runs unconditionally, even when execute_wait()
  fails to spawn the game
- Propagate game's real exit status via std::process::exit(); report
  post-hook failures clearly to stderr
- Centralize hook execution via run_hook() helper (sh -c)

New features in this batch:
- Sparse config and profile support: only configured fields are written;
  unset fields fall back through profile → global chain
- config show --effective flag: renders the fully-resolved view
- Config migration: upgrades legacy flat config to current schema
- Structured decision logging (src/log.rs) for session-level audit trail
- Gamescope improvements: additional flags and validation
- CHANGELOG.md tracking template releases

Schema / UX:
- HookErrors enum (Warn/Fail) added to Settings and ResolvedSettings
- hook-errors key in keys.rs, mod.rs rendering, completion candidates,
  doctor output, help text, README, and dry-run display
- 9 focused tests covering warn/fail behavior, exit propagation,
  round-trip (set/show/reset), profile round-trip, export/import

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-06-14 09:35:24 -04:00

340 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# gamewrap Roadmap
## Purpose
`gamewrap` is a Steam-first Linux game launcher wrapper that keeps Steam launch options short while moving launch behavior into a readable, persistent config.
The project is designed to make features like MangoHud and GameMode easier to use without requiring users to remember long launch commands, environment variables, or per-game flag combinations.
Core product goals:
- keep Steam launch options simple
- prefer human-friendly configuration over flag-heavy one-off commands
- fail clearly when launch requirements are not met
- keep runtime overhead low
- support both quick default usage and deeper profile-based customization
## Current Direction
The current preferred Steam usage is:
```text
gamewrap %command%
```
The preferred low-maintenance install approach is:
1. install with `cargo install`
2. ensure `~/.cargo/bin` is on PATH in the desktop session
This lets Steam resolve `gamewrap` by name without committing to long-term package maintenance yet.
## Current Feature Set
Implemented features:
- Steam-first launcher flow with `gamewrap %command%`
- Default launch mode with MangoHud and GameMode
- Friendly setting names for all launch options
- Named game-specific profiles (flat two-tier: global defaults + per-game overrides)
- Per-profile environment variable overrides (`profile env set/unset/list/clear`)
- Manual executable-to-profile bindings
- Observed game history with launch count, timestamps, and display names
- Play time tracking per game (when post-launch hook is configured)
- `game rename` for human-readable game names
- `game forget` to remove entries from observed history
- `gamewrap last` to see the most recently played game
- gamescope Wayland compositor integration
- vkBasalt post-processing integration
- FPS cap via MangoHud
- Proton esync/fsync/large-address-aware controls
- Pre-launch and post-launch shell hooks
- `status` command
- `doctor` preflight checks with color-coded output
- `dry-run` launch plan preview
- `config edit` to open config in `$EDITOR`
- Config and profile export/import for sharing
- `notify test` for graphical notification verification
- ANSI color output (respects NO_COLOR, CLICOLOR, CLICOLOR_FORCE)
- Shell completion with live candidates (profiles, games, settings)
- Clear runtime dependency checks and actionable error messages
Friendly settings supported:
- `mangohud`, `gamemode`, `steam-host-libs`, `game-libs`, `verbose`
- `gamescope`, `gamescope-width`, `gamescope-height`, `gamescope-fps`
- `fps-cap`, `vkbasalt`
- `esync`, `fsync`, `large-address-aware`
- `pre-launch`, `post-launch`
- `env-vars` (via `profile env` subcommands)
## v1 Done Criteria
The project can be considered functionally complete for v1 when all of the following are true:
- [x] Steam launch works reliably with the chosen install method
- [x] MangoHud enable/disable works correctly
- [x] GameMode enable/disable works correctly
- [x] `doctor`, `status`, and `dry-run` are trustworthy for normal troubleshooting
- [x] launch failures are visible and understandable
- [x] README and CLI help are clear enough for a new user
- [x] no major known bugs remain in the core launch path
- [x] native Linux games validated in real testing
- [x] Proton / Windows games validated in real testing
- [x] one intentional failure case tested
**v1 complete — 2026-05-31.**
## Validation Still Desired
Real-world validation to finish before calling v1 done:
- test at least one native Linux game
- test at least one Proton / Windows game
- test one intentional failure case
- confirm Steam launch behavior with the preferred install method
- confirm notification behavior for internal launcher failures
- confirm that profile binding works on an actual game executable
## Packaging and Distribution Plan
Long-term packaging direction:
- distro-native packages first
- `cargo install` remains supported but is not the ideal end-user distribution path
Planned packaging targets:
- Arch Linux / AUR
- Debian / Ubuntu
- Fedora / RPM
Packaging goals:
- install `gamewrap` to a system-visible path such as `/usr/bin/gamewrap`
- allow Steam launch options to use `gamewrap %command%`
- avoid requiring absolute paths for normal packaged installs
Packaging status:
- deferred for now in favor of low maintenance
- still an explicit project direction, not abandoned
Repository:
- Gitea: https://git.44r0n.cc/44r0n7/gamewrap.git (canonical for now)
- Issue tracker: https://git.44r0n.cc/44r0n7/gamewrap/issues
Still undecided:
- homepage URL
- release hosting / distribution channels
- whether to mirror to GitHub
## Deferred Feature Expansion
Features that were deferred from the initial scope and are now implemented:
-`gamescope` integration
-`vkBasalt` integration
- ✓ Custom environment presets (per-profile env var overrides)
- ✓ Proton and Wine compatibility toggles (esync, fsync, large-address-aware)
Features still deferred:
- Benchmark and recording profile presets (named templates that bundle several settings)
- Additional launcher helpers beyond the current set
- **Profile description field for community sharing** — add `description: Option<String>` to `ProfileConfig` and `SharedProfileFile`, shown at the top of exported `.gamewrap-profile.toml` files so ProtonDB/forum posts are self-documenting. CLI: `gamewrap profile describe <name> <text>` and `profile clear-describe <name>`. Preserved through import and shown in `profile show`/`profile list`. No tags, AppIDs, or author fields — those belong on the posting platform, not in the file.
## Recommended Expansion Order
Items 13 are now implemented. Remaining if development continues:
4. Benchmark / recording profile presets — named templates that bundle several settings into a shareable starting point
5. Graphics API detection (advisory only — see separate section)
6. Additional launcher helpers only if they clearly improve the main use case
## Future Proton and Compatibility Controls
One planned expansion area is support for common Steam/Proton launch adjustments that users often copy from compatibility guides, community comments, or ProtonDB reports.
Examples of future controls that may be worth supporting:
- DXVK-related toggles
- VKD3D-related toggles
- esync/fsync toggles
- Wine debug environment controls
- fullscreen and compositor-related tweaks
- launch-time environment overrides for specific games
- Proton-specific compatibility presets that bundle several known-good settings
This should not become a free-form dump of obscure environment variables by default. The intended direction is:
- expose the most common useful adjustments with friendly names
- keep raw environment overrides available only as an advanced escape hatch if ever added
- prefer reusable presets and profiles over forcing users to remember low-level variables
- use `doctor` and help text to explain what a toggle actually changes
Potential sources of future ideas:
- recurring compatibility patterns seen in ProtonDB reports
- common launch command snippets shared in Linux gaming communities
- settings that repeatedly solve real issues in actual testing
Guardrails for this work:
- do not blindly mirror every ProtonDB workaround
- avoid adding toggles that are highly game-specific unless they can be grouped into a sensible preset model
- keep the main UX readable and non-intimidating
- require a clear explanation in help text for every added compatibility control
## Graphics API Detection (Maybe)
A potential future addition: detect a game's graphics API at launch time and use that to surface
warnings or skip inapplicable settings. Not on the roadmap yet, but worth revisiting.
Specific cases where it would help:
- **vkBasalt safety** — vkBasalt only works with Vulkan. For OpenGL or WineD3D games, `ENABLE_VKBASALT=1`
silently does nothing. Detection could skip the env var or warn in `doctor`.
- **Gamescope compatibility** — Gamescope is Vulkan-only. If `gamescope = on` is set but the game uses
OpenGL, it will fail or fall back unexpectedly. A preflight warning would catch this.
- **DXVK vs VKD3D-Proton env hints** — Per-profile overrides like `DXVK_ASYNC 1` only matter for D3D9/10/11
games (DXVK). D3D12 games use VKD3D-Proton with a different set of vars. Detection could surface
a mismatch warning when running `doctor`.
- **MangoHud invocation method** — MangoHud works as both a command prefix and an env var injection. The
env var path works better for some Vulkan games. Detection could pick the right method.
How detection would likely work in practice:
- Check for `d3d9.dll`/`d3d11.dll`/`dxgi.dll` in the game directory → DXVK (D3D9/10/11 via Vulkan)
- Check for `d3d12.dll` → VKD3D-Proton (D3D12 via Vulkan)
- Check for `.dxvk-cache` / `.d3d12.cache` files → reliable secondary signals
- Native Linux ELFs: inspect imported libs with `ldd` or `file` — harder, lower priority
Guardrails if this is ever added:
- Detection should be advisory only — never silently override user config
- Emit warnings in `doctor` and `dry-run`, not at actual launch time
- Degrade gracefully when detection is inconclusive (most common case)
- Do not make profile selection automatic based on detection results
The "avoid" note in Product Boundaries refers to _automatic profile selection_ based on detection,
not to using detection for diagnostics and warnings. Those are meaningfully different.
## Product Boundaries
Things `gamewrap` should continue to optimize for:
- simple Steam usage
- low system impact
- minimal always-on behavior
- understandable configuration
- useful diagnostics
Things to avoid unless clearly justified:
- automatic profile selection based on graphics API or runtime detection (advisory warnings are fine)
- heavy background services
- large dependency trees just to support optional extras
- turning the project into a general desktop/session manager
## Installation Strategy for Now
Short-term recommended install strategy:
- `cargo install --path . --force` — installs to `~/.cargo/bin/gamewrap`
- Ensure `~/.cargo/bin` is on PATH in your desktop session so Steam can find it by name
Reason:
- low maintenance
- easy updates
- Steam can resolve `gamewrap` by name if `~/.cargo/bin` is on session PATH
- no distro package maintenance burden yet
## Dependency Maintenance (post-1.0)
Checked 2026-05-31. Most crates are on current patch versions via `cargo update`. Two deferred upgrades:
- **toml 0.8 → 1.x**: top-level `from_str`/`to_string_pretty` likely unchanged but the 1.x release has low-level Deserializer/Serializer API changes. Verify against 1.x docs before upgrading. Low urgency — 0.8 is still maintained.
- **owo-colors 1.x → 4.x**: major version jump. Our usage (`.green()`, `.bold()`, `.dimmed()`, `.cyan()`, `OwoColorize`) is fundamental and unlikely to have changed, but read the changelog before upgrading. Low urgency — 1.x works fine.
- **clap_complete `unstable-dynamic` feature**: may have been renamed to `unstable-command` in 4.6.x. Run `cargo update && cargo test` — if it fails, rename the feature flag in `Cargo.toml`. Low risk, one-line fix if needed.
## Notes for Future Work
Before starting packaging or deferred features, re-check:
- whether the install story should remain PATH-based for personal use
- whether the project is going public
- whether package maintenance is worth the overhead
- whether v1 behavior is stable enough to freeze the main CLI/config model
---
## Post-v1 Backlog
Logged 2026-06-06. Priority order reflects dependencies — B1 sets naming used by B5, and JSON output (B6 Phase 1) is prerequisite for any GUI work.
### B1 + B4 — Settings grouping, tool-prefixed names, help system overhaul
**Problem:**
- `gamewrap help settings` outputs 36 settings in a flat, ungrouped list with no visual separation by tool
- `overlay` (MangoHud) and `performance` (GameMode) have no tool prefix while every gamescope/vkbasalt/mangohud-log setting already does
- A gamescope configuration note currently sits orphaned between log options and the gamescope settings block in help output
**Proposed changes:**
- Rename `overlay``mangohud` (the MangoHud enable/disable toggle), consistent with `mangohud-log`
- Rename `performance``gamemode` (the GameMode enable/disable toggle)
- Group `gamewrap help settings` into tool-based sections: **Core**, **MangoHud**, **GameMode**, **Gamescope**, **vkBasalt**, **Proton/Wine**, **Hooks & Logging**
- Move the gamescope configuration note into the Gamescope section header (fixes B4)
- Enhance `topic_text()` in `src/help.rs` to accept an optional tool filter: `gamewrap help settings gamescope`
- Propagate renames everywhere: `Settings` struct fields, CLI parser, `config/keys.rs`, TOML serialization, shell completion, tests, README, docs
- Add a migration path for existing configs using the old names (clear error pointing to new name, or silent rename on load)
**Note:** Breaking change — existing config files and profiles using `overlay` or `performance` will need migration. Sets the naming foundation for B5.
**Key files:** `src/help.rs`, `src/config/schema.rs`, `src/config/keys.rs`, `src/config/mod.rs`, `src/cli.rs`, `src/completion.rs`, `tests/`, `README.md`
---
### B2 — Large game list management
**Problem:**
- After using gamewrap on many games (demos, uninstalled games, one-offs), `game list` grows without bound
- The only removal option is `game forget` (hard deletion); no way to soft-hide entries
**Proposed changes:**
- Add `game archive <name-or-exe>` / `game unarchive <name-or-exe>` — sets an `archived` flag on the state entry, excluded from default `game list`
- `game list --all` shows archived entries alongside active ones (visually marked)
- `game forget` remains for permanent removal
- `game list` shows an entry count and a hint if the list exceeds a threshold (e.g. 20 entries)
**Key files:** `src/cli.rs`, state file handling in `src/config/mod.rs`, `src/detect.rs`, tests
---
### B3 — Profile export semantics
**Question:** When a profile is exported to share:
- **Option A — sparse:** Export only what was explicitly set in the profile. Recipient's globals fill the rest at their end. Simple and portable; behavior depends on recipient's global config.
- **Option B — effective:** Export fully resolved settings (profile + globals baked in). Recipient gets a "known good" snapshot but must manually strip their own preferences.
- **Option C — sparse + informational context:** Export sparse profile, plus a `# context:` comment block showing what the exporter's globals were at export time. Informational only — not interpreted by import.
**Current behavior:** Option A (sparse).
**Resolved:** Sparse export implemented. Profiles are now flat (no inheritance). Export produces only explicitly set settings.
---
### B5 — Grouped, cleaner `config show` / `profile show` display
**Problem:**
- `config show` output (especially `--effective`) has no visual grouping — 30+ settings appear in struct field order
- No section headers separating e.g. gamescope settings from MangoHud settings
**Proposed changes:**
- Refactor `render_resolved_settings()` and `render_profile_settings_with_indent()` to emit settings under dimmed section headers using the same tool groups as B1
- Configured mode (default): only show a section header if that section has at least one configured value
- Effective mode (`--effective`): always show section headers; show `(nothing configured)` per-section if empty
**Dependency:** Best done after B1, which defines the canonical section groupings. Can be scoped independently by hardcoding groups if B1 is deferred.
**Key files:** `src/config/mod.rs`, tests
---
### B6 — JSON output flag + GUI (discussion needed)
**Phase 1 — JSON flag (independent):**
- Add `--json` flag to read commands: `config show`, `profile show`, `game list`, `status`, `dry-run`
- Write/mutating commands return `{"ok": true}` or the updated state on success
- Useful for scripting independently of any GUI
**Phase 2 — GUI (dependent on Phase 1):**
- Build a GUI that invokes `gamewrap` as a subprocess and renders the JSON output
- CLI remains the authoritative source of truth; GUI is a frontend only
**Discussion points before Phase 2:**
- Framework: egui (Rust, self-contained), iced (Rust async), Tauri (web frontend, heavier), GTK4 (gtk-rs)?
- Scope: full settings editor, profile manager, game list browser, or read-only status overlay?
- Packaging: GUI as an optional Cargo feature flag to keep the base CLI install slim?
**Recommended starting point:** Phase 1 JSON flag only.