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