Files
Space-Game/apps/game/AGENTS.md
francy51 f83a0c5e59 feat(galaxy): refactor params into core/disk/beam layers, fix randomize button scaling
- Split GalaxyParams into CoreParams, DiskParams, and BeamParams sub-structs
- Add polar beam systems (top/bottom) with visual differentiation
- Add scrollable control panel with section headers for each layer
- Fix Randomize Settings button: remove explicit width (use flex auto)
  and bump height from 28px to 32px to match other action buttons
- Add mouse-wheel scroll routing for the control panel
- Add 'Randomize Settings' button that randomizes all params within bounds
- Add SystemOrigin enum for per-layer tracking
- Update AGENTS.md with new module layout and plugin pattern
2026-06-09 23:07:55 -04:00

4.2 KiB

apps/game — Bevy/Rust Game Client

Single-player space exploration RPG built with Bevy 0.16. Crate name: void-nav.

This app is independent of the pnpm/TS workspace — no Vite, no React, no Tailwind. It builds with plain cargo from this directory.

Commands

cargo run               # Build + launch the game
cargo check             # Fast typecheck (no codegen)
cargo build             # Build without running
cargo clippy            # Lint
cargo test              # Run unit tests

Module Layout

src/
├── main.rs              # App builder: plugins, state init, system registration
├── state.rs             # AppState enum (MainMenu, Galaxy, CharacterCreation, InGame, Options)
├── camera.rs            # Camera spawn
├── ui/                  # UI screens (menus, HUD, etc.)
│   ├── mod.rs
│   └── main_menu.rs
└── gameplay/            # Non-UI gameplay systems
    ├── mod.rs
    ├── character_creation/   # Character creation scene (skeleton)
    ├── galaxy/              # Procedural galaxy inspection scene
    ├── movement/            # Ship movement (kinematic + orbital)
    ├── physics/             # Physics primitives (mass, gravity, etc.)
    └── star_map/            # Star map data + visualization

When to add a file vs a folder

  • Default: one file per feature (e.g. main_menu.rs).
  • Promote to a folder when the file exceeds ~300 lines, mixes UI + logic + data, or needs shared private helpers.
  • A promoted folder should expose its public API via mod.rs and ideally bundle its systems into a Bevy Plugin (see pattern below).
// src/gameplay/galaxy/mod.rs
pub struct GalaxyPlugin;

impl Plugin for GalaxyPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(OnEnter(AppState::Galaxy), setup_galaxy)
            .add_systems(OnExit(AppState::Galaxy), despawn_galaxy)
            .add_systems(Update, (
                /* update systems */
            ).run_if(in_state(AppState::Galaxy)));
    }
}

Then main.rs collapses to app.add_plugins((..., GalaxyPlugin)).

Naming Conventions

Follows Rust RFC 344. Bevy layers these additional conventions:

Item Convention Example
Files, modules, directories snake_case galaxy, main_menu
Crate name snake_case void-nav
Structs, enums, enum variants UpperCamelCase AppState, Galaxy
Components UpperCamelCase (suffix optional) Player, MainMenuUi
Resources UpperCamelCase ClearColor, Time
States UpperCamelCase + State suffix AppState, GameState
Plugins UpperCamelCase + Plugin suffix GalaxyPlugin
Functions, systems, locals snake_case, verb-first spawn_camera, setup_main_menu
Constants, statics SCREAMING_SNAKE_CASE MAX_HEALTH

Warnings & Errors Policy

Never suppress compiler warnings or errors. This includes but is not limited to:

  • Do not add #[allow(...)] / #[allow(dead_code)] / #[allow(unused)] / #[allow(unused_variables)] or any other lint suppression attribute.
  • Do not prefix unused variables with _ to silence warnings (e.g. _unused_var).
  • Do not use let _ = ... to discard results that might carry meaningful errors.
  • Do not add #[cfg_attr(..., allow(...))] or equivalent conditional suppressions.
  • Do not use #![allow(...)] at the crate or module level.

If a warning or error fires, fix the underlying issue — remove dead code, use the variable, handle the error properly, or restructure the code. Suppressing warnings hides real problems and is not an acceptable fix.

Architecture Notes

  • State machine driven: each AppState variant has its own UI/systems wired via OnEnter / OnExit / Update (latter guarded by in_state).
  • Persistence: SpacetimeDB will be the authoritative backend (via the Rust SDK, not the TS bindings). Not yet wired up.
  • No module_bindings/ here: TS bindings live in the TS workspace and are consumed by the docs prototype.