- Refactor apps/game/src/main.rs into modules: state.rs, camera.rs, ui/, gameplay/ - Add gameplay/galaxy_creation.rs scaffold (stubs only, no new logic) - Update root AGENTS.md: separate TS workspace vs Rust game commands - Update apps/AGENTS.md: docs/game/site use two toolchains, not one - Add apps/game/AGENTS.md: build commands, module layout, naming conventions, Plugin pattern
79 lines
3.2 KiB
Markdown
79 lines
3.2 KiB
Markdown
# apps/game — Bevy/Rust Game Client
|
|
|
|
Single-player space exploration RPG built with [Bevy 0.16](https://bevyengine.org).
|
|
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
|
|
|
|
```bash
|
|
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, GalaxyCreation, 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
|
|
└── galaxy_creation.rs
|
|
```
|
|
|
|
### When to add a file vs a folder
|
|
|
|
- **Default**: one file per feature (e.g. `main_menu.rs`, `galaxy_creation.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).
|
|
|
|
### Plugin pattern (recommended once a folder exists)
|
|
|
|
```rust
|
|
// src/gameplay/galaxy_creation/mod.rs
|
|
pub struct GalaxyCreationPlugin;
|
|
|
|
impl Plugin for GalaxyCreationPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_systems(OnEnter(AppState::GalaxyCreation), setup_galaxy_creation)
|
|
.add_systems(OnExit(AppState::GalaxyCreation), despawn_galaxy_creation)
|
|
.add_systems(Update, (
|
|
/* update systems */
|
|
).run_if(in_state(AppState::GalaxyCreation)));
|
|
}
|
|
}
|
|
```
|
|
|
|
Then `main.rs` collapses to `app.add_plugins((..., GalaxyCreationPlugin))`.
|
|
|
|
## Naming Conventions
|
|
|
|
Follows [Rust RFC 344](https://rust-lang.github.io/api-guidelines/naming.html). Bevy layers these additional conventions:
|
|
|
|
| Item | Convention | Example |
|
|
|---|---|---|
|
|
| Files, modules, directories | `snake_case` | `galaxy_creation.rs`, `main_menu.rs` |
|
|
| Crate name | `snake_case` | `void-nav` |
|
|
| Structs, enums, enum variants | `UpperCamelCase` | `AppState`, `GalaxyCreation` |
|
|
| Components | `UpperCamelCase` (suffix optional) | `Player`, `MainMenuUi` |
|
|
| Resources | `UpperCamelCase` | `ClearColor`, `Time` |
|
|
| States | `UpperCamelCase` + `State` suffix | `AppState`, `GameState` |
|
|
| Plugins | `UpperCamelCase` + `Plugin` suffix | `GalaxyCreationPlugin` |
|
|
| Functions, systems, locals | `snake_case`, verb-first | `spawn_camera`, `setup_main_menu` |
|
|
| Constants, statics | `SCREAMING_SNAKE_CASE` | `MAX_HEALTH` |
|
|
|
|
## 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.
|