Skip to content

feat!: target GocciaScript 0.14.0 and bind the complete raylib API - #11

Merged
frostney merged 1 commit into
mainfrom
t3code/4b7db725
Oct 1, 2026
Merged

frostney merged 1 commit into
mainfrom
t3code/4b7db725

Conversation

@frostney

@frostney frostney commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

The bindings were pinned to GocciaScript 0.10.0, whose FFI could not bind 112 of raylib's 600 functions and forced several workarounds. GocciaScript 0.11–0.14 removed those limits, and 0.14 replaced GocciaScriptLoader and "unsafe-ffi" with GocciaRunner and a deny-by-default permission model, so the 0.10.0 setup no longer runs at all on the current release.

This moves the repository to GocciaScript 0.14.0 and replaces each workaround with the native capability.

What changes for users

  • Complete API. All 600 functions are generated (was 488). Mixed float arguments, more than eight arguments, and variadic calls bind natively; SKIPPED.md is empty.
  • Variadic calls. TraceLog and TextFormat take one typed tail: TextFormat("%s %03d", FFI.varargs(["utf8string", "i32"], ["raylib", 7])).
  • Nullable strings. LoadShader, LoadShaderFromMemory, LoadAutomationEventList and the four text-replacement functions accept string | null. The seven *Raw duplicates are removed.
  • Exact field names. AudioStream.buffer is raylib's field again; nativeBuffer and RAYLIB_FIELD_ALIASES are removed. FFI.metadata(value) returns the backing store.
  • Permissions. Both goccia.json files request ffi in a permissions block. Run GocciaRunner --trust goccia.json once, or pass -P per run. Without the grant the bindings throw a TypeError that names it.
  • Import by name. package.json gains an exports map, so an installed copy is import … from "@frostney/gocciascript-raylib" with allow-import: ["node_modules=."]. Other packaged files stay reachable by subpath.

Breaking

Requires GocciaScript 0.14.0. The *Raw exports, RAYLIB_FIELD_ALIASES and AudioStream.nativeBuffer are gone. GOCCIA_LOADER is now GOCCIA_RUNNER. The package is unpublished and untagged, so the version stays 0.1.0.

Example workarounds removed

Example Before After
Bunnymark instanced quad GenMeshHeightmap on a throwaway 2x2 image, both buffers replaced GenMeshPlane, positions replaced
DOOM 2x scaling zoomed Camera2D DrawTextureEx
Bunnymark imports 27 local alias constants direct imports

Rendering is unchanged: the Bunnymark instanced and DrawTextureV frames are still byte-identical (e22537b0…, the Linux hash already recorded in benchmarks/bunnymark-instancing.md), and DOOM frame 8 is byte-identical before and after on both display paths (2fdda7ef…).

The aliases existed because an imported-binding read cost about 9 µs on 0.10.0; on 0.14.0 it costs about 0.1 µs more than a local read. benchmarks/import-binding-aliases.md records the measurements.

Bunnymark, 10,000 sprites, uncapped, mean of three interleaved 25-frame runs on one machine (Ryzen 9 6900HX, Radeon RX 6600M, Linux). Each side runs its own revision of the example, so this is engine and example together:

Draw path main on 0.10.0 This PR on 0.14.0 Change
DrawMeshInstanced 29.8 FPS 33.8 FPS +13.4%
DrawTextureV 9.9 FPS 10.1 FPS +1.7%

Deliberately kept

  • Goccia.gc() every 10 frames in DOOM: automatic collection is off during bytecode execution, and the heap otherwise grows about 1.7 MB per frame until the memory ceiling.
  • The Node .mjs adapters: GocciaRunner has no host process or hashing API.
  • for...of in the examples.

For the reviewer

  • test:goccia:interpreter was silently running bytecode, because the root config sets "mode": "bytecode". Both scripts now pass --mode.
  • The DOOM subproject has its own goccia.json, which makes it its own project root, so it also requests read access to bindings/raylib.ts.
  • New in the gates: a consumer type-check (tests/types/consumer.ts), an assertion on the package entry point, and make test-palette in CI and the Dockerfile.
  • The window smokes, Bunnymark pixel comparison and DOOM smoke run on Linux only, as before. The macOS lane covers generation, unit, type, ABI, native-call and package checks, including the variadic and mixed-float calls on arm64.

GocciaScript 0.11 to 0.14 lifted the FFI limits the 0.10.0 bindings worked
around, and 0.14 replaced the script loader and the unsafe-ffi switch with
GocciaRunner and a deny-by-default permission model.

- Generate all 600 raylib functions: mixed float arguments, more than eight
  arguments and variadic calls now bind natively.
- Replace the seven Raw raw-pointer variants with FFI.nullable("utf8string")
  and keep AudioStream.buffer under its native name.
- Move both goccia.json files to a permissions block and run every lane
  through GocciaRunner 0.14.0.
- Make the package importable by name through an exports map.
- Drop the example workarounds: Bunnymark uses GenMeshPlane and direct
  imports, DOOM scales with DrawTextureEx. Frames are byte-identical.

BREAKING CHANGE: requires GocciaScript 0.14.0. The Raw exports and
RAYLIB_FIELD_ALIASES are removed, and AudioStream.nativeBuffer is now
AudioStream.buffer.
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: 634d2049-b7b2-436f-b613-824b466cb7d8

📥 Commits

Reviewing files that changed from the base of the PR and between 70a0453 and dfd9cbd.

📒 Files selected for processing (31)
  • .agent/HANDOFF.md
  • .github/workflows/ci.yml
  • .gitignore
  • README.md
  • SKIPPED.json
  • SKIPPED.md
  • benchmarks/import-binding-aliases.md
  • bindings/raylib.d.ts
  • bindings/raylib.ts
  • examples/doom-gpl/Makefile
  • examples/doom-gpl/README.md
  • examples/doom-gpl/goccia.json
  • examples/doom-gpl/src/i_video.ts
  • examples/lib/bunny-instancing.ts
  • examples/lib/run-bunnymark.ts
  • goccia.json
  • metadata/gocciascript.json
  • package.json
  • scripts/generate-bindings.mjs
  • scripts/lib/abi.mjs
  • scripts/lib/bindings.mjs
  • scripts/validate-package.mjs
  • tests/abi/layout-probe.ts
  • tests/fixtures/ffi-smoke.ts
  • tests/integration/abi.test.mjs
  • tests/integration/bunnymark-visual.test.mjs
  • tests/integration/ffi.test.mjs
  • tests/integration/helpers.mjs
  • tests/linux/Dockerfile
  • tests/types/consumer.ts
  • tests/unit/bindings.test.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

Changes

GocciaScript 0.14.0 upgrade

Layer / File(s) Summary
Generator and binding contracts
metadata/gocciascript.json, scripts/lib/bindings.mjs, scripts/generate-bindings.mjs
The generator now supports aggregate metadata, nullable strings, variadic functions, native field names, capability checks, and schema version 2 reports.
Generated Raylib API
bindings/raylib.ts, bindings/raylib.d.ts
The bindings target GocciaScript 0.14.0, expose 600 Raylib functions, add variadic and aggregate contracts, and remove raw nullable-string variants.
Runtime and example migration
.github/workflows/ci.yml, tests/linux/Dockerfile, examples/doom-gpl/*, examples/lib/*, goccia.json, package.json
CI, package permissions, examples, and runner selection now use GocciaScript 0.14.0 and GocciaRunner.
Validation and reports
tests/*, scripts/lib/abi.mjs, scripts/validate-package.mjs, README.md, SKIPPED.*, benchmarks/*, .agent/HANDOFF.md
Tests and ABI probes cover the new binding contracts. Reports, documentation, benchmarks, and handoff notes describe the updated runtime and generated API.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CI
  participant GocciaRunner
  participant RaylibBindings
  participant FFI
  participant Validation
  CI->>GocciaRunner: launch tests with permission flags
  GocciaRunner->>RaylibBindings: load generated bindings
  RaylibBindings->>FFI: bind Raylib functions
  FFI-->>Validation: execute native calls and metadata checks
  Validation-->>CI: report test status
Loading

Merge Risk: ⚪ Minimal · up to dfd9c

The upgrade appears mergeable after normal checks. No actionable incompatibility remains established in the bindings, permission configuration, package exports, or migrated examples.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 17 files. (14 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the GocciaScript 0.14.0 migration, complete raylib API coverage, removed workarounds, permission changes, breaking changes, validation, and performance results.
Title check ✅ Passed The title clearly and concisely identifies the two main changes: targeting GocciaScript 0.14.0 and binding the complete raylib API.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 17 files. (14 skipped: 14 unsupported.)

  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Comment @coderabbitai help to get the list of available commands.

@frostney
frostney marked this pull request as ready for review October 1, 2026 12:21
@frostney
frostney merged commit 3eeab1f into main Oct 1, 2026
3 checks passed
@frostney
frostney deleted the t3code/4b7db725 branch October 1, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant