Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .agents/skills/headless-benchmark/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You run repeatable ZigCraft performance benchmarks without showing a window or s

## Hard Rules

- Always wrap commands in `nix develop --command`.
- Always wrap commands in `devenv shell`.
- Always set a Bash tool timeout longer than the benchmark duration. Never run benchmarks without a timeout.
- Use `zig build benchmark`; it is configured for offscreen graphics rendering and skip-present behavior.
- Use `-Dbenchmark-preset=<preset>` when comparing graphics presets. Valid presets are `low`, `medium`, `high`, `ultra`, and `extreme`.
Expand All @@ -21,39 +21,39 @@ You run repeatable ZigCraft performance benchmarks without showing a window or s
Short smoke benchmark:

```bash
nix develop --command zig build benchmark -Dbenchmark-duration=5 -Dbenchmark-output=zig-out/benchmark-smoke.json
devenv shell zig build benchmark -Dbenchmark-duration=5 -Dbenchmark-output=zig-out/benchmark-smoke.json
```

Recommended Bash timeout: `60000` ms.

Standard benchmark:

```bash
nix develop --command zig build benchmark -Dbenchmark-preset=medium -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-medium.json
devenv shell zig build benchmark -Dbenchmark-preset=medium -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-medium.json
```

Recommended Bash timeout: `120000` ms.

Low preset benchmark:

```bash
nix develop --command zig build benchmark -Dbenchmark-preset=low -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-low.json
devenv shell zig build benchmark -Dbenchmark-preset=low -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-low.json
```

Recommended Bash timeout: `120000` ms.

High preset benchmark:

```bash
nix develop --command zig build benchmark -Dbenchmark-preset=high -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-high.json
devenv shell zig build benchmark -Dbenchmark-preset=high -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-high.json
```

Recommended Bash timeout: `120000` ms.

Release-style benchmark build:

```bash
nix develop --command zig build benchmark -Doptimize=ReleaseFast -Dbenchmark-preset=high -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-high-release.json
devenv shell zig build benchmark -Doptimize=ReleaseFast -Dbenchmark-preset=high -Dbenchmark-duration=60 -Dbenchmark-output=benchmark-high-release.json
```

Recommended Bash timeout: `180000` ms.
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/headless-crash-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You are validating ZigCraft runtime stability in the background without disrupti

## Hard Rules

- Always wrap commands in `nix develop --command`.
- Always wrap commands in `devenv shell`.
- Always set a Bash tool timeout. Never run an open-ended game command without a timeout.
- Prefer `-Dskip-present` for runtime checks. It keeps full offscreen graphics rendering active while hiding the SDL window and skipping presentation.
- Do not use visible monitor-placement flags for crash testing unless the user explicitly asks for a visible window.
Expand All @@ -20,23 +20,23 @@ You are validating ZigCraft runtime stability in the background without disrupti
Use this for a quick startup and world-load crash check:

```bash
nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5
devenv shell zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5
```

Recommended Bash timeout: `30000` ms.

Use this for a longer stability check:

```bash
nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=30
devenv shell zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=30
```

Recommended Bash timeout: `60000` ms.

Use this for the automated smoke mode:

```bash
nix develop --command zig build run -Dskip-present -Dsmoke-test
devenv shell zig build run -Dskip-present -Dsmoke-test
```

Recommended Bash timeout: `60000` ms.
Expand Down
12 changes: 6 additions & 6 deletions .agents/skills/headless-graphics-verification/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You verify graphics-related changes safely in the background using offscreen ren

## Hard Rules

- Always wrap commands in `nix develop --command`.
- Always wrap commands in `devenv shell`.
- Always set Bash tool timeouts for every run command.
- Use `-Dskip-present` for any command that launches the game unless the user explicitly requests a visible window.
- Run `zig build test` for shader validation after shader or graphics code changes.
Expand All @@ -20,39 +20,39 @@ You verify graphics-related changes safely in the background using offscreen ren
Format changed Zig files:

```bash
nix develop --command zig fmt <changed-zig-files>
devenv shell zig fmt <changed-zig-files>
```

Recommended Bash timeout: `120000` ms.

Build offscreen graphics mode:

```bash
nix develop --command zig build -Dskip-present
devenv shell zig build -Dskip-present
```

Recommended Bash timeout: `120000` ms.

Run unit tests and shader validation:

```bash
nix develop --command zig build test
devenv shell zig build test
```

Recommended Bash timeout: `120000` ms.

Run a bounded offscreen world-load check:

```bash
nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5
devenv shell zig build run -Dskip-present -Dauto-world=normal -Dstartup-diagnostic-seconds=5
```

Recommended Bash timeout: `30000` ms.

Run a quick offscreen benchmark if performance may be affected:

```bash
nix develop --command zig build benchmark -Dbenchmark-duration=5 -Dbenchmark-output=zig-out/benchmark-smoke.json
devenv shell zig build benchmark -Dbenchmark-duration=5 -Dbenchmark-output=zig-out/benchmark-smoke.json
```

Recommended Bash timeout: `60000` ms.
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/headless-screenshot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You capture visual output from ZigCraft without opening a visible game window.

## Hard Rules

- Always wrap commands in `nix develop --command`.
- Always wrap commands in `devenv shell`.
- Always set a Bash tool timeout. Screenshot commands can hang if rendering or world loading stalls.
- Always include `-Dskip-present` unless the user explicitly requests a visible capture.
- Use deterministic launch flags where possible (`-Dauto-world=normal`, `-Dshadow-test-scene`, or other existing scenario flags).
Expand All @@ -20,23 +20,23 @@ You capture visual output from ZigCraft without opening a visible game window.
General world screenshot:

```bash
nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dscreenshot-path=screenshots/headless-capture.png -Dscreenshot-frame=120
devenv shell zig build run -Dskip-present -Dauto-world=normal -Dscreenshot-path=screenshots/headless-capture.png -Dscreenshot-frame=120
```

Recommended Bash timeout: `90000` ms.

Delayed capture after world load:

```bash
nix develop --command zig build run -Dskip-present -Dauto-world=normal -Dscreenshot-path=screenshots/headless-capture.png -Dscreenshot-frame=180 -Dscreenshot-delay-seconds=3
devenv shell zig build run -Dskip-present -Dauto-world=normal -Dscreenshot-path=screenshots/headless-capture.png -Dscreenshot-frame=180 -Dscreenshot-delay-seconds=3
```

Recommended Bash timeout: `120000` ms.

Shadow test scene capture:

```bash
nix develop --command zig build run -Dskip-present -Dshadow-test-scene -Dscreenshot-path=screenshots/shadow-test.png -Dscreenshot-frame=180
devenv shell zig build run -Dskip-present -Dshadow-test-scene -Dscreenshot-path=screenshots/shadow-test.png -Dscreenshot-frame=180
```

Recommended Bash timeout: `120000` ms.
Expand Down
28 changes: 14 additions & 14 deletions .agents/skills/test-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ ZigCraft is a high-performance Minecraft-style voxel engine built with:
- **Zig 0.16+** with strict memory management (explicit allocators, defer/errdefer)
- **SDL3** for windowing and input
- **Vulkan** for rendering (only backend, via RHI abstraction)
- **Nix** for reproducible builds (`nix develop --command zig build`)
- **devenv** for reproducible builds (`devenv shell zig build`)
- **GLSL shaders** validated via glslangValidator
- **Custom job system** for multithreaded world generation and meshing

### Build Commands

| Command | Purpose |
|---|---|
| `nix develop --command zig build test` | Unit tests + shader validation |
| `nix develop --command zig fmt src/ modules/` | Format code |
| `nix develop --command zig build test -- --test-filter "test name"` | Verify a specific new test is discovered and runnable |
| `nix develop --command zig build test-integration` | Integration smoke tests for game/graphics/runtime-adjacent changes |
| `nix develop --command zig build -Doptimize=ReleaseFast` | Release build |
| `devenv shell zig build test` | Unit tests + shader validation |
| `devenv shell zig fmt src/ modules/` | Format code |
| `devenv shell zig build test -- --test-filter "test name"` | Verify a specific new test is discovered and runnable |
| `devenv shell zig build test-integration` | Integration smoke tests for game/graphics/runtime-adjacent changes |
| `devenv shell zig build -Doptimize=ReleaseFast` | Release build |

### Project Structure (testing-relevant)

Expand Down Expand Up @@ -198,9 +198,9 @@ You are running inside the opencode GitHub Action. The infrastructure auto-creat

1. Write your test files
2. Register new test files in `src/tests.zig`
3. Format: `nix develop --command zig fmt src/ modules/`
4. Run tests: `nix develop --command zig build test` — ALL tests must pass, not just yours
5. Run at least one new test by filter: `nix develop --command zig build test -- --test-filter "<new test name>"`
3. Format: `devenv shell zig fmt src/ modules/`
4. Run tests: `devenv shell zig build test` — ALL tests must pass, not just yours
5. Run at least one new test by filter: `devenv shell zig build test -- --test-filter "<new test name>"`
6. Self-review the diff and remove any fake, tautological, misleading, or unsafe test before committing
7. Count actual added `test "..."` declarations from your diff and keep the run within 3-8 total new tests
8. Commit your changes with message: `test: add {area} tests for {module}`
Expand All @@ -214,11 +214,11 @@ The infrastructure will push the branch and create the PR automatically.
- Tests MUST pass before committing. This is non-negotiable.
- A filtered run for at least one newly added test MUST pass before committing.
- The new tests MUST be semantically analyzed and executed by `zig build test`; do not rely on registrations that hide test blocks from the test runner.
- Format before commit: `nix develop --command zig fmt src/ modules/`.
- Format before commit: `devenv shell zig fmt src/ modules/`.
- 3-8 tests per run across the whole PR, not per file. Quality over quantity.
- If the module has no testable logic, stop without committing and note limitations.
- Skip if nothing to test — do not create trivial tests just to create a PR.
- For game, graphics, windowing-adjacent, or runtime initialization tests, run `nix develop --command zig build test-integration` when feasible and report if it was not feasible.
- For game, graphics, windowing-adjacent, or runtime initialization tests, run `devenv shell zig build test-integration` when feasible and report if it was not feasible.

## Stop Conditions

Expand Down Expand Up @@ -260,8 +260,8 @@ The PR body should follow this format:
- Functions or paths that still need tests and why

## Verification
- [x] `nix develop --command zig fmt src/ modules/` passes
- [x] `nix develop --command zig build test` passes (all tests, not just new ones)
- [x] `nix develop --command zig build test -- --test-filter "..."` passes for a newly added test
- [x] `devenv shell zig fmt src/ modules/` passes
- [x] `devenv shell zig build test` passes (all tests, not just new ones)
- [x] `devenv shell zig build test -- --test-filter "..."` passes for a newly added test
- [x] No non-test source files were modified
```
7 changes: 7 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

eval "$(devenv direnvrc)"

# Local developers get the full default shell (zls, mesa, weston, kcov).
# CI overrides this with --profile unit or --profile graphics.
use devenv --profile default
4 changes: 2 additions & 2 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ echo "To bypass these checks in an emergency, use: git push --no-verify"
echo ""

echo "[1/2] Checking formatting..."
nix develop --command zig fmt --check src/
devenv shell --profile unit -- zig fmt --check src/

echo "[2/2] Running full test suite..."
nix develop --command zig build test
devenv shell --profile unit -- zig build test

echo ""
echo "=== All pre-push checks passed! ==="
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Setup Nix
description: Install Nix with primary/fallback strategy and restore cache
name: Setup devenv
description: Install Nix (primary/fallback), devenv CLI, and restore the devenv shell cache

inputs:
cache-key-prefix:
description: Prefix for the cache primary key
required: false
default: nix
default: devenv
cache-paths:
description: Paths to cache
required: false
Expand All @@ -14,12 +14,12 @@ inputs:
runs:
using: composite
steps:
- name: Mark Nix setup start
- name: Mark devenv setup start
shell: bash
run: |
START=$(date +%s)
echo "SETUP_NIX_START=$START" >> "$GITHUB_ENV"
echo "Nix setup start: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "devenv setup start: $(date -u +%Y-%m-%dT%H:%M:%SZ)"

- name: Install Nix (primary)
id: nix_install_primary
Expand All @@ -37,21 +37,38 @@ runs:
shell: bash
run: nix --version

# The devenv project publishes prebuilt closures to its own Cachix cache.
# Pulling from it avoids building devenv and its module dependencies.
# Public cache: no authToken needed; skipPush because we only pull.
- name: Configure devenv Cachix cache
uses: cachix/cachix-action@v16
with:
name: devenv
skipPush: true

- name: Install devenv
shell: bash
run: nix profile add nixpkgs#devenv

- name: Verify devenv installation
shell: bash
run: devenv version

- name: Cache Nix Store
continue-on-error: true
uses: nix-community/cache-nix-action@v7
with:
primary-key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('flake.nix', 'flake.lock') }}
primary-key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('devenv.nix', 'devenv.yaml', 'devenv.lock') }}
restore-prefixes-first-match: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-
paths: ${{ inputs.cache-paths }}

- name: Mark Nix setup complete
- name: Mark devenv setup complete
shell: bash
run: |
END=$(date +%s)
START=${SETUP_NIX_START:-$END}
{
echo "### Nix Setup"
echo "### devenv Setup"
echo "- Duration: $((END - START))s"
echo "- Cache key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('flake.nix', 'flake.lock') }}"
echo "- Cache key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('devenv.nix', 'devenv.yaml', 'devenv.lock') }}"
} >> "$GITHUB_STEP_SUMMARY"
8 changes: 8 additions & 0 deletions .github/actions/setup-lavapipe/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ runs:
shell: bash
run: |
set -euo pipefail
# Lavapipe ICD and the Khronos validation layers are resolved from the
# floating nixpkgs-unstable flake registry, matching how dev's CI has
# always resolved them. They are NOT pinned to devenv.lock's nixpkgs:
# the pinned (nixos-unstable) rev does not keep vulkan-validation-layers
# in the binary cache, so pinning forces a from-source build that fails
# (missing git in the sandbox). The integration-test correctness signal
# is governed by the binary's SDL3/vulkan-loader versions, which the
# devenv nixpkgs pin already locks to the pre-migration versions.
LVP_PATH=$(nix build --no-link --print-out-paths nixpkgs#mesa.drivers)/share/vulkan/icd.d/lvp_icd.x86_64.json
LAYER_PATH=$(nix build --no-link --print-out-paths nixpkgs#vulkan-validation-layers)/share/vulkan/explicit_layer.d
{
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/setup-zig-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ runs:
path: |
${{ github.workspace }}/${{ inputs.global-cache-dir }}
${{ github.workspace }}/${{ inputs.local-cache-dir }}
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('build.zig', 'build.zig.zon', 'flake.nix', 'flake.lock') }}-${{ hashFiles('src/**', 'modules/**', 'libs/**', 'assets/shaders/**') }}
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('build.zig', 'build.zig.zon', 'devenv.nix', 'devenv.yaml', 'devenv.lock') }}-${{ hashFiles('src/**', 'modules/**', 'libs/**', 'assets/shaders/**') }}
restore-keys: |
${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('build.zig', 'build.zig.zon', 'flake.nix', 'flake.lock') }}-
${{ inputs.cache-key-prefix }}-${{ runner.os }}-${{ hashFiles('build.zig', 'build.zig.zon', 'devenv.nix', 'devenv.yaml', 'devenv.lock') }}-
${{ inputs.cache-key-prefix }}-${{ runner.os }}-

- name: Summarize Zig cache
Expand Down
12 changes: 6 additions & 6 deletions .github/actions/start-weston/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ name: Start Weston
description: Start a headless Weston compositor and wait for the Wayland socket

inputs:
nix-shell:
devenv-profile:
required: false
default: .#ci-graphics
description: Nix shell containing weston
default: graphics
description: devenv profile containing weston
runtime-dir:
required: false
default: /tmp/runtime-runner
Expand Down Expand Up @@ -46,10 +46,10 @@ runs:
chmod 700 "${{ inputs.runtime-dir }}"
export XDG_RUNTIME_DIR="${{ inputs.runtime-dir }}"

echo "Realizing ${{ inputs.nix-shell }} before starting Weston"
nix develop "${{ inputs.nix-shell }}" --command true
echo "Realizing devenv profile ${{ inputs.devenv-profile }} before starting Weston"
devenv shell --profile "${{ inputs.devenv-profile }}" -- true

nix develop "${{ inputs.nix-shell }}" --command weston \
devenv shell --profile "${{ inputs.devenv-profile }}" -- weston \
--socket="${{ inputs.socket }}" \
--backend=headless-backend.so \
--width=1280 \
Expand Down
Loading
Loading