init repo
This commit is contained in:
7
.cargo/config.toml
Normal file
7
.cargo/config.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[alias]
|
||||||
|
r = "run"
|
||||||
|
rr = "run --release --no-default-features"
|
||||||
|
c = "check"
|
||||||
|
t = "test"
|
||||||
|
nt = "nextest run"
|
||||||
|
cl = "clippy --workspace --all-targets --all-features -- -D warnings"
|
||||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
/result
|
||||||
|
.direnv
|
||||||
|
.DS_Store
|
||||||
|
ai/context/*.md
|
||||||
|
ai/context/*.txt
|
||||||
45
.opencode/opencode.json
Normal file
45
.opencode/opencode.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"default_agent": "build",
|
||||||
|
"instructions": [
|
||||||
|
"AGENTS.md",
|
||||||
|
"docs/ai/*.md"
|
||||||
|
],
|
||||||
|
"permission": {
|
||||||
|
"edit": "ask",
|
||||||
|
"bash": "ask",
|
||||||
|
"skill": {
|
||||||
|
"*": "allow"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watcher": {
|
||||||
|
"ignore": [
|
||||||
|
"target/**",
|
||||||
|
".git/**",
|
||||||
|
"ai/context/**"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"snapshot": true,
|
||||||
|
"command": {
|
||||||
|
"context": {
|
||||||
|
"template": "Read @AGENTS.md and @ai/context/project-context.md. Refresh context if stale by running `!./ai/scripts/build-context.sh`. Summarize current architecture, next milestone, and top risks.",
|
||||||
|
"description": "Summarize current Bevy project context",
|
||||||
|
"agent": "plan"
|
||||||
|
},
|
||||||
|
"feature": {
|
||||||
|
"template": "Read @AGENTS.md, @docs/ai/bevy-quick-reference.md, @docs/ai/bevy-project-patterns.md, and @ai/context/project-context.md. Plan and then implement feature: $ARGUMENTS. Before editing, explain files to change, ECS design, and verify commands.",
|
||||||
|
"description": "Plan and implement small Bevy feature",
|
||||||
|
"agent": "build"
|
||||||
|
},
|
||||||
|
"bug": {
|
||||||
|
"template": "Read @AGENTS.md, @docs/ai/bevy-debug-playbook.md, and @ai/context/project-context.md. Investigate and fix: $ARGUMENTS. Show likely root cause, patch plan, and verify commands.",
|
||||||
|
"description": "Fix Bevy bug with root cause first",
|
||||||
|
"agent": "build"
|
||||||
|
},
|
||||||
|
"review": {
|
||||||
|
"template": "Read @AGENTS.md, @docs/ai/bevy-quick-reference.md, @docs/ai/bevy-project-patterns.md, and @ai/context/project-context.md. Review ECS design and architecture for: $ARGUMENTS. Give strengths, risks, concrete refactor steps.",
|
||||||
|
"description": "Review Bevy architecture",
|
||||||
|
"agent": "plan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
.opencode/skills/bevy-architecture/SKILL.md
Normal file
32
.opencode/skills/bevy-architecture/SKILL.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: bevy-architecture
|
||||||
|
description: Review and improve Bevy project structure, plugin boundaries, and feature isolation
|
||||||
|
license: MIT
|
||||||
|
compatibility: opencode
|
||||||
|
metadata:
|
||||||
|
stack: bevy
|
||||||
|
concern: architecture
|
||||||
|
---
|
||||||
|
|
||||||
|
## What I do
|
||||||
|
|
||||||
|
- review plugin boundaries
|
||||||
|
- spot ECS smells
|
||||||
|
- suggest module split
|
||||||
|
- suggest state/event/resource boundaries
|
||||||
|
- keep project workshop-fast
|
||||||
|
|
||||||
|
## Smells to flag
|
||||||
|
|
||||||
|
- giant systems
|
||||||
|
- state hidden in many places
|
||||||
|
- UI mixed with gameplay
|
||||||
|
- direct coupling across features
|
||||||
|
- asset logic spread everywhere
|
||||||
|
|
||||||
|
## Deliverable
|
||||||
|
|
||||||
|
- top strengths
|
||||||
|
- top risks
|
||||||
|
- concrete refactor order
|
||||||
|
- verify commands
|
||||||
31
.opencode/skills/bevy-debug/SKILL.md
Normal file
31
.opencode/skills/bevy-debug/SKILL.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: bevy-debug
|
||||||
|
description: Debug common Bevy runtime, ECS, asset, input, and scheduling problems
|
||||||
|
license: MIT
|
||||||
|
compatibility: opencode
|
||||||
|
metadata:
|
||||||
|
stack: bevy
|
||||||
|
mode: debug
|
||||||
|
---
|
||||||
|
|
||||||
|
## What I do
|
||||||
|
|
||||||
|
- narrow likely root causes
|
||||||
|
- map symptom to file and system
|
||||||
|
- suggest smallest probe first
|
||||||
|
- suggest smallest safe fix
|
||||||
|
- give exact verify commands
|
||||||
|
|
||||||
|
## Use when
|
||||||
|
|
||||||
|
- app opens but scene blank
|
||||||
|
- movement or input broken
|
||||||
|
- UI not updating
|
||||||
|
- panic or borrow conflict appears
|
||||||
|
- schedule/state confusion happens
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- quote exact compiler/runtime error if present
|
||||||
|
- do not jump to big refactor first
|
||||||
|
- check camera, assets, queries, states, and schedules
|
||||||
41
.opencode/skills/bevy-ecs/SKILL.md
Normal file
41
.opencode/skills/bevy-ecs/SKILL.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
name: bevy-ecs
|
||||||
|
description: Design clean Bevy ECS layouts with components, resources, events, systems, and states
|
||||||
|
license: MIT
|
||||||
|
compatibility: opencode
|
||||||
|
metadata:
|
||||||
|
stack: bevy
|
||||||
|
language: rust
|
||||||
|
---
|
||||||
|
|
||||||
|
## What I do
|
||||||
|
|
||||||
|
- turn game idea into ECS parts
|
||||||
|
- split data across components, resources, and events
|
||||||
|
- propose system boundaries
|
||||||
|
- suggest state flow
|
||||||
|
- keep Bevy code idiomatic and small
|
||||||
|
|
||||||
|
## When to use me
|
||||||
|
|
||||||
|
Use when:
|
||||||
|
- new mechanic starts
|
||||||
|
- code feels like one giant system
|
||||||
|
- feature needs plugin split
|
||||||
|
- event vs resource choice unclear
|
||||||
|
|
||||||
|
## Output shape
|
||||||
|
|
||||||
|
1. goal
|
||||||
|
2. ECS map
|
||||||
|
3. file plan
|
||||||
|
4. patch order
|
||||||
|
5. verify commands
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- prefer Bevy built-ins before extra crates
|
||||||
|
- keep `main.rs` thin
|
||||||
|
- prefer events for loose coupling
|
||||||
|
- prefer states for app flow
|
||||||
|
- keep names specific
|
||||||
23
.opencode/skills/bevy-ui/SKILL.md
Normal file
23
.opencode/skills/bevy-ui/SKILL.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: bevy-ui
|
||||||
|
description: Build and debug Bevy UI flows for HUD, score, menus, and state-driven screens
|
||||||
|
license: MIT
|
||||||
|
compatibility: opencode
|
||||||
|
metadata:
|
||||||
|
stack: bevy
|
||||||
|
area: ui
|
||||||
|
---
|
||||||
|
|
||||||
|
## What I do
|
||||||
|
|
||||||
|
- propose HUD/menu structure
|
||||||
|
- map UI state to resources/events/states
|
||||||
|
- keep gameplay logic out of UI systems
|
||||||
|
- suggest update flow for score and status text
|
||||||
|
|
||||||
|
## Use when
|
||||||
|
|
||||||
|
- adding score counter
|
||||||
|
- adding pause/menu/game over screen
|
||||||
|
- fixing stale UI text
|
||||||
|
- separating HUD from gameplay
|
||||||
98
.vscode/tasks.json
vendored
Normal file
98
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "requirements:check (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "bash ./scripts/check-requirements.sh --mode native",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "requirements:check (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "bash ./scripts/check-requirements.sh --mode nix-host && nix develop -c bash ./scripts/check-requirements.sh --mode nix-shell",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build:check (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cargo check",
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build:check (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "nix develop -c cargo check",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build:lint (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cargo fmt --all && cargo check && cargo clippy --workspace --all-targets --all-features -- -D warnings",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build:lint (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "nix develop -c bash -lc 'cargo fmt --all && cargo check && cargo clippy --workspace --all-targets --all-features -- -D warnings'",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "dev:run (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cargo run",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "dev:run (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "nix develop -c cargo run",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "dev:watch (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cargo watch -x run",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "dev:watch (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "nix develop -c cargo watch -x run",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "run:release (native)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cargo run --release --no-default-features",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "run:release (nix)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "nix develop -c cargo run --release --no-default-features",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$rustc"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
AGENTS.md
Normal file
78
AGENTS.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Bevy Game Project Rules
|
||||||
|
|
||||||
|
## Mission
|
||||||
|
|
||||||
|
Build game features fast, but keep code clean enough to survive workshop iteration.
|
||||||
|
Target stack:
|
||||||
|
|
||||||
|
- Rust `1.95.0`
|
||||||
|
- Bevy `0.18.1`
|
||||||
|
- 2D first
|
||||||
|
- local assets in `assets/`
|
||||||
|
|
||||||
|
## Hard rules
|
||||||
|
|
||||||
|
- Use Bevy `0.18.1` APIs only.
|
||||||
|
- Prefer Bevy built-ins before adding third-party crates.
|
||||||
|
- Keep compile loop short. Small steps. Small diffs.
|
||||||
|
- No giant god-systems. Split logic into focused systems and plugins.
|
||||||
|
- Keep rendering, input, gameplay, UI, and debug concerns separate.
|
||||||
|
- New feature must include:
|
||||||
|
- code change
|
||||||
|
- short reason
|
||||||
|
- how to run
|
||||||
|
- what to test manually
|
||||||
|
- After code edits run, in order:
|
||||||
|
1. `cargo fmt --all`
|
||||||
|
2. `cargo check`
|
||||||
|
3. `cargo clippy --workspace --all-targets --all-features -- -D warnings`
|
||||||
|
- If command fails, quote exact error.
|
||||||
|
- Do not migrate versions unless asked.
|
||||||
|
- Do not invent APIs. Check local files first, then docs index in `docs/ai/bevy-source-index.md`.
|
||||||
|
|
||||||
|
## Bevy design rules
|
||||||
|
|
||||||
|
- App setup in `main.rs` stays thin.
|
||||||
|
- Put features in plugins under `src/` when project grows.
|
||||||
|
- Use:
|
||||||
|
- Components for entity data
|
||||||
|
- Resources for singleton state
|
||||||
|
- Events for loose coupling
|
||||||
|
- States for game flow
|
||||||
|
- For temporary prototypes, prefer explicit code over macro cleverness.
|
||||||
|
- Keep startup systems idempotent where possible.
|
||||||
|
- Use `Name` on important entities in debug-heavy scenes.
|
||||||
|
- Asset paths relative to `assets/`.
|
||||||
|
|
||||||
|
## Architecture defaults
|
||||||
|
|
||||||
|
When adding real gameplay, move toward this split:
|
||||||
|
|
||||||
|
- `src/game/` core gameplay plugin
|
||||||
|
- `src/player/` player components + systems
|
||||||
|
- `src/ui/` UI plugin
|
||||||
|
- `src/state/` app/game states
|
||||||
|
- `src/debug/` debug helpers
|
||||||
|
|
||||||
|
## Review checklist
|
||||||
|
|
||||||
|
Before final answer:
|
||||||
|
|
||||||
|
- Is ECS layout sane?
|
||||||
|
- Are system names specific?
|
||||||
|
- Are queries minimal?
|
||||||
|
- Is state transition explicit?
|
||||||
|
- Is UI separate from gameplay?
|
||||||
|
- Are commands deferred only where needed?
|
||||||
|
- Is code Bevy-idiomatic for `0.18.1`?
|
||||||
|
- Did you list exact run/test commands?
|
||||||
|
|
||||||
|
## AI context files
|
||||||
|
|
||||||
|
Read when useful:
|
||||||
|
|
||||||
|
- `docs/ai/bevy-quick-reference.md`
|
||||||
|
- `docs/ai/bevy-project-patterns.md`
|
||||||
|
- `docs/ai/bevy-debug-playbook.md`
|
||||||
|
- `docs/ai/workshop-scope.md`
|
||||||
|
- `ai/context/project-context.md`
|
||||||
164
CLAUDE.md
Normal file
164
CLAUDE.md
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
# Bevy Nix Template - Detailed Dev Guide
|
||||||
|
|
||||||
|
This is the canonical deep guide for newcomers and AI agents working in this repo.
|
||||||
|
|
||||||
|
## Project Snapshot
|
||||||
|
|
||||||
|
- Purpose: minimal Bevy template for fast workshop iteration with optional local AI workflows.
|
||||||
|
- Stack:
|
||||||
|
- Rust `1.95.0` target (via `flake.nix` dev shell)
|
||||||
|
- Bevy `0.18.1`
|
||||||
|
- 2D-first project scope
|
||||||
|
- Current app behavior (`src/main.rs`):
|
||||||
|
- starts Bevy app with a titled 1280x720 window
|
||||||
|
- spawns a single `Camera2d`
|
||||||
|
|
||||||
|
## Canonical File Map
|
||||||
|
|
||||||
|
Authoritative files:
|
||||||
|
|
||||||
|
- `AGENTS.md`: coding and architecture rules for this template.
|
||||||
|
- `Cargo.toml`: Rust package and Bevy dependency configuration.
|
||||||
|
- `flake.nix`: reproducible Nix development environment.
|
||||||
|
- `justfile`: daily dev commands.
|
||||||
|
- `.opencode/opencode.json`: OpenCode command templates and permissions.
|
||||||
|
- `ai/scripts/*.sh`: local context and llama automation scripts.
|
||||||
|
- `docs/ai/*.md`: Bevy design and debugging references.
|
||||||
|
- `src/main.rs`: current game entrypoint.
|
||||||
|
|
||||||
|
Generated files:
|
||||||
|
|
||||||
|
- `ai/context/project-context.md`: generated by `just context` or `./ai/scripts/build-context.sh`.
|
||||||
|
- Do not hand-edit this file.
|
||||||
|
- Regenerate when source/docs change and before context-heavy AI prompts.
|
||||||
|
|
||||||
|
## Setup Paths
|
||||||
|
|
||||||
|
Recommended path (reproducible):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional host-native path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# install rust + tooling yourself, then run
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Run prerequisites checker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash ./scripts/check-requirements.sh --mode native
|
||||||
|
bash ./scripts/check-requirements.sh --mode nix-host
|
||||||
|
nix develop -c bash ./scripts/check-requirements.sh --mode nix-shell
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS, install Xcode Command Line Tools if missing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fast Iteration Workflows
|
||||||
|
|
||||||
|
Native commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run
|
||||||
|
cargo watch -x run
|
||||||
|
cargo fmt --all
|
||||||
|
cargo check
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
Nix-wrapped equivalents:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop -c cargo run
|
||||||
|
nix develop -c cargo watch -x run
|
||||||
|
nix develop -c cargo fmt --all
|
||||||
|
nix develop -c cargo check
|
||||||
|
nix develop -c cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
Just shortcuts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just run
|
||||||
|
just watch
|
||||||
|
just check
|
||||||
|
just lint
|
||||||
|
just test
|
||||||
|
```
|
||||||
|
|
||||||
|
## VS Code Tasks
|
||||||
|
|
||||||
|
Tasks are defined in `.vscode/tasks.json` and cover:
|
||||||
|
|
||||||
|
- requirements checks (native and nix)
|
||||||
|
- build check (native and nix)
|
||||||
|
- lint pipeline (`fmt -> check -> clippy`, native and nix)
|
||||||
|
- dev run/watch (native and nix)
|
||||||
|
- release run with `--no-default-features` (native and nix)
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cmd/Ctrl+Shift+P -> "Tasks: Run Task"
|
||||||
|
```
|
||||||
|
|
||||||
|
## AI Workflows
|
||||||
|
|
||||||
|
Build/update project context:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just context
|
||||||
|
# or
|
||||||
|
./ai/scripts/build-context.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Run local llama flows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export LLAMA_MODEL=/absolute/path/to/model.gguf
|
||||||
|
just ai-chat
|
||||||
|
just ai-plan "add player movement"
|
||||||
|
just ai-fix "camera jitters on move"
|
||||||
|
just ai-review "review ECS plugin split"
|
||||||
|
```
|
||||||
|
|
||||||
|
OpenCode config:
|
||||||
|
|
||||||
|
- Canonical config: `.opencode/opencode.json`
|
||||||
|
- It expects `ai/context/project-context.md` to exist or be refreshed.
|
||||||
|
|
||||||
|
## Verification Workflow
|
||||||
|
|
||||||
|
After Rust code edits, run in this order:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --all
|
||||||
|
cargo check
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
For runtime smoke checks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run
|
||||||
|
cargo watch -x run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- `Could not resolve host: index.crates.io`:
|
||||||
|
- network access is required for first dependency download.
|
||||||
|
- `xcode-select` errors on macOS:
|
||||||
|
- install CLT with `xcode-select --install`.
|
||||||
|
- `llama-cli: command not found`:
|
||||||
|
- install `llama.cpp` tooling or skip local llama commands.
|
||||||
|
- missing `ai/context/project-context.md`:
|
||||||
|
- run `just context` before prompts that read project context.
|
||||||
6069
Cargo.lock
generated
Normal file
6069
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
Cargo.toml
Normal file
20
Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "bevy-template-ai"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy = { version = "0.18.1", features = ["dynamic_linking"] }
|
||||||
|
|
||||||
|
# Fast enough in dev, not awful to iterate.
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
# Shipping profile. No dynamic_linking in release command.
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "thin"
|
||||||
|
strip = "debuginfo"
|
||||||
86
README.md
Normal file
86
README.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Bevy + Local AI Template
|
||||||
|
|
||||||
|
Rust `1.95.0` target. Bevy `0.18.1`.
|
||||||
|
|
||||||
|
Recommended deep guide: [`CLAUDE.md`](./CLAUDE.md)
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
Recommended setup (Nix):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Host-native setup check:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash ./scripts/check-requirements.sh --mode native
|
||||||
|
```
|
||||||
|
|
||||||
|
Nix setup check:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash ./scripts/check-requirements.sh --mode nix-host
|
||||||
|
nix develop -c bash ./scripts/check-requirements.sh --mode nix-shell
|
||||||
|
```
|
||||||
|
|
||||||
|
On macOS, if needed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Daily Loop
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# run game
|
||||||
|
cargo run
|
||||||
|
|
||||||
|
# auto-rebuild + rerun
|
||||||
|
cargo watch -x run
|
||||||
|
|
||||||
|
# required verification order
|
||||||
|
cargo fmt --all
|
||||||
|
cargo check
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
|
# tests
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# refresh generated AI context
|
||||||
|
just context
|
||||||
|
```
|
||||||
|
|
||||||
|
## AI Context and Local Llama
|
||||||
|
|
||||||
|
`ai/context/project-context.md` is generated, not hand-authored.
|
||||||
|
|
||||||
|
Refresh it with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
just context
|
||||||
|
# or
|
||||||
|
./ai/scripts/build-context.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Local llama usage:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export LLAMA_MODEL=/absolute/path/to/model.gguf
|
||||||
|
just ai-chat
|
||||||
|
just ai-plan "add player movement with WASD"
|
||||||
|
just ai-fix "camera jitters when player moves"
|
||||||
|
just ai-review "review ECS layout and plugin split"
|
||||||
|
```
|
||||||
|
|
||||||
|
## VS Code Tasks
|
||||||
|
|
||||||
|
This repo includes `.vscode/tasks.json` for quick iteration:
|
||||||
|
|
||||||
|
- requirements checks (native and nix)
|
||||||
|
- build check (native and nix)
|
||||||
|
- lint (`fmt -> check -> clippy`, native and nix)
|
||||||
|
- run/watch (native and nix)
|
||||||
|
- release run (`--no-default-features`, native and nix)
|
||||||
15
ai/prompts/fix.md
Normal file
15
ai/prompts/fix.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Task type: bug fixing
|
||||||
|
|
||||||
|
Read:
|
||||||
|
- AGENTS.md
|
||||||
|
- docs/ai/bevy-debug-playbook.md
|
||||||
|
- ai/context/project-context.md
|
||||||
|
|
||||||
|
Then:
|
||||||
|
- restate bug
|
||||||
|
- list top 3 likely root causes
|
||||||
|
- point to exact file/section likely involved
|
||||||
|
- propose smallest fix first
|
||||||
|
- show verify commands
|
||||||
|
- if evidence weak, say what to inspect next
|
||||||
|
- keep Bevy 0.18.1 APIs only
|
||||||
16
ai/prompts/plan.md
Normal file
16
ai/prompts/plan.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Task type: feature planning
|
||||||
|
|
||||||
|
Read:
|
||||||
|
- AGENTS.md
|
||||||
|
- docs/ai/bevy-quick-reference.md
|
||||||
|
- docs/ai/bevy-project-patterns.md
|
||||||
|
- ai/context/project-context.md
|
||||||
|
|
||||||
|
Then:
|
||||||
|
- summarize current architecture
|
||||||
|
- propose smallest next milestone
|
||||||
|
- list files to add/edit
|
||||||
|
- sketch ECS design: components, resources, events, states, plugins
|
||||||
|
- give ordered patch steps
|
||||||
|
- give verify commands
|
||||||
|
- keep Bevy 0.18.1 APIs only
|
||||||
16
ai/prompts/review.md
Normal file
16
ai/prompts/review.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Task type: architecture review
|
||||||
|
|
||||||
|
Read:
|
||||||
|
- AGENTS.md
|
||||||
|
- docs/ai/bevy-quick-reference.md
|
||||||
|
- docs/ai/bevy-project-patterns.md
|
||||||
|
- ai/context/project-context.md
|
||||||
|
|
||||||
|
Then:
|
||||||
|
- identify top 3 strengths
|
||||||
|
- identify top 5 risks
|
||||||
|
- call out ECS smells
|
||||||
|
- suggest plugin split
|
||||||
|
- suggest resources/events/states to add or remove
|
||||||
|
- keep advice concrete and patchable
|
||||||
|
- keep Bevy 0.18.1 APIs only
|
||||||
68
ai/scripts/build-context.sh
Executable file
68
ai/scripts/build-context.sh
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
mkdir -p ai/context
|
||||||
|
|
||||||
|
OUT="ai/context/project-context.md"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "# Project Context"
|
||||||
|
echo
|
||||||
|
echo "Generated: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||||
|
echo
|
||||||
|
echo "## Repo Tree"
|
||||||
|
echo
|
||||||
|
echo '```text'
|
||||||
|
if command -v tree >/dev/null 2>&1; then
|
||||||
|
tree -a -I target -I .git
|
||||||
|
else
|
||||||
|
echo "[tree not installed, showing file list fallback]"
|
||||||
|
fd -t f . src docs ai .cargo -E ai/context -E target | sort
|
||||||
|
fi
|
||||||
|
echo '```'
|
||||||
|
echo
|
||||||
|
echo "## Cargo.toml"
|
||||||
|
echo
|
||||||
|
echo '```toml'
|
||||||
|
cat Cargo.toml
|
||||||
|
echo '```'
|
||||||
|
echo
|
||||||
|
echo "## AGENTS.md"
|
||||||
|
echo
|
||||||
|
cat AGENTS.md
|
||||||
|
echo
|
||||||
|
echo "## Source Files"
|
||||||
|
echo
|
||||||
|
while IFS= read -r file; do
|
||||||
|
echo "### ${file}"
|
||||||
|
echo
|
||||||
|
case "${file}" in
|
||||||
|
*.rs)
|
||||||
|
echo '```rust'
|
||||||
|
cat "${file}"
|
||||||
|
echo '```'
|
||||||
|
;;
|
||||||
|
*.toml)
|
||||||
|
echo '```toml'
|
||||||
|
cat "${file}"
|
||||||
|
echo '```'
|
||||||
|
;;
|
||||||
|
*.md)
|
||||||
|
cat "${file}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo '```text'
|
||||||
|
cat "${file}"
|
||||||
|
echo '```'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo
|
||||||
|
done < <(fd -t f . src docs ai .cargo -E ai/context -E target | sort)
|
||||||
|
echo "## TODO / FIXME / HACK"
|
||||||
|
echo
|
||||||
|
echo '```text'
|
||||||
|
rg -n "TODO|FIXME|HACK|BUG" . --glob '!target/**' --glob '!ai/context/**' || true
|
||||||
|
echo '```'
|
||||||
|
} > "${OUT}"
|
||||||
|
|
||||||
|
echo "Wrote ${OUT}"
|
||||||
18
ai/scripts/llama-chat.sh
Executable file
18
ai/scripts/llama-chat.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MODEL="${LLAMA_MODEL:-}"
|
||||||
|
if [ -z "${MODEL}" ]; then
|
||||||
|
echo "error: LLAMA_MODEL not set"
|
||||||
|
echo "export LLAMA_MODEL=/absolute/path/to/model.gguf"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
./ai/scripts/build-context.sh >/dev/null
|
||||||
|
|
||||||
|
exec llama-cli \
|
||||||
|
-m "${MODEL}" \
|
||||||
|
-sysf ai/system-prompt.md \
|
||||||
|
-f ai/context/project-context.md \
|
||||||
|
-cnv \
|
||||||
|
-mli
|
||||||
47
ai/scripts/llama-task.sh
Executable file
47
ai/scripts/llama-task.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MODE="${1:-}"
|
||||||
|
TASK="${2:-}"
|
||||||
|
|
||||||
|
if [ -z "${MODE}" ] || [ -z "${TASK}" ]; then
|
||||||
|
echo "usage: $0 <plan|fix|review> <task text>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
MODEL="${LLAMA_MODEL:-}"
|
||||||
|
if [ -z "${MODEL}" ]; then
|
||||||
|
echo "error: LLAMA_MODEL not set"
|
||||||
|
echo "export LLAMA_MODEL=/absolute/path/to/model.gguf"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${MODE}" in
|
||||||
|
plan|fix|review) ;;
|
||||||
|
*)
|
||||||
|
echo "error: mode must be one of: plan fix review"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
./ai/scripts/build-context.sh >/dev/null
|
||||||
|
|
||||||
|
TMP="$(mktemp)"
|
||||||
|
trap 'rm -f "$TMP"' EXIT
|
||||||
|
|
||||||
|
{
|
||||||
|
cat "ai/prompts/${MODE}.md"
|
||||||
|
echo
|
||||||
|
echo "User task:"
|
||||||
|
echo "${TASK}"
|
||||||
|
echo
|
||||||
|
echo "Project context follows:"
|
||||||
|
echo
|
||||||
|
cat ai/context/project-context.md
|
||||||
|
} > "${TMP}"
|
||||||
|
|
||||||
|
exec llama-cli \
|
||||||
|
-m "${MODEL}" \
|
||||||
|
-sysf ai/system-prompt.md \
|
||||||
|
-f "${TMP}" \
|
||||||
|
-st
|
||||||
34
ai/system-prompt.md
Normal file
34
ai/system-prompt.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
You are local game-dev copilot for Rust + Bevy project.
|
||||||
|
|
||||||
|
Goals:
|
||||||
|
- help build small playable games fast
|
||||||
|
- preserve clean ECS design
|
||||||
|
- keep answers grounded in repo files and local docs
|
||||||
|
- prefer smallest safe next step
|
||||||
|
|
||||||
|
Project facts:
|
||||||
|
- Rust 1.95.0
|
||||||
|
- Bevy 0.18.1
|
||||||
|
- workshop setting
|
||||||
|
- 2D-first scope
|
||||||
|
- assets in ./assets
|
||||||
|
- GIMP exists on host, not in Nix shell
|
||||||
|
|
||||||
|
Behavior:
|
||||||
|
- read project context first if present
|
||||||
|
- propose small diffs
|
||||||
|
- prefer Bevy built-ins before new crates
|
||||||
|
- keep main.rs thin
|
||||||
|
- suggest plugins, resources, events, states when code grows
|
||||||
|
- quote exact commands to run
|
||||||
|
- when fixing bug: identify likely root cause, not symptoms only
|
||||||
|
- when unsure: state uncertainty and list what file or example to inspect next
|
||||||
|
- never invent Bevy APIs
|
||||||
|
- do not upgrade dependencies unless asked
|
||||||
|
|
||||||
|
Response format:
|
||||||
|
1. Goal
|
||||||
|
2. Plan
|
||||||
|
3. Patch sketch
|
||||||
|
4. Verify commands
|
||||||
|
5. Risks
|
||||||
0
assets/.gitkeep
Normal file
0
assets/.gitkeep
Normal file
62
docs/ai/bevy-debug-playbook.md
Normal file
62
docs/ai/bevy-debug-playbook.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Bevy Debug Playbook
|
||||||
|
|
||||||
|
## When build fails
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo check
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
Quote exact compiler error. Fix smallest cause first.
|
||||||
|
|
||||||
|
## When game opens but nothing visible
|
||||||
|
|
||||||
|
Check:
|
||||||
|
|
||||||
|
1. camera spawned?
|
||||||
|
2. entity has render component?
|
||||||
|
3. transform in view?
|
||||||
|
4. asset path correct?
|
||||||
|
5. window created?
|
||||||
|
6. alpha / color not invisible?
|
||||||
|
7. system registered in right schedule/state?
|
||||||
|
|
||||||
|
## When movement broken
|
||||||
|
|
||||||
|
Check:
|
||||||
|
|
||||||
|
- input system runs?
|
||||||
|
- query matches entity?
|
||||||
|
- transform or velocity changed?
|
||||||
|
- another system overwrites transform?
|
||||||
|
- delta time used correctly?
|
||||||
|
|
||||||
|
## When UI broken
|
||||||
|
|
||||||
|
Check:
|
||||||
|
|
||||||
|
- UI entity spawned?
|
||||||
|
- text component updated?
|
||||||
|
- wrong state schedule?
|
||||||
|
- score resource/event exists?
|
||||||
|
- UI and gameplay mixed too tightly?
|
||||||
|
|
||||||
|
## When architecture feels messy
|
||||||
|
|
||||||
|
Refactor by:
|
||||||
|
- extracting plugin
|
||||||
|
- moving singleton data into resource
|
||||||
|
- replacing direct calls with events
|
||||||
|
- introducing state for flow
|
||||||
|
- shrinking system queries
|
||||||
|
|
||||||
|
## Review output format for AI
|
||||||
|
|
||||||
|
When AI reviews code, demand:
|
||||||
|
|
||||||
|
1. top 3 bugs
|
||||||
|
2. top 3 architecture risks
|
||||||
|
3. concrete patch plan
|
||||||
|
4. exact commands to verify
|
||||||
94
docs/ai/bevy-project-patterns.md
Normal file
94
docs/ai/bevy-project-patterns.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# Bevy Project Patterns
|
||||||
|
|
||||||
|
## Start small
|
||||||
|
|
||||||
|
For workshop speed, stay in one crate.
|
||||||
|
When code grows, split by feature modules, not by technical layer only.
|
||||||
|
|
||||||
|
Good early structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/
|
||||||
|
├── main.rs
|
||||||
|
├── player.rs
|
||||||
|
├── ui.rs
|
||||||
|
├── state.rs
|
||||||
|
└── game.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
Later:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/
|
||||||
|
├── main.rs
|
||||||
|
├── game/
|
||||||
|
│ ├── mod.rs
|
||||||
|
│ ├── plugin.rs
|
||||||
|
│ ├── events.rs
|
||||||
|
│ └── state.rs
|
||||||
|
├── player/
|
||||||
|
│ ├── mod.rs
|
||||||
|
│ ├── components.rs
|
||||||
|
│ ├── systems.rs
|
||||||
|
│ └── plugin.rs
|
||||||
|
└── ui/
|
||||||
|
├── mod.rs
|
||||||
|
├── components.rs
|
||||||
|
├── systems.rs
|
||||||
|
└── plugin.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Thin main
|
||||||
|
|
||||||
|
`main.rs` should mostly:
|
||||||
|
|
||||||
|
- create `App`
|
||||||
|
- add plugins
|
||||||
|
- init resources
|
||||||
|
- add states
|
||||||
|
- run
|
||||||
|
|
||||||
|
Business logic lives in feature plugins.
|
||||||
|
|
||||||
|
## Plugin boundaries
|
||||||
|
|
||||||
|
Each plugin should own:
|
||||||
|
|
||||||
|
- components
|
||||||
|
- resources
|
||||||
|
- events
|
||||||
|
- systems
|
||||||
|
- setup hooks
|
||||||
|
|
||||||
|
## Event flow example
|
||||||
|
|
||||||
|
Input system -> movement system -> collision system -> score event -> UI system
|
||||||
|
|
||||||
|
Good because:
|
||||||
|
- no direct UI coupling in gameplay code
|
||||||
|
- each step easy to test and inspect
|
||||||
|
|
||||||
|
## State flow example
|
||||||
|
|
||||||
|
`Loading -> Menu -> Playing -> GameOver`
|
||||||
|
|
||||||
|
Each state should have:
|
||||||
|
- enter setup
|
||||||
|
- update systems
|
||||||
|
- exit cleanup if needed
|
||||||
|
|
||||||
|
## Asset handling
|
||||||
|
|
||||||
|
- keep asset paths stable
|
||||||
|
- store handles in resources or components
|
||||||
|
- preload if startup hitches matter
|
||||||
|
- keep workshop assets tiny and few
|
||||||
|
|
||||||
|
## Debug helpers
|
||||||
|
|
||||||
|
Worth adding early:
|
||||||
|
|
||||||
|
- `Name` components on important entities
|
||||||
|
- debug print on critical events
|
||||||
|
- optional debug plugin
|
||||||
|
- one place for feature flags and tuning constants
|
||||||
112
docs/ai/bevy-quick-reference.md
Normal file
112
docs/ai/bevy-quick-reference.md
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# Bevy Quick Reference
|
||||||
|
|
||||||
|
## Core mental model
|
||||||
|
|
||||||
|
Bevy app = plugins + schedules + systems + ECS data.
|
||||||
|
|
||||||
|
- **Entity**: ID
|
||||||
|
- **Component**: data attached to entity
|
||||||
|
- **System**: function operating on ECS data
|
||||||
|
- **Resource**: singleton global-ish state
|
||||||
|
- **Event**: decoupled message
|
||||||
|
- **State**: app/game phase control
|
||||||
|
- **Plugin**: feature boundary
|
||||||
|
|
||||||
|
## Default 2D startup
|
||||||
|
|
||||||
|
Typical minimum:
|
||||||
|
|
||||||
|
- add `DefaultPlugins`
|
||||||
|
- spawn `Camera2d`
|
||||||
|
- later: sprites, transforms, input systems
|
||||||
|
|
||||||
|
## Good first feature order
|
||||||
|
|
||||||
|
1. camera
|
||||||
|
2. player entity
|
||||||
|
3. movement
|
||||||
|
4. bounds / collision
|
||||||
|
5. score / HUD
|
||||||
|
6. game state
|
||||||
|
7. win / lose loop
|
||||||
|
8. juice: audio, particles, animation
|
||||||
|
|
||||||
|
## ECS rules
|
||||||
|
|
||||||
|
Good:
|
||||||
|
|
||||||
|
- data-only components
|
||||||
|
- small systems
|
||||||
|
- clear queries
|
||||||
|
- events for cross-feature signaling
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
- single mega resource for all state
|
||||||
|
- one system doing input + movement + combat + UI
|
||||||
|
- hidden state mutation in many places
|
||||||
|
- coupling features through direct queries everywhere
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
- `Player`
|
||||||
|
- `Velocity`
|
||||||
|
- `Health`
|
||||||
|
- `Score`
|
||||||
|
- `GameState`
|
||||||
|
- `spawn_player`
|
||||||
|
- `move_player`
|
||||||
|
- `update_score_ui`
|
||||||
|
|
||||||
|
Avoid vague names:
|
||||||
|
|
||||||
|
- `Data`
|
||||||
|
- `Info`
|
||||||
|
- `do_stuff`
|
||||||
|
- `manager`
|
||||||
|
|
||||||
|
## Common patterns
|
||||||
|
|
||||||
|
### Resource pattern
|
||||||
|
Use for global config, score, timers, handles, current run state.
|
||||||
|
|
||||||
|
### Event pattern
|
||||||
|
Use when one system announces and another reacts:
|
||||||
|
- enemy died
|
||||||
|
- score changed
|
||||||
|
- level completed
|
||||||
|
- damage taken
|
||||||
|
|
||||||
|
### State pattern
|
||||||
|
Use for flow:
|
||||||
|
- `Loading`
|
||||||
|
- `Menu`
|
||||||
|
- `Playing`
|
||||||
|
- `Paused`
|
||||||
|
- `GameOver`
|
||||||
|
|
||||||
|
### Plugin pattern
|
||||||
|
Use for feature isolation:
|
||||||
|
- player
|
||||||
|
- UI
|
||||||
|
- combat
|
||||||
|
- level
|
||||||
|
|
||||||
|
## Performance-first habits
|
||||||
|
|
||||||
|
- query only data needed
|
||||||
|
- avoid expensive string churn each frame
|
||||||
|
- keep UI rebuilds scoped
|
||||||
|
- avoid asset reloading loops
|
||||||
|
- prefer change detection / explicit triggers when useful
|
||||||
|
|
||||||
|
## Workshop-safe scope
|
||||||
|
|
||||||
|
Keep small:
|
||||||
|
- one-screen loop
|
||||||
|
- one mechanic
|
||||||
|
- one UI counter
|
||||||
|
- one win/lose condition
|
||||||
|
- one polish pass
|
||||||
34
docs/ai/bevy-source-index.md
Normal file
34
docs/ai/bevy-source-index.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Bevy Source Index
|
||||||
|
|
||||||
|
Use these official sources first.
|
||||||
|
|
||||||
|
## Start here
|
||||||
|
|
||||||
|
- Quick start setup
|
||||||
|
- Learn page
|
||||||
|
- API docs
|
||||||
|
- Official examples
|
||||||
|
- Migration guides
|
||||||
|
- Plugin development page
|
||||||
|
|
||||||
|
## Official URLs
|
||||||
|
|
||||||
|
- https://bevy.org/learn/quick-start/getting-started/setup/
|
||||||
|
- https://bevy.org/learn/
|
||||||
|
- https://docs.rs/bevy
|
||||||
|
- https://github.com/bevyengine/bevy/tree/latest/examples
|
||||||
|
- https://bevy.org/news/bevy-0-18/
|
||||||
|
- https://bevy.org/learn/quick-start/plugin-development/
|
||||||
|
|
||||||
|
## Search order for AI
|
||||||
|
|
||||||
|
1. local project files
|
||||||
|
2. `docs/ai/*.md`
|
||||||
|
3. official examples
|
||||||
|
4. API docs
|
||||||
|
5. migration / release notes
|
||||||
|
|
||||||
|
## Rule
|
||||||
|
|
||||||
|
Do not suggest deprecated Bevy APIs from old blog posts or random tutorials.
|
||||||
|
Match examples to `0.18.1`.
|
||||||
56
docs/ai/workshop-scope.md
Normal file
56
docs/ai/workshop-scope.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Workshop Scope Map
|
||||||
|
|
||||||
|
## Agenda to feature translation
|
||||||
|
|
||||||
|
### Day 1
|
||||||
|
Focus:
|
||||||
|
- Bevy basics
|
||||||
|
- ECS basics
|
||||||
|
- setup
|
||||||
|
- first app
|
||||||
|
|
||||||
|
Project target:
|
||||||
|
- app boots
|
||||||
|
- 2D camera
|
||||||
|
- one visible entity
|
||||||
|
- one moving entity
|
||||||
|
|
||||||
|
### Day 2
|
||||||
|
Focus:
|
||||||
|
- player movement
|
||||||
|
- collision
|
||||||
|
- mechanics
|
||||||
|
- UI
|
||||||
|
- scoring
|
||||||
|
- polish
|
||||||
|
|
||||||
|
Project target:
|
||||||
|
- main loop playable in one room / one screen
|
||||||
|
- score counter
|
||||||
|
- game rule
|
||||||
|
- fail or win condition
|
||||||
|
|
||||||
|
### Day 3
|
||||||
|
Focus:
|
||||||
|
- animation
|
||||||
|
- sound
|
||||||
|
- extended systems
|
||||||
|
- free project work
|
||||||
|
|
||||||
|
Project target:
|
||||||
|
- one polish mechanic
|
||||||
|
- one feedback channel: sound, animation, particles, screen effect
|
||||||
|
- project cleanup
|
||||||
|
- final showcase build
|
||||||
|
|
||||||
|
## Scope kill list
|
||||||
|
|
||||||
|
Cut first if time low:
|
||||||
|
|
||||||
|
- procedural generation
|
||||||
|
- networking
|
||||||
|
- save system
|
||||||
|
- complex AI
|
||||||
|
- plugin rabbit holes
|
||||||
|
- large asset pipelines
|
||||||
|
- ECS over-abstraction
|
||||||
96
flake.lock
generated
Normal file
96
flake.lock
generated
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1776548001,
|
||||||
|
"narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1744536153,
|
||||||
|
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1776827647,
|
||||||
|
"narHash": "sha256-sYixYhp5V8jCajO8TRorE4fzs7IkL4MZdfLTKgkPQBk=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "40e6ccc06e1245a4837cbbd6bdda64e21cc67379",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
104
flake.nix
Normal file
104
flake.nix
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
description = "Bevy + local AI game dev template for macOS with Nix";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [ (import rust-overlay) ];
|
||||||
|
};
|
||||||
|
|
||||||
|
lib = pkgs.lib;
|
||||||
|
|
||||||
|
rustToolchain = pkgs.rust-bin.stable."1.95.0".default.override {
|
||||||
|
extensions = [
|
||||||
|
"rust-src"
|
||||||
|
"rustfmt"
|
||||||
|
"clippy"
|
||||||
|
"rust-analyzer"
|
||||||
|
];
|
||||||
|
targets = [
|
||||||
|
"wasm32-unknown-unknown"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
linuxLibs = lib.optionals pkgs.stdenv.isLinux (with pkgs; [
|
||||||
|
alsa-lib
|
||||||
|
libudev-zero
|
||||||
|
vulkan-loader
|
||||||
|
wayland
|
||||||
|
libxkbcommon
|
||||||
|
xorg.libX11
|
||||||
|
xorg.libXcursor
|
||||||
|
xorg.libXi
|
||||||
|
xorg.libXrandr
|
||||||
|
]);
|
||||||
|
in {
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
rustToolchain
|
||||||
|
pkg-config
|
||||||
|
clang
|
||||||
|
cmake
|
||||||
|
git
|
||||||
|
just
|
||||||
|
bacon
|
||||||
|
cargo-edit
|
||||||
|
cargo-watch
|
||||||
|
cargo-nextest
|
||||||
|
nil
|
||||||
|
nixd
|
||||||
|
taplo
|
||||||
|
imagemagick
|
||||||
|
pngquant
|
||||||
|
ffmpeg
|
||||||
|
jq
|
||||||
|
fd
|
||||||
|
ripgrep
|
||||||
|
tree
|
||||||
|
python3
|
||||||
|
nodejs_22
|
||||||
|
libiconv
|
||||||
|
] ++ linuxLibs;
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export RUST_SRC_PATH="${rustToolchain}/lib/rustlib/src/rust/library"
|
||||||
|
export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib"
|
||||||
|
export CARGO_INCREMENTAL=1
|
||||||
|
export RUST_BACKTRACE=1
|
||||||
|
export BEVY_ASSET_ROOT="$PWD/assets"
|
||||||
|
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
if ! xcode-select -p >/dev/null 2>&1; then
|
||||||
|
echo 'error: Xcode Command Line Tools missing. Run: xcode-select --install'
|
||||||
|
else
|
||||||
|
export SDKROOT="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p assets ai/context
|
||||||
|
|
||||||
|
echo "Bevy + AI shell ready"
|
||||||
|
echo "rustc: $(rustc --version)"
|
||||||
|
echo "cargo: $(cargo --version)"
|
||||||
|
echo "node: $(node --version)"
|
||||||
|
|
||||||
|
# Keep user prompt/plugins by switching interactive sessions to system zsh.
|
||||||
|
# This does not affect `nix develop -c ...` non-interactive commands.
|
||||||
|
if [ -n "''${PS1:-}" ] && [ -z "''${ZSH_VERSION:-}" ] && [ -z "''${IN_NIX_DEVELOP_SYSTEM_ZSH:-}" ] && [ -x /bin/zsh ]; then
|
||||||
|
export IN_NIX_DEVELOP_SYSTEM_ZSH=1
|
||||||
|
export SHELL=/bin/zsh
|
||||||
|
exec /bin/zsh -i
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
44
justfile
Normal file
44
justfile
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
set shell := ["bash", "-euo", "pipefail", "-c"]
|
||||||
|
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
run:
|
||||||
|
cargo run
|
||||||
|
|
||||||
|
watch:
|
||||||
|
cargo watch -x run
|
||||||
|
|
||||||
|
check:
|
||||||
|
cargo check
|
||||||
|
|
||||||
|
test:
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
nextest:
|
||||||
|
cargo nextest run
|
||||||
|
|
||||||
|
lint:
|
||||||
|
cargo fmt --all
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
|
release:
|
||||||
|
cargo run --release --no-default-features
|
||||||
|
|
||||||
|
context:
|
||||||
|
./ai/scripts/build-context.sh
|
||||||
|
|
||||||
|
ai-chat:
|
||||||
|
./ai/scripts/llama-chat.sh
|
||||||
|
|
||||||
|
ai-plan TASK:
|
||||||
|
./ai/scripts/llama-task.sh plan "{{TASK}}"
|
||||||
|
|
||||||
|
ai-fix TASK:
|
||||||
|
./ai/scripts/llama-task.sh fix "{{TASK}}"
|
||||||
|
|
||||||
|
ai-review TASK:
|
||||||
|
./ai/scripts/llama-task.sh review "{{TASK}}"
|
||||||
|
|
||||||
|
tree:
|
||||||
|
tree -a -I target -I .git
|
||||||
176
scripts/check-requirements.sh
Executable file
176
scripts/check-requirements.sh
Executable file
@@ -0,0 +1,176 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MODE="native"
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--mode)
|
||||||
|
MODE="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 --mode <native|nix-host|nix-shell>"
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "${MODE}" ]]; then
|
||||||
|
echo "error: --mode is required"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
OS="$(uname -s)"
|
||||||
|
FAILED=0
|
||||||
|
|
||||||
|
print_install_hint() {
|
||||||
|
local cmd="$1"
|
||||||
|
|
||||||
|
if [[ "${OS}" == "Darwin" ]]; then
|
||||||
|
case "${cmd}" in
|
||||||
|
nix) echo " install: sh <(curl -L https://nixos.org/nix/install) --daemon" ;;
|
||||||
|
cargo|rustc|rustup) echo " install: curl https://sh.rustup.rs -sSf | sh" ;;
|
||||||
|
just) echo " install: brew install just" ;;
|
||||||
|
rg) echo " install: brew install ripgrep" ;;
|
||||||
|
fd) echo " install: brew install fd" ;;
|
||||||
|
tree) echo " install: brew install tree" ;;
|
||||||
|
cargo-watch) echo " install: cargo install cargo-watch" ;;
|
||||||
|
cargo-nextest) echo " install: cargo install cargo-nextest --locked" ;;
|
||||||
|
*) echo " install: use your package manager to install '${cmd}'" ;;
|
||||||
|
esac
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${cmd}" in
|
||||||
|
nix) echo " install: sh <(curl -L https://nixos.org/nix/install) --daemon" ;;
|
||||||
|
cargo|rustc|rustup) echo " install: curl https://sh.rustup.rs -sSf | sh" ;;
|
||||||
|
just) echo " install: sudo apt update && sudo apt install -y just" ;;
|
||||||
|
rg) echo " install: sudo apt update && sudo apt install -y ripgrep" ;;
|
||||||
|
fd) echo " install: sudo apt update && sudo apt install -y fd-find" ;;
|
||||||
|
tree) echo " install: sudo apt update && sudo apt install -y tree" ;;
|
||||||
|
cargo-watch) echo " install: cargo install cargo-watch" ;;
|
||||||
|
cargo-nextest) echo " install: cargo install cargo-nextest --locked" ;;
|
||||||
|
*) echo " install: use your package manager to install '${cmd}'" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
require_cmd() {
|
||||||
|
local cmd="$1"
|
||||||
|
if command -v "${cmd}" >/dev/null 2>&1; then
|
||||||
|
echo "ok: ${cmd}"
|
||||||
|
else
|
||||||
|
echo "missing: ${cmd}"
|
||||||
|
print_install_hint "${cmd}"
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
warn_if_missing() {
|
||||||
|
local cmd="$1"
|
||||||
|
if command -v "${cmd}" >/dev/null 2>&1; then
|
||||||
|
echo "ok(optional): ${cmd}"
|
||||||
|
else
|
||||||
|
echo "missing(optional): ${cmd}"
|
||||||
|
print_install_hint "${cmd}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_xcode_clt() {
|
||||||
|
if [[ "${OS}" != "Darwin" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if xcode-select -p >/dev/null 2>&1; then
|
||||||
|
echo "ok: xcode-command-line-tools"
|
||||||
|
else
|
||||||
|
echo "missing: xcode-command-line-tools"
|
||||||
|
echo " install: xcode-select --install"
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_context_note() {
|
||||||
|
if [[ -f "ai/context/project-context.md" ]]; then
|
||||||
|
echo "ok: ai/context/project-context.md exists (generated file)"
|
||||||
|
else
|
||||||
|
echo "info: ai/context/project-context.md is generated and currently missing"
|
||||||
|
echo " generate with: just context"
|
||||||
|
echo " or: ./ai/scripts/build-context.sh"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_native() {
|
||||||
|
echo "mode: native"
|
||||||
|
require_cmd cargo
|
||||||
|
require_cmd rustc
|
||||||
|
require_cmd just
|
||||||
|
require_cmd rg
|
||||||
|
require_cmd fd
|
||||||
|
require_cmd tree
|
||||||
|
|
||||||
|
if command -v rustup >/dev/null 2>&1; then
|
||||||
|
if rustup component list --installed | rg -q "^rustfmt"; then
|
||||||
|
echo "ok: rustup component rustfmt"
|
||||||
|
else
|
||||||
|
echo "missing: rustup component rustfmt"
|
||||||
|
echo " install: rustup component add rustfmt"
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if rustup component list --installed | rg -q "^clippy"; then
|
||||||
|
echo "ok: rustup component clippy"
|
||||||
|
else
|
||||||
|
echo "missing: rustup component clippy"
|
||||||
|
echo " install: rustup component add clippy"
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "missing: rustup"
|
||||||
|
print_install_hint rustup
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
warn_if_missing cargo-watch
|
||||||
|
warn_if_missing cargo-nextest
|
||||||
|
check_xcode_clt
|
||||||
|
print_context_note
|
||||||
|
}
|
||||||
|
|
||||||
|
check_nix_host() {
|
||||||
|
echo "mode: nix-host"
|
||||||
|
require_cmd nix
|
||||||
|
check_xcode_clt
|
||||||
|
}
|
||||||
|
|
||||||
|
check_nix_shell() {
|
||||||
|
echo "mode: nix-shell"
|
||||||
|
require_cmd cargo
|
||||||
|
require_cmd rustc
|
||||||
|
require_cmd just
|
||||||
|
require_cmd rg
|
||||||
|
require_cmd fd
|
||||||
|
require_cmd tree
|
||||||
|
require_cmd cargo-watch
|
||||||
|
require_cmd cargo-nextest
|
||||||
|
check_xcode_clt
|
||||||
|
print_context_note
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${MODE}" in
|
||||||
|
native) check_native ;;
|
||||||
|
nix-host) check_nix_host ;;
|
||||||
|
nix-shell) check_nix_shell ;;
|
||||||
|
*)
|
||||||
|
echo "error: unknown mode '${MODE}'"
|
||||||
|
echo "usage: $0 --mode <native|nix-host|nix-shell>"
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "${FAILED}" -ne 0 ]]; then
|
||||||
|
echo "requirements check: FAILED"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "requirements check: OK"
|
||||||
19
src/main.rs
Normal file
19
src/main.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||||
|
primary_window: Some(Window {
|
||||||
|
title: "Bevy Template AI".into(),
|
||||||
|
resolution: (1280, 720).into(),
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
..default()
|
||||||
|
}))
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands) {
|
||||||
|
commands.spawn(Camera2d);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user