Build and web

Native checks feed the public WebAssembly lab.

The pipeline keeps simulator correctness, browser artifacts, and static Pages publishing as separate gates.

Local commands

make

Build the native raylib app.

make test

Run C test binaries for simulation, app, and renderer helpers.

make headless test-core

Build the CSV runner and run physics/app tests without raylib.

make test-build test-cli test-validators

Verify Make dependency/failure behavior, repeatable CSV output and artifact rejection.

make test-sanitize

Run C binaries and CLI cases with address/undefined-behavior sanitizers.

make web

Compile the browser target with Emscripten.

make dist-wasm

Package JS/WASM assets and their revision/checksum manifest.

make docs-assets

Validate and copy the runtime assets into Astro public output.

npm run check --prefix docs

Type-check Astro source before static output.

make docs-check

Check generated routes, base-path-safe assets, navigation, and sitemap completeness after the Astro build.

Build and preview the complete site

Run these commands from the repository root after preparing raylib 6.0 for the web with the same Emscripten SDK. Replace the source path with your checkout. Native raylib object files must be rebuilt for the web platform before reuse.

make PLATFORM=PLATFORM_WEB -C /absolute/path/to/raylib/src
make docs-assets RAYLIB_WEB_SRC=/absolute/path/to/raylib/src
npm ci --prefix docs
npm test --prefix docs
npm run check --prefix docs
npm run build --prefix docs
make docs-check
npm run preview --prefix docs

Open the printed loopback URL under /solar-system-simulator/. Leave PUBLIC_GA_ID unset for local builds. The simulator pair, catalog-orbits.wasm, the learning-lab pair, and build-info.json must all be staged; copying only the main JS/WASM pair leaves the catalog and comparison pages incomplete.

Content-only work can reuse an already validated runtime bundle. After edits, rerun docs tests, type-check, build, and route checks; C changes also require fresh runtime assets. For live editing use npm run dev:background --prefix docs, then dev:status, dev:logs, or dev:stop with the same npm prefix to manage that server.

Artifact checks

tools/check_wasm_artifacts.py confirms the generated solar-system-simulator.js and .wasm files exist, checks the loader/control/export bridge, verifies \0asm\1\0\0\0 WebAssembly header bytes, and matches every artifact to build-info.json checksums and source revision.

Use raylib 6.0, Emscripten 6.0.9, Python 3.10+, and Node 24+ (CI uses Node 26). Point RAYLIB_WEB_SRC at a raylib source directory built for the same Emscripten version. Build-only provenance is regenerated when the revision changes; local uncommitted edits are labeled dirty.

The docs use Astro 7.3.3 and @astrojs/check 0.9.10. TypeScript stays at 6.0.3 because the checker supports TypeScript 5/6, not 7. The lockfile pins the resolved dependency tree.

Emscripten 6 raises its generated-code minimums to Chrome 85, Firefox 79, and Safari 14.1. Those are compiler minimums, not an application-wide tested browser matrix: the simulator needs WebGL and the catalog uses modern browser APIs. Use a current browser for the full lab.

docs/src/pages/simulator.astro owns the browser canvas and shared page layout. docs/src/lib/simulator.ts configures Emscripten before loading its JavaScript, sends control actions through the exported solar_web_command function, and formats live C inspector/playback state. Controls stay disabled until C reports readiness and after fatal loading/runtime failures.

The old /wasm/solar-system-simulator.html URL redirects to /simulator/. Astro renders that compatibility document at build time; the published site remains static.

Older local builds may leave a generated docs/public/wasm/solar-system-simulator.html. Move that legacy file outside docs/public/ before building: Astro gives public files precedence over its redirect endpoint, and make docs-check rejects the stale page.

learning-lab.mjs and learning-lab.wasm serve the graphics-free comparison page using the same C sessions, configuration parser and measurements as the native CLI. Their checksums join the runtime manifest. tools/test_learning_wasm.mjs compares native and WASM outputs for circular, encounter and collision experiments.

GitHub workflows

.github/workflows/build.yml runs on main pushes, pull requests, and manual dispatch. Its native, sanitized, WebAssembly, and Astro lanes include dependency auditing, full offline catalog validation, C/TypeScript catalog comparison, and native/WASM comparison checks. Build uses read-only repository permissions and immutable action/raylib revisions. Only the canonical main build includes configured analytics; the build and checker share that setting.

.github/workflows/deploy-pages.yml accepts only successful same-repository main builds triggered by push or manual dispatch. It downloads that run's already checked Pages tree, verifies runtime provenance, and publishes without rebuilding Astro. Runs for an older main revision are skipped. Deployment retains its narrowly scoped Pages permissions.

.github/workflows/codeql.yml separately scans C/C++, JavaScript/TypeScript, and Actions with security-and-quality queries on main pushes, PRs targeting main, weekly schedules, and manual dispatch. Its C analysis builds both the native app and headless runner.

Pinned Playwright browser tests exercise the built Pages site, including parameter sharing/import, collision identity, a 100-day Phobos challenge, mobile hit targets, SI export invariance and real failed asset fixtures. Run PLAYWRIGHT_CHANNEL=chrome npm run test:browser --prefix docs with installed Chrome. CI installs the pinned Chromium build; sandboxing and TLS validation stay enabled.

Keep documentation source-backed

Page content lives in docs/src/pages/; shared navigation/milestone copy lives in docs/src/lib/site.ts, and the ownership map lives in docs/src/lib/sourceMap.ts. Update related README claims when changing a build, model, or control contract. New canonical routes also belong in docs/public/sitemap.xml and the route checker.

Use make headless followed by node tools/check_catalog.mjs to cross-check core names, kinds, parents, and order. Use python3 tools/small_body_catalog.py --check for the full pinned catalog. Snapshot counts and retrieval dates come from versioned data; an offline audit does not fetch a newer astronomical inventory.