Skip to content

Releases

v0.91.0

Choose a tag to compare

@marcelocantos marcelocantos released this 01 Aug 07:15
2998ed5

Added

  • Multi-segment hint authoring (🎯T179) — makeContactClip / PhaseTiming / Player(Clip) for continuous multi-waypoint contact with independent approach/stroke/lift/exit timings; stock Kinds route through the same builders
  • Articulating SDF pointing hand (🎯T180) — small motion is finger/wrist, large is body translate, over-reach pivots about the wrist; contact tip stays PointerState.pos; hint.artic_* tweaks

Changed

  • STABILITY snapshot for v0.91.0

Notes

  • Library submodule — pin consumers to this tag; homebrew_tap: disabled
  • 🎯T181 (prebuilts on GitHub Releases) is filed, not shipped in this release
  • Primary modality remains direct ge::run; control plane is spyder

v0.90.0

Choose a tag to compare

@marcelocantos marcelocantos released this 28 Jul 10:04
3b36164

Added

  • Hint-driven synthetic touch input (🎯T177) — ge::hint::InputDriver (<ge/hint_input.h>): a strictly opt-in second consumer of a gesture-hint timeline that converts the same interpolated pointer states the hand renderer draws into synthetic SDL finger events (down/motion/up; pinch = two fingers), injected through the app's production event path. A demo therefore exercises real input handling — a driven tap presses an actual ge::Button, a driven drag rotates an actual GlobeController — with zero game-side correlation code and no drift from the drawn gesture. Synthetic events carry a reserved touch id and finger-id range (isSyntheticFinger) so games can filter consequences; cancel() lifts held fingers cleanly; tag ordering guarantees snapshot-at-contact precedes the input applying. Presentation never implies driving. Demonstrated live in tiltbuggy (HINT=tap HINT_DRIVE=1).
  • ge::spriteFromRgba (🎯T176) — the internal RGBA8→Sprite upload promoted to public API, with the game-thread-only contract documented in one place.

Changed

  • Thread-safe text rasterisation (🎯T176) — architected from FreeType's documented contract: one shared FT_Library with a mutex only around face create/destroy; lock-free glyph rendering on per-call faces; a write-once shared font-bytes cache that FT_New_Memory_Face maps without copying (the FontRef path now reads each font from disk once per process instead of per call). rasterizeTextToPixels is callable from any thread, concurrently — verified by an 8-thread byte-identical concurrency test — and rasterizeText is a thin composition of it plus spriteFromRgba.

Notes

  • 🎯T177's yourworld2 onboarding validation and the 🎯T178 scenario layer (steps, anchors, verdicts, interruption policy, per-sink opt-in coupling) are the tracked follow-ons.

v0.89.0

Choose a tag to compare

@marcelocantos marcelocantos released this 28 Jul 08:24
d3f6c79

Changed

  • Dev-plane session scoping (🎯T175) — everything session-varying in the dev plane is now per-session, completing the 🎯T174 globals-audit campaign tests-first: per-session app-channel stores (state slices, serializers, hit-target extras, time control, perf counters, game-thread task queues) with process-default registrations inherited by every session; stable session ids (Context::sessionId()) advertised in the app-channel hello; dev RPCs address a session with an optional {"session": <id>} (sole-session default); per-session button hit-target registries (dead sessions pruned), cmdstream LiveCapture sinks (hot path unchanged via an engine-bound active cache), SensorControl accel authority, wire-fed viewer-backgrounded bit, and session-tagged metrics::Scope resolution. "Pause" now means one session, and frame_ms means one session's frame time.

Notes

  • Behaviour-preserving by construction: a characterization suite (🎯T175.12) locked every touched surface before surgery and stayed green throughout; 13 new isolation tests prove two sessions hold distinct state. 427/427 unit tests; render goldens unchanged.
  • docs/globals-audit.md is now all-green: every accidental global is fixed, session-addressed, or has a written concurrency decision (sprite frame cursors — safe by serialisation, documented at the commit listener).
  • With 🎯T163's process-per-session architecture these were latent, not live, defects; this release keeps the in-process multi-world option genuinely open. 🎯T176 (FreeType thread safety) remains open.

v0.88.0

Choose a tag to compare

@marcelocantos marcelocantos released this 27 Jul 13:43
76910ba

Changed

  • ge::debug state is per-session (🎯T174) — the debug primitive queues, the debug-draw enable, and the perf HUD config (enable / placement / provider) are now carried by the Context rather than a process-global singleton. The host binds the active session around game callbacks and flush(ctx, …) re-binds from its Context, so a multi-session server keeps each stream's debug content and HUD strip separate. The free-function API is unchanged; direct-mode games behave identically. GPU pipelines and the monospace font remain process-global on the shared sokol device.

Notes

  • Full process-globals audit in docs/globals-audit.md: all 38 statics in src/ classified. Remaining latent multi-session items filed as 🎯T175 (app-channel registries, button hit-target registry, cmdstream LiveCapture, SensorControl, viewer-backgrounded bit, metrics addressing) and 🎯T176 (text.cpp FreeType thread safety). All gate 🎯T163 true multi-session, not current behaviour.
  • Multi-session isolation doctests added; prebuilts recooked for all platforms + debug variants.

v0.87.0

Choose a tag to compare

@marcelocantos marcelocantos released this 27 Jul 13:18
145fd5d

Added

  • Gesture-hint service (🎯T170) — hand-gesture hint animations as an engine service. ge::hint::Player (<ge/hint.h>) compiles tap, double-tap, long-press, swipe, drag, pinch-zoom, and pinch-rotate into keyframed timelines over unit gesture space, with parametric trajectory (Params.from/to), display-rate-continuous motion, and event tags (contact, release, apex, hold-start, pinch-start/end) fired at exact timeline moments. Games consume the pointer states + tags with their own art (data-only tier) or call ge::hint::drawHand (<ge/hint_hand.h>) — a white-fill / black-outline / sticker-halo cartoon hand re-derived every frame from the skeleton as a smooth-min capsule SDF in a fragment shader: fingers blend into the palm, fingertip squashes on contact, the pinch hand scales with fingertip spread, fwidth AA at any zoom, no textures or cooked assets. Look knobs are hint.* Tweaks. Demonstrated both ways in sample/tiltbuggy (HINT=<kind>, HINT_STYLE=ring), locked by 10 new render-test goldens, unit-tested tag timing, verified on desktop Metal and the iOS simulator.
  • Perf HUD strip (🎯T173, engine side) — the dt/fps frame-stats box every ge game rebuilds is now ge::debug machinery with game-supplied segments: hudEnabled/setHudEnabled (independent GE_PERF_HUD latch), imperative per-frame-safe placement (setHudPlacement — four corner anchors + HudAnchor::Custom absolute position), setHudProvider for game segments appended after engine dt/fps, pure doctested hudLabel, translucent backing box for legibility. yourworld2 adopts it in a follow-up (T173 converging).

Notes

  • Prebuilt static libs recooked for all platforms + debug variants; ge_hint shader added to the prebuild cook (kept in sync with Module.mk).
  • Follow-ups filed: 🎯T170.1 (device-pose track — hand-holding-phone tilt hint), 🎯T172 (verify-prebuilds blind to newly added sources).

v0.86.0

Choose a tag to compare

@marcelocantos marcelocantos released this 27 Jul 12:15
f1e96a4

Added

  • App-method advertise: registerMethod(name, handler, exampleParams, doc) — optional discovery metadata rides in hello as mixed methods entries (bare string or {name, example_params?, doc?})
  • Consumer handlers run on the game thread (same as state_query)
  • TiltBuggy sample: reset_pose for spyder app_call

Docs

  • agents-guide: registerMethod + spyder app_methods / app_call loop

Note

Pair with spyder ≥ v0.74.0 for host discovery and generic invoke.

v0.85.0

Choose a tag to compare

@marcelocantos marcelocantos released this 27 Jul 05:34
c8405d1

🎯T169 — cmdstream image-recipe leak (critical)

Every direct-mode ge game leaked ~2.3 MB of native heap per rendered frame: rasterizeText registered a stream-only image recipe unconditionally, copying the full font file per rasterized string into a registry keyed by never-recycled sokol id generations, with no erasure. Changing HUD/clock text produced one registration per frame — 24 GB desktop RSS in ~80 s; foreground lmkd kill on 8 GB Android tablets within minutes.

Fixed

  • Recipe registration is off by default (cmdstream::setImageRecipesEnabled); LiveCapture::begin enables it for the stream/capture path. Direct mode pays nothing — the font file isn't even read.
  • Sprite::destroy now unregisters its image, so an enabled registry mirrors live textures instead of growing per rasterization.
  • Font bytes are cached per path (one copy per font, no per-string disk reads).

Added

  • cmdstream::imageRecipesEnabled / unregisterImage / imageRecipeCount.

Known limitation (T128.2 spike scope): textures created before the first capture arm carry no recipes; the experimental SP2S replay should retro-register or fall back when it graduates.

Verification: yw2 desktop RSS flat over 30 s soaks on both render paths (was ~250 MB/s); 386/386 unit tests.

v0.84.0

Choose a tag to compare

@marcelocantos marcelocantos released this 26 Jul 14:21
272dc06

🎯T168 — Cube-sphere tile pyramid

Globe-scale imagery for consumer games: one nested pack, fully-resident coarse-first loading, device-tier depth cap. Driven by yourworld2's 1 km/px Blue Marble globe.

Added

  • .getp tile-pack format (TilePackFormat.h): per-face quadtree pyramid of compressed tiles, multiple planes per pack (imagery / country-ID / SDF), coarse→fine blob layout with a byte-prefix truncation property — a capped cook is byte-identical to a prefix of the full pack. Frozen on-disk structs; data-breaking to change.
  • bin/ge-texpack cook (ge::cookTilePack): equirectangular master → gnomonic per-face reprojection with supersampled leaf sampling, box-filtered pyramid levels, gutters via continuous face extension, per-tile mips, parallel astcenc. JSON config; plane encodings Astc4x4, R8, and Rg8 (16-bit IDs as lo/hi bytes, for region sets that overflow u8).
  • ge::TilePyramid loader (TilePack.h): fully-resident coarse-first loading — background reader thread, budgeted render-thread upload pump (tilepack.uploads_per_frame tweak), ancestor-fallback resolve(), capped/truncated-pack presence rule, defensive parsing, FAILED-state resource checks.
  • ge::CubeSphere (CubeSphere.h): shared cube-sphere conventions — face basis matching sokol cubemap slice addressing, tile/patch math, tileAncestorRemap, equirect helpers. Pinned by convention-oracle tests.
  • ge::queryDeviceTier (DeviceTier.h): Full / Capped / Legacy texture tier from physical RAM (sysctl / sysinfo) + live ASTC support, mapped to a pyramid load-depth cap. Logged and reported on the app channel.

Changed

  • Apple-silicon macOS Metal now samples ASTC/ETC2/EAC (vendored sokol patch, runtime MTLGPUFamilyApple7 gate) — M-series desktops get dev parity with mobile compressed textures.
  • sg_setup image/view pools raised to 2048/4096 on all backends (tile fleets need more than sokol's 128 default).
  • GeTilePlaneEncoding gains Rg8; .getex (GETX) format unchanged.

Fixed

  • Cook gunzip path uses gunzip -c (BSD zcat demands .Z suffixes on macOS).

Follow-ups filed: 🎯T168.4 (cook band-streaming — whole-image float loading currently peaks ~4× source bytes), 🎯T168.5 (pack size: per-tile mip redundancy, EacR11 SDF encoding).

v0.83.0

Choose a tag to compare

@marcelocantos marcelocantos released this 25 Jul 11:17
b843bc4

Added

  • 🎯T167 compressed-texture pipeline (cook + load)
    • bin/ge-texenc + Module.mk patterns: %.astc.getex / %.etc2.getex / %.png.getex from %.png
    • ge::loadTexture / ge::loadCube — backend-aware encoding pick (ASTC → ETC2 → PNG getex → PNG)
    • Docs in AGENTS.md; path-resolution unit tests

Changed

  • Recooked iOS / Android / web-wasm prebuilts to include texture_load.cpp

v0.82.0

Choose a tag to compare

@marcelocantos marcelocantos released this 25 Jul 05:53
9f13885

Changed

  • SDL3 bumped to release-3.4.12; headers, vendor static libs/xcframeworks, and all platform prebuilts recooked
  • SDL_image build pin aligned to 3.4.4 in build-deps.sh
  • STABILITY snapshot for v0.82.0

Notes

  • Library submodule — pin consumers to this tag; homebrew_tap: disabled
  • Open stream WIP (#178) is not included
  • Primary modality remains direct ge::run; control plane is spyder