Repository navigation
Aura3D 4.2.0
Pre-releaseSuperseded. This version is deprecated. Upgrade to Aura3D 4.7.8.
- Animation Studio no longer calls the retired asset-index worker.
animation-scene cast add --queryandprop add --query, andbuild-clip-library, now resolve from open licence-clear sources at build time throughaura3d assets search(newscripts/open-source-search.ts; the template depends on@aura3d/cli). Accepted files keep the licence and author the provider reported (no more hard-codedCC-BY-4.0), the sha256, rig grading and weight-normalising loader. When nothing matches, the command says so and names the next steps:--file ./rigged.glb/aura3d assets add, or Meshy with--allow-meshy --budget N(opt-in, never a silent fallback to a network endpoint). Cast provenance is nowopen-source-resolvedormeshy-generated; documents that saycatalog-resolvedstill read the same. - Athletes and Links polish: round eyes with a pupil instead of dark bars, one clean waist line and 6 mm hems, smooth normals and matte cloth on the Hoops, Diamond, Links, FC and Red Zone athletes (fit to each shipped model); the Links camera frames the golfer on phones; matte golf cart. Known issue: Diamond bat leaves the hands mid-swing (attach reads the forearm before the procedural arm pose).
- Group B last fixes (layout, material, palette). Gridlock Courier: a phone layout (minimap under the score at the top right, speed readout bottom right, nitro bottom left, so nothing overlaps) and a cleaner hero car: glass, light and underside regions only apply to outward-facing triangles of the double-shell mesh (inner-shell fragments take the body colour) and the paint carries a subtle vertical COLOR_0 gradient. Craterline GP: the phone title screen has a backdrop panel and an anchored tagline, and the track paint is world-space triplanar noise, so there is no directional streak stretch. Serpentine Sky Run: the default runner is a teal suit with silver trim (the orange gi and teal sash are gone), the surge shell is far less solid and the emissive wash is lower so the runner is no longer washed out, and the Slide, Fly and Surge touch buttons are 48 px, high contrast, with a shape icon. Chroma Roll: the start card fits a 390 px viewport. Ion Circuit: the countdown sits at the top centre and the objective card hides while it shows.
- Links, FC and the repainted athletes: stroke counter, bag, cart, faces, hems, kits, referee, camera. The Links stroke counter climbed to about 19 per swing because the swing meter reports
committedon every frame of the downswing;commitStrokenow counts one stroke per shot. The golfer "bag" was a basketball ball rack (now a plain bag) and the golf cart's baked shard atlas is repainted flat.tools/hoops-athlete-retexture/retexture-face.mjsrepaints the 15-joint athletes with clean hems and a flat face (Hoops, Diamond, Links, Red Zone, FC); FC keeps named materials so team tints work, and its skin weights are now smoothed over the whole mesh (triangles past 2x stretch: 750 and 869 down to 140 and 12; worst case 120x down to 5.2x). FC tints shorts, socks and skin per team, the referee is the player body in a yellow and black kit instead of a sci-fi guard model, and the broadcast camera is tighter (9.5 m up, 20 m back, 38 degrees). Verified by unit tests and CPU model renders; in-game frames are software GL where noted inevidence/<game>/rework/play-fix/.
A feature release: the games get real physics, animation and objectives, every game has its own name, render interpolation makes 120 and 144 Hz displays smooth, photographic and brand textures are gone from served assets, and the library gains the kits those fixes needed. It also carries the fixes that were planned as 4.1.4 (Hoops freeze, Cumulus Dash 2x crop, partial first frame, neutral-environment 404, canvas growth, onFrame errors). Everything here was verified on software WebGL2 unless a line says otherwise; none of it is real-GPU evidence.
Fixes
-
Bone attachments follow the final pose of the frame. Overlay poses, IK and procedural bone overrides written after the clip only dirtied local transforms, so
handle.attach/attachToBonesockets andsocket(bone)reads used the clip pose: a held item (the Diamond bat) left the hands as soon as a procedural swing diverged from the clip. The bone lookup now refreshes the actor's world transforms (dirty-tracked) before reading. Test:tests/unit/agent-api/actor-bone-attach-pose-order.test.ts. -
Asset search keeps working when the hosted index is down, and returns relevant models.
aura3d assets searchandresolvenow always run the open zero-auth sources (Khronos samples, Poly Haven, jsDelivr CC0 mirror of Kenney and Quaternius, OS3A) beside the hosted index, so a dead index no longer leaves only the built-in starter pack; texture sets, HDRIs and images are hidden from model queries unless the query asks for a surface or environment; and catalog popularity or screened-hero bonuses no longer rank an asset that matches no query term ("Garbage Truck" no longer appears for "sword"). On 20 realistic prompts, a clearly relevant first result went from 3 (published 4.1.3, which also logsasset-index fetch failed 404) to 13. Also fixes a"polyhaven"vs"poly-haven"adapter id mismatch. Audit and the asset resolution plan:docs/audit/asset-catalog-claim.md,docs/workflows/asset-resolution-plan.md. The hosted index Worker itself is not deployed (see the audit). -
Gridlock Courier: the road no longer goes missing in the first frames.
await app.ready()settles the mount, not the shader programs: programs compile asynchronously and a draw whose program is still compiling is skipped, so the first frame the player saw drew 47 of its 113 draw calls (no road). It is intermittent and not tied to canvas size (three 1440x900 loads were bit-identical; a cold 1280x720 load had no road). NewwarmPrograms(app)in@aura3d/engine/gamesettles the programs, steps a frame so the renderer kicks the exact feature records, settles again, then steps frames until the draw-call count is stable (diagnostics().drawCalls); the port awaits it before it marks itself ready and exposessettle()on its QA hook for captures after a teleport.?warm=0keeps the old behaviour for diagnostics. Regression spec:tests/browser/fixgrid.spec.ts. Every other game that renders right afterready()has the same exposure. Not fixed here: after a long jump the road can still flip in and out of consecutive frames on a loaded software-GL runner (cause not found), and the hypercar still reads as translucent (texture smoothing and a paint override had no measurable effect); both are written up inevidence/drift-and-deliver-port/rework/render-fix/README.md. -
warmProgramsalso waits for a pending environment HDRI (waitForEnvironment,environmentTimeoutMs; the result gainsenvironmentFramesandenvironmentReady). When the HDRI lands every material switches to its image-based-lighting program variant (the diagnostics showedprograms.reusedjump from about 1,500 to 3,000), which dropped frames after a game believed it was settled. -
Fix: with
resize: false, a canvas backing size set after mount no longer leaves the picture in a corner of the buffer. The renderer's viewport and targets were sized from the backing store at mount, so a game that capped its own device pixel ratio afterapp.ready()(Cumulus Dash at 1.5 on a 2x display) drew into 720 of 1080 pixels: the 3D view filled the lower-left two thirds of the frame. The frame loop now forwards a changed backing size to the renderer (authoredBackingResize). Cumulus Dash itself now lets the engine size the canvas (pixelRatiocapped at 1.5, no hand-written resize), so it also follows a window resize, which the pinned inline CSS size used to block. This class of bug is also present in code released as 4.1.3 (Cumulus Dash on any display with a pixel ratio above 1). -
A renderer mount failure that is not strict now prints
RENDERER_MOUNT_FAILEDto the console. One model failing to load (a 404 on a GLB) rejects the whole mount,app.ready()still resolves in non-strict mode, and the page showed a black canvas with only the browser's "Failed to load resource". The text was already inapp.diagnostics().errors; it is now also oneconsole.errorline that says nothing will draw and points atstrict: true. Apex Overdrive, with its/aura-assetsGLBs blocked, reproduces the black canvas; its GLBs are tracked and ship in a clean deploy, so the live site is not affected unless an asset request fails. This behaviour (one failed model blanks every node) is unchanged and is in code released as 4.1.3. -
Fix: a throwing
app.onFramecallback no longer stops the frame loop. The exception used to unwind the render loop, so nothing was drawn again and the page stayed blank (found by the cold-start agent trial: a cube whoseonFramecalledapp.nodes.require("cube")on a node without.runtime({ id, mutable: true })rendered black with 0 draw calls). The error is now caught per callback, reported once asonFrame callback threw: ...(console anddiagnostics().errors), and the other callbacks and later frames keep running. Unit testtests/unit/agent-api/on-frame-errors.test.ts. -
Fix: a canvas beside a HUD no longer grows until nothing draws. The app sizes its canvas to its parent. When the parent is an auto-height
<body>or wrapper that also holds a HUD<div>, every resize grew the parent and so the canvas again, until the backing store passed GPU limits and the frame was black although draws were issued (the cold-start game-loop task, 2 of 3 runs).createParentFitnow detects a write that moves the parent and keeps the mounted size on that axis; parents with a definite size are followed as before. Passingresize: falseis no longer needed as a workaround. Tests:tests/unit/parent-fit. -
Fix: published-package apps no longer request
/aura-environments/neutral.*(a 404 and a console error in every app). The bakedneutralenvironment is embedded in@aura3d/renderingas its own lazily loaded chunk (gzip + base64, decoded withDecompressionStream) and applied with no fetch; other presets still load from/aura-environments. The embedded copy keeps 5 significant mantissa bits on mip 0 (the sharp reflection) and 4 on the blurred mips, which is comparable to the bake's own Monte-Carlo noise (about 1.7% neighbour difference), so the chunk is 141 KB raw (about 100 KB gzip) and not the 703 KB of the first version: the stock cube app is 3,395 kB raw / 1,062 kB gzip against 3,258 / 963 on 4.1.3. Tolerance, enforced per texel intests/unit/environment-embedded: at most half a quantization step against the smallest normalised max-channel mantissa (3.5% of the texel's peak on mip 0, 6.6% on the other mips; mean error under 1.5%). Frames on software GL (two scenes, same build otherwise): Silt & Signal rings differ by 0.074/255 mean absolute (0.04% of pixels by more than 8 levels, max 50, mean luma 76.441 to 76.442); Ninja Runner differs by 0.229/255, the same as two runs of the unchanged build against each other (0.226/255), so it is animation timing, not the environment. Regenerate withnode tools/environments/embed-neutral.mjs. -
Fix: a
material.customfragment that declares its ownprecision highp float;no longer fails to compile. The engine only injected a default precision when the author had none, but its own prelude (uniform float ...) sits before the author's line, so the shader failed withNo precision specified for (float)and the object drew nothing (found by the cold-start water task). The default is now always declared first; a later author declaration still governs their code. Tests:tests/unit/custom-shader-precision. -
Fix:
fetchBytestolerates a response withoutheaders(two HDRI loader tests failed on stubbed fetches).
Games
-
Gridlock Courier: the player car is a new solid hatchback. The old Meshy car was thin overlapping plates with gaps, so the interior showed through whatever material it wore. It is replaced by a freshly generated compact courier hatchback (text prompt only, no marks): one closed shell (0 open edges), 37.5k triangles, 1.8 MB, baked to the port's car convention by
tools/gridlock-courier-bake/bake.mjs; the retexture tool for the old car is retired. Sim, collider and steering are unchanged. -
Links, FC and the repainted athletes: stroke counter, bag, cart, faces, hems, kits, referee, camera. The Links stroke counter climbed to about 19 per swing because the swing meter reports
committedon every frame of the downswing;commitStrokenow counts one stroke per shot. The golfer "bag" was a basketball ball rack (now a plain bag) and the golf cart's baked shard atlas is repainted flat.tools/hoops-athlete-retexture/retexture-face.mjsrepaints the 15-joint athletes with clean hems and a flat face (Hoops, Diamond, Links, Red Zone, FC); FC keeps named materials so team tints work, and its skin weights are now smoothed over the whole mesh (triangles past 2x stretch: 750 and 869 down to 140 and 12; worst case 120x down to 5.2x). FC tints shorts, socks and skin per team, the referee is the player body in a yellow and black kit instead of a sci-fi guard model, and the broadcast camera is tighter (9.5 m up, 20 m back, 38 degrees). Verified by unit tests and CPU model renders; in-game frames are software GL where noted inevidence/<game>/rework/play-fix/. -
Teleoperator, Iron Crown and Cross Hop last fixes (game-rework). Teleoperator's fare card is a compact collapsible bottom sheet on phones (14.8% of the height, 4% collapsed) and its name tags move clear of panels and of each other with a leader line (0 overlaps measured, was up to 2,800 px^2). The robotaxi is repainted into flat region materials with recomputed smooth normals (33.5k triangles, no baked atlas). Iron Crown's fighters Kenji and Mara get flat stylised faces (
tools/iron-crown-restyle/flatface.mjs), and phones show first names on the health plates. Cross Hop gets the shared quick bar with six world buttons. Software-WebGL2 checks only. -
Dot Dash 3D is now Glint Courier, its own game. The arcade-derived maze layouts (Relay Grid, Smelter Rows, Overgrowth) were redrawn and the other boards renamed. The hero is a faceted drone with a spinning ring, the four sentries have distinct silhouettes (cone, cube, ring, saucer), pickups are datachips and surge cells, the bonus items are gems, the palette is a graphite board with amber and cyan traces, and the title, HUD, mode and message wording is new. The 11 unused Meshy models (6.4 MB) and their manifest are removed. The simulation and its rules are unchanged; sounds are still the shared library effects, not new cue-bank parameters.
-
Gridlock Courier: the hero car no longer reads as see-through, and the terrain no longer lies under the road. The hero car's Meshy GLB baked glass, interior and reflections into a shard atlas on a shell with a second layer of inward-facing triangles, so it looked translucent;
tools/gridlock-car-retexture/splits the same mesh by region (body, glass, tyres, rims, lights, underbody) into flat PBR materials: geometry unchanged, 2.46 MB to 1.73 MB, no textures, no credits (car region mean luma 144 against 92 to 94 before; software GL). The model'senvMapIntensityoverride never reached it (it writes the legacy ambient uniform, not the image-based reflection term), so the paint override is gone. The terrain around the road is now a frame around the road square instead of a plane 3 cm under it (hardening against a depth tie; the intermittent road-less first frames were not reproduced with either layout, so their root cause is still open, seeevidence/drift-and-deliver-port/rework/render-fix/README.md). -
Group C visible names and mobile layouts. The Bellkeeper's Walk title card no longer shows the old name; Cumulus Dash drops the inspiration-derived title, chapter name ("Mount Paozu" is now "Cumulus Ridge") and "star orbs" (now "sky pearls"); Apex Overdrive loses a stale "AURA3D 4.0" pill. At 390x844, Duneglide, Saltwind Highway, Lamplight Line and The Bellkeeper's Walk no longer overlap their own HUD panels; Duneglide gets a real results card (time, lamps restored, field notes, impacts, rating). Apex Overdrive now fills the viewport (the canvas had no CSS size and stayed 1280x800), its quick-switcher is a single scrolling row at the top, and the Meshy box truck and carrier are width-fitted to the lane (the box truck was 1.72x wider than its sim width). The Cumulus Dash runner palette changed (teal tunic, gold sash, plum hair) with
tools/kid-goku/recolor-hero.py. Evidence inevidence/<game>/rework/ui-fix/(software WebGL2, not real-GPU). -
Sports games: Diamond, Hoops, Links, Red Zone and FC use the shared quick bar; overlaps fixed. The bar is one sideways-scrolling row (never three or four rows over the scoreboard on a phone) and carries one "Built with Aura3D" credit link; each game's HUD now sits below it. Diamond's strike zone is an outline, not a grey slab over the batter. Red Zone's play-call cards are a compact strip with a collapse toggle, and the sheet is rebuilt only when it changes (it was rebuilt every frame, which could swallow clicks). Hoops' intro message also ends on wall-clock time so it cannot linger on slow frames. Slingshot Siege keeps its own bar but it no longer wraps, and the ammo tray sits above the hint footer.
-
Bunker Zero: the pistol is a pistol, and enemies and pickups keep their textures. The
pistolviewmodel was the pulse-rifle model; a sidearm was generated through Meshy (30 credits, admitted with sha256 and provenance) and a single table (src/weapons-view.ts) now picks the model in hand per weapon, with a test that no two weapons share a model. Seven near-black models (gunner, guard, hound, warden, armor, crate, barrel) get Bunker Zero-local copies with the base-colour atlas lifted (tools/bunker-zero-lift/lift.mjs), and the pickups' full-material replacements are texture-preserving tints. Evidence:evidence/showcase-bunker-zero/rework/content-fix/. -
Duneglide: QA hooks refresh the HUD.
stepFrames,replayandrenderleft the speed readout at its last live value (0 in manual runs while the rider flew at 41 m/s). Live play was already correct. -
Five games: old names and "port" wording gone from the UI, HUD overlaps fixed, scenery stretch and track smear reduced. Chroma Roll's title card, Craterline GP's title screen, Serpentine Sky Run's title text and two taglines no longer name the games they were inspired by. Ion Circuit hides its HUD and countdown behind the title card and wraps its top row under 900 px; Craterline GP's standings list and banner sit below the top row; Chroma Roll's popups start under the HUD and scale to the viewport width; Serpentine Sky Run's distance bar moves to the bottom on phones and the touch buttons hide behind its cards; Shadowstep Gauntlet's forms, abilities and sound pill stack in rows on phones. Meshy houses, towers and gates keep their proportions within about 1.6x (they were stretched up to about 3x, which smeared their textures), and the Craterline GP track's brush streaks are 5:1 instead of 10:1. Software-GL frames only; evidence under
evidence/<game>/rework/ui-fix/. -
Cross Hop: log, lily-pad and stone platforms no longer render near-black, and vehicle textures are 1024 px. The instanced mover pools applied their colour twice (base material colour times per-instance colour, a
#8b5a2blog came out#472c14); they now use a white base like the other pools. The ten vehicle GLBs (cars, tram, train) had three 2048 px textures each: 70 MB became 9.6 MB (tools/asset-optimize/texture-downscale.mjs), the app's assets went from 95 MB to 43 MB, and on software WebGL2 the game is ready in about 22 s instead of about 40 s and runs about 2.9 s per frame instead of about 3.7 s (the rest is software rasterisation; this is not real-GPU data). Evidence:evidence/cross-hop/rework/content-fix/. -
Iron Crown: Kenji and Volt restyled, kit marker slabs removed, stage text made generic. Kenji's baked texture is recoloured by colour family (
tools/iron-crown-restyle/recolor.mjs): white gi to deep teal, red headband to hair, so he no longer reads as a known fighting-game character; Volt goes burgundy and amber. The fighting kit's debug-style nodes (camera safe-zone posts, centre aura beam, start-lane slabs) are replaced by spawn rings.Bangkok Dock Market,Desert AirbaseandHimalayan Monasteryare nowLantern Dock Market,Dustline AirstripandCloudstep Monastery. Evidence:evidence/iron-crown/rework/content-fix/. -
Teleoperator: every vehicle is now an original, generic Meshy-generated design. The Jaguar-style robotaxi with lettering, the Cybercab, Corvette, Cybertruck-style and roadster hero cars and the sedan, SUV, taxi, van, pickup and bus traffic models (photo-style atlases of real vehicles) are replaced by eight generated vehicles (robotaxi, compact hatch, sedan, sports coupe, delivery van, pickup truck, box truck, roadster; 14k to 38k triangles each, about 14.5 MB in total against about 59 MB before). Badges and door marks the generator invented were covered with plain discs, the traffic yaw now matches the new front-facing models, and the traffic sizes and collision footprints follow the new bodies (the box truck replaces the 11.8 m bus at 7.6 m, the hatch replaces the SUV at 3.9 m).
tests/unit/likeness-audit/teleop-vehicles.test.tslocks the manifest hashes, the removal of the old files and a 42k-triangle budget;qaSetYawis a new QA hook for framing a vehicle from every side. The Cable Car is not part of this swap. Evidence, prompts, task ids and credits are inevidence/teleoperator/rework/vehicles/README.md. -
Kid Goku (Cloud Runner): the runner no longer reads as sliding. The Meshy run clip plants a foot at about 3.3 m/s while the sim moves the kid at about 14.5 m/s, and the old playback rate left the feet delivering about 4.7 m/s. Cadence and phase now come from
createLocomotion, a leg-bone overlay widens the swing up to 1.8x, and footstep dust fires on foot touchdowns. Feet are planted up to 10.7 m/s of ground speed; at full sprint about 23% of the ground speed still slides (measured from the clip constants, not rendered bones). Evidence inevidence/kid-goku-beyond-the-clouds-port/rework/. -
Aura Hoops 3D: the game no longer freezes after the first basket, athletes are clean, shots are decided by the physics. The juice hit-stop counted down on game time while frozen game time stands still, so the first made basket or dunk froze the simulation forever (found by a 10-minute remote run: 183 of 186 frames stuck in a dunk, 0-0); it now uses the library
createHitStopon the frame clock. The athlete model's texture atlas tore single triangles across the whole map (shard artefacts, torn hems) and contained a photographic face, lettering and a brand mark; both athletes are re-skinned with a flat palette strip and boundary-subdivided region cuts (tools/hoops-athlete-retexture). Makes and misses come from the library impact kit: a 28-sphere rim ring and glass box resolve a ballistic shot launched with aim error from the release read (3000-shot Monte Carlo: 100% made at a perfect release, 99.3% green, 59% at 0.75, 27% at 0.55; rim rolls, rim misses, banks and airballs all occur); the ball integrates in fixed 1/240 s substeps with a compensated launch. The ball sits on the palm at contact at any speed (median palm-to-ball 0.209 m to 0.110 m), locomotion clips play at ground speed over measured clip speed, idle arms hang nearly straight instead of bowed.@aura3d/debuggainscreateFrameErrorBoundary. Evidence:evidence/aura-hoops-3d/rework/. -
Teleoperator: cars are solid. The player used to drive straight through traffic. Contact now runs through the impact kit (
createImpactWorldin each car's own frame, hit-stop, camera shake, a synthesized hit cue and a spark burst), the speed change comes from the collision (no scripted slow-down), and the ride takes a penalty: comfort rides lose comfort, street rides lose a multiplier step and bounty. Rear-end, head-on and side hits at 8, 16 and 30 m/s each raise exactly one impact with zero penetration (evidence/teleoperator/rework/). The game has no replay, so no reference was regenerated. -
Drift & Deliver no longer stands still on every second frame on 120 and 144 Hz displays. The car, the traffic and the headlight beams are drawn between the last two 60 Hz simulation steps (
createRenderInterpolator), and the chase camera follows that smoothed car. Measured with the real simulation and loop: at 120 Hz the old presentation drew an unchanged car on 479 of 960 frames, now on none. Teleports and wrapped traffic snap instead of smearing. Software-WebGL2 browser check pending; the refresh-rate harness istools/motion-audit/refresh-audit.mts. -
Every game has its own name. The eleven games previously titled as ports now carry unique names (Craterline GP, Chroma Roll, Serpentine Sky Run, Gridlock Courier, Ion Circuit, Shadowstep Gauntlet, Lamplight Line, Saltwind Highway, The Bellkeeper's Walk, Duneglide, Cumulus Dash). Titles, UI, metadata, the index cards and the sitemap no longer say "port", "reconstruction" or name another game; each game shows one neutral "Built with Aura3D" credit. New public URLs are
/apps/<name>/; the old/apps/showcase-<slug>-port/roots redirect (308). Mapping:tools/showcase-port-pages/names.json; record and name screen:docs/workflows/game-names.md. -
Strange Orbit: solid scenery has consequences in zero-G flight. Gate pillars and lintels, rim boulders and spires, the lander and the observatories are now colliders (built from the same frames as the meshes via
examples/strange-orbit-port/obstacles.ts), and a rider flying up under the track bounces instead of passing through. Impacts run through the librarycreateImpactWorld, hit-stop, camera shake and cue; one impact event and one penalised hit per contact (energy -10, combo reset, 1 s cooldown). Measured: 18 surface-and-speed cases and 3 underside cases, one impact each, none passes through (evidence/strange-orbit-port/rework/). Replay references unchanged. -
Serpentine Sky Run no longer shakes on 120 and 144 Hz displays. The 60 Hz simulation stepped the runner, its run cycle and the chase camera on some display frames and not on others, so the runner stood still on every second frame and the rigged runner flipped between its run and idle clips about 1,200 times in 10 seconds. The renderer now blends the last two simulation steps with the game kit's
createRenderInterpolator, the run cycle follows the blended distance, and the procedural fallback runner's pelvis bob is nearly halved. Measured on the real simulation and fixed-step loop (evidence/saiyan-snake-way-port/rework/): per-frame speed variation 1.00 to 0.054 at 120 Hz, camera acceleration 0.48 to 0.0004 m per frame squared, clip flips 1,196 to 0 per 10 seconds. The simulation and its replay are unchanged. -
HEATSINK has something to do: a strike layer on the Time Trial. 16 sentry and heavy drones per lap hover over the road, 12 barrels are now shootable, and the player's existing heat-limited gun fires bolts (
F,Jor click). Kills score with a chain multiplier (x1 to x5, 3 s window), style points for boost pads, checkpoints and pickups, a clean-lap bonus, bronze, silver and gold medals at 16, 30 and 42 kills of 48 (finishing required), a score, multiplier and targets HUD, a stated objective from the countdown, a results screen with medal, accuracy and best chain, bolt tracers, bursts, camera shake and synthesised cues. Additive: the movement replay still matches the original within 1e-6, and the strike replay (reference movement with the gun held down) is pinned by its own hash.examples/heatsink-port/{operation,audio}.ts,tests/unit/heatsink-port/strike.test.ts,tests/browser/heatsink-strike.spec.ts. -
Where the Wind Wanders: the traveller's feet now move at the pace of the ground. The hero animator re-issued
playwith a fresh crossfade and a movingcaptureTimeevery frame, so the clip phase ran 2.4x to 3.8x too fast (planted-foot slide 5.5 u/s against 3.2 u/s of ground speed, ratio 1.72, derived from the recorded commands and the rig's forward kinematics). It now uses the library'screateLocomotion, fed the real ground speed once per sim step with a pinned stride phase and a crossfade only on a gait change: phase rate exact, median slide 0.15 u/s (ratio 0.05). The authored walk clip still skates a little on its own (toe p95 about 0.5 to 0.65 u/s); stride warping or foot IK is the follow-up. Unit tests recompute the gait table fromhero.glband run the library foot-slide meter; evidence and frame strips inevidence/where-the-wind-wanders-port/rework/. Software GL only; real-GPU feel is the owner's to confirm. -
Aura Links 3D: the golfer no longer reads as slanted, and the club head decides the strike. The legs were children of the hips, so the hip hinge rotated them too: at address the thighs leaned 17 degrees and both ankles sat 0.23 m behind the stance, on top of 36.7 degrees of trunk flex. Two-bone leg IK now keeps the ankles planted with the knees bent toward the ball (about 32 degrees of flex), and the spine reads about 28 degrees from the hips with the head over the ball. The ball now launches when the club head's swept path meets it (
game/contact.ts), with a timed fallback so a missed contact can never soft-lock the hole, and the club is attached through the libraryattachToBone. Software-GL frames only; real-GPU look is unchecked. -
Ninja Runner: crates and beams are solid. With the reworked contact rules (default in the game;
?rules=originalkeeps the original's pass-through), an unavoided hit stops the runner, knocks it back (bump 0.55 m, crash 0.95 m past 21.5 m/s) and breaks the obstacle into physical debris (planks bounce, slide and fade); a dash or attack still breaks it cleanly. Feedback runs through the library impact kit (createImpactFeedback,createHitStop,createCameraShake): hit-stop, trauma shake, a tier cue. The original-rules replay is unchanged (tests/unit/ninja-runner-port, 86 tests). -
Aura Diamond 3D: the batter holds the bat, fielders wear gloves, the bat helps decide the hit. The game passed its hand-pose bones as arrays where the engine reads
{ x, y, z, w }objects, so the arms never moved while the bat floated beside him; fixed, with the bat and gloves attached throughattachToBone(a failed attach is now loud, the route-side fallback that put the bat on the ground is deleted). The pitch now reflects about the swinging bat's face (batContact, bounded to 14 and 9 degrees from the timing model), and the swing accelerates into contact instead of stopping there. Software-GL measurements inevidence/aura-diamond-3d/rework/; not real-GPU. -
Aura FC 3D: the players now actually kick, and the doubled legs are gone. Four causes, all measured. (1) The GLBs'
Shootclip is not a kick (the right foot travels 0.28 m at a peak 1 m/s), so the game drove procedural shorts and sock boxes through a real swing beside legs that barely moved: that was the double frame. The boxes and the procedural limb pose are removed; the athlete is one skinned body. (2) NewKickTap/KickPass/KickShotclips are baked into both athlete GLBs with analytic two-bone leg IK (tools/aura-fc/bake-kick.mjs, no new Meshy credits): plant foot fixed (under 1.2 cm drift), boot back, accelerating through the ball, follow-through, boot tip inside the ball radius at the sim's launch fraction. The clip phase is the swing progress (kickT / kickDur), so the boot meets the ball on the exact frame the sim launches it (error under one frame across 95 simulated kicks) and a hit-stop freezes the swing. (3) The default animation path ignoresAuraAnimationSpec.speed, so every clip speed the game set was a no-op and a planted foot slid 0.3 to 1.2 m/s; run cycles now advance with distance travelled (planted-foot slide RMS 0.05 to 0.11 m/s from jog to sprint, 0.14 to 0.35 m/s on the walk clip). (4) The pale slabs and flaps at the hips (the other half of the double-framed look) are bridging triangles the Meshy auto-rig left between body parts that move independently (left thigh to right thigh across the shorts seam, hand to hip); in a kick pose 328 triangles stretched past 3x and some past 100x.tools/aura-fc/skin.mjssoftens the skin weights around them (no geometry removed): across the walk, run, sprint, kick, jump and tackle clips only 21 triangles of the striker (17 of the keeper) stretch past 2x and none past 5x. Sim fixes found on the way: the kicker now turns to face the kick line during the swing (up to 176 degrees off before) and is planted for it; a swing interrupted by a tackle, steal or stun no longer fires later as a phantom pass in a stale direction (seen 7 to 68 s after the swing in every simulated match); the AI no longer starts a swing during the kickoff countdown, where the ball launched a second after the animation ended. New unit teststests/unit/aura-fc-3d/(29), a QA hook (window.__AURA_AURA_FC_3D__:freezeAtKick,step,focusFastest) and a remote filmstrip spectests/browser/rework-fc.spec.ts. Known limits: the shirt colour is a whole-mesh tint (the shorts and socks kit blocks are gone until runtime nodes expose bone sockets); the librarycreateLocomotionis not used because its midpoint clip switching and 0.6 rate clamp slide 3 to 7 times more than the game's switch points on this rig (numbers inlocomotion-sync.test.ts); crosses still use the pass swing.
Likeness and brand
- Borrowed lore renamed at the source in Serpentine Sky Run, Shadowstep Gauntlet and Cumulus Dash; the runtime label masking is gone. The three games no longer hide another game's character, move, item and place names behind
installNeutralLabels(deleted, withapps/showcase-port-shared/neutralLabels.tsand Serpentine'sdisplayTextlayer): every identifier, string, QA hook and test now uses the games' own names (for example Surge, Vital Seed, Grapple Staff, the Serpent Hall, Spirit, Spiral Orb, Beast form, Lantern Village, Sky Pearls, Glider, Cumulus Ridge; QA globals__AURA_SERPENTINE_SKY_RUN__,__AURA_CUMULUS_DASH__,__lanternhold). Behaviour is unchanged: all 247 unit tests of the three games pass and the replays still match the captured original runs, which stay as captured;tests/unit/_support/legacy-names.tsmaps the captured names in tests only, andcourseDigesttakes an optional type-name mapper so the Shadowstep test reproduces the captured digest exactly. Also: hand-typedengineVersionstrings dropped (Hoops, Diamond, Links, Red Zone, Teleoperator), licensed font stacks in FC, Iron Crown and Aura Slam, the Red Zone cup asset key renamedrzChampionCupMeshy,.vercelignorepatterns anchored (same ignore set) plus/evidence/so a clean deploy stays under the file limit, and the game-checks lore list extended. - Likeness and brand cleanup of shared models. The trophy cabinet (framed photographs of people), the rooftop athlete face scans and the Bean Brawl Race yellow bean (a Pikachu-like face) no longer carry those textures: base-colour atlases are softened or the marks painted out, with new hash-named files, updated manifests and content-based tests (
tests/unit/likeness-audit). A texture-by-texture audit of every served GLB is indocs/audit/likeness-brand-audit.md. - Iron Crown: the Crown Arena no longer shows framed photographic portraits. The shared trophy-cabinet model's baked atlas holds small framed photographs of people; the arena now builds its two cabinets from instanced primitives (wood frame, shelves, gold cups, flat crimson banners with gold borders; eight draws) and
tests/unit/likeness-audit/iron-crown-stage-props.test.tsfails if the scanned cabinet, its hash or its bytes come back into the app. The other Iron Crown stage props were scanned for photographs and real marks: only generic signage ("RAMEN") and small panels, no faces or brands found. Evidence:evidence/iron-crown/rework/portraits/. - Athlete models repainted in Diamond, FC, Links and Red Zone (no photographic faces, lettering, crests or brand marks).
diamondAthlete,fcSoccerStrikerMeshy,fcGoalkeeperMeshy,linksGolferAthleteMeshy,rzQuarterbackMeshyandrzDefenderLinemanMeshynow point at flat-colour models painted by body region (same rig and 23 clips, no textures), generated withtools/hoops-athlete-retexture/retexture.mjs(new per-sport config). The eight original athlete GLBs were removed. FC's team tint targets the kit material only.docs/audit/likeness-brand-audit.mdlists what else still ships real marks (Teleoperator vehicles, rooftop face scans, race textures). - Fix: real brand marks and photographic likeness removed from served assets. The six athlete models (Hoops, Diamond, Links, FC, Red Zone) are repainted in flat region colours (no face, lettering, crest or swoosh); the Formula opponent livery and tyre lettering, the Tsukuba circuit logos and a Dunlop arch texture are cleaned; the unused rooftop face-scan GLBs are smeared and their unreferenced duplicates deleted. Geometry is unchanged, so body shapes that replicate real vehicles still need new art (
docs/audit/likeness-brand-audit.md).
Library
clearCameraEyeandcreateCameraClearance(@aura3d/engine/game): a chase camera that does not sit inside scenery. Pulls the eye back along the focus-to-eye line to just before the first solid sample, fast in and slow out. Duneglide uses it with its chapter colliders plus tree, rock and pier columns (trees and rocks have no sim collider, and a camera inside a crown fills the view with it): on the chapter-0 flight the unobstructed chase eye was inside scenery on 153 of 300 sampled steps; with clearance, 3 (all at the 2.5 m minimum distance behind a rider hugging a crown). The eye keeps 1.8 m from colliders, the most the rider's own 1.85 m wall clearance always allows. QA stepping (stepFrames,replay) now cuts the camera to the chase pose instead of easing from its previous pose, so QA frames show the real camera.docs/api/motion-camera-clear.md.summarizeTextureUpgradeandtexturedNodesReady(@aura3d/engine/game): wait for textures before capturing. Textured materials upgrade one at a time after mount, so an early frame, or any frame on a software-rendered runner where each new shader takes tens of seconds, shows plain white models. Saltwind Highway's QA hook now reportstextures(), and its player car is added to the scene first so it is the first model textured (it used to be last: 12 of 15 textures were in by 480 s on SwiftShader and the car was not). No regression: the same pace was measured on the commits from the Meshy art pass through 4.1.3.- One shared quick-switcher bar (
apps/showcase-port-shared/quickbar.css) replaces the per-game bars in Aura Slam, Iron Crown, Pips Big Leap, Dot Dash 3D, Thermal Drift and Bunker Zero. It is a single row that scrolls sideways instead of wrapping to four rows on a phone, reserves its height in--a3d-bar-spaceso HUDs sit below it, and has an opt-in centred pill layout for wide screens. Iron Crown moves its fighter and venue pickers into a toggled panel, Thermal Drift's command bar moves from the bottom of phones to the top and its HUD shrinks to fit, and Teleoperator's fleet dock collapses into one chip with stacked cards on phones. The "AURA3D ENGINE" chip and stale "Aura3D 4.0.x" text are gone from the game UIs, replaced by one "Built with Aura3D" link. - Smooth on 120 and 144 Hz displays:
createFixedStepPresenter,createRecordBlend,runMotionGateandcreateFixedStepLoop().alpha. Additive. A 60 Hz sim drawn without interpolation stood still on every second frame at 120 Hz and flipped animation clips; the presenter draws between the last two steps (replays andstepFramesuntouched), andrunMotionGatefails a game that does not. Defaults ofcreateFixedStepLoopare unchanged. Docs:docs/api/motion-presenter.md. - Motion kit in
@aura3d/engine/game(additive).attachToBone(role-resolved bone sockets with a loudATTACH_BONE_NOT_FOUND),createLocomotionandproceduralLegSwing(stride-synced gaits),createFootSlideMeter(planted-foot drift and legs-not-stepping check),createImpactWorld,createImpactFeedback,createHitStopandcreateCameraShake(swept collision with one event per contact plus hit-stop, shake, cue, particles and damage),smoothDamp,createSmoothFollow3,createRenderInterpolatorandjitterReport, andcheckDoubleFrame.attachToBonebone matching is case-, punctuation- and rig-prefix-insensitive with forearm, upper-arm, shoulder, thigh, shin, foot and hips roles for Mixamo, Meshy, Rigify, Unreal, glTF Avatar and Biped naming, andATTACH_BONE_NOT_FOUNDlists the tried names. Docs:docs/api/motion-*.md. These are pure TypeScript with no DOM, so they run in unit tests and QA hooks. - API:
.position,.rotateand.lookAton scene node builders (and instanced and batched handles) accept an array as well as separate numbers, like.scalealready did (primitives.box().position([1, 2, 3])). The array form was the most common first-draft type error afterapp.cameraandsetUniformbeing optional; the signatures are overloads, so existing calls are unchanged.
Docs and tooling
-
Docs:
docs/agents/recipes.md(complete compiled scenes for the five common tasks) and the.runtime({ id, mutable: true })rule in the quickstart. In the cold-start trial, 8 of 15 runs spent all 40 turns readingdist/without writing a scene; with the recipes the median dropped from 40 to 13 turns (seeevidence/agent-eval/REPORT-after.md). -
Docs: type traps table in
docs/agents/recipes.mdfor the stricttscerrors agents hit on a first draft (app.cameraandsetUniformare optional,translateis on the runtime handle,geometry.definehas nokind,material.customoption shapes). -
Docs: black frame checklist in
docs/agents/troubleshooting.mdand the sized-wrapper advice indocs/agents/recipes.md. -
Tests: three stale test doubles fixed (
prd03-s18c-custom-passes, two cases inprd03-t0-16-statecache-invalidate). Their fake WebGL host lackedlifecycle.bindOutput, whichrunV2LdrTailhas called since 4.0.4; they fail the same way on the commit before the frame-cost change, so they were never a regression of it. -
Tooling: the cold-start scorer scores the forest task on a reduced canvas and frame plan so the 10,000-instance scene completes on software GL.
-
Lessons learned and automated game checks.
docs/agents/lessons-learned.mdcatalogues every mistake from the 4.1.x and 4.2.0 programs (rendering, motion, game design, assets and likeness, naming and copy, build and deploy, verification, agent process) with the API or check that prevents it;docs/agents/new-game-checklist.mdis the one-page pre-flight and acceptance list.node tools/game-checks/run.mjs <game-slug|--all>runs 13 per-game checks (old names and "port" wording, engine chip, own quick bar, canvas size after ready, fixed-step without presenter, hit-stop on frozen time, array bone poses, brand and lore terms, asset sha256, hand-rolled kits, three.js and vendored bundles, runtime text masking, fonts, tracked screenshots) and 3 repo-wide checks (unanchored.vercelignore, hand-typed game counts, Meshy caps). Baseline over the 26 games indocs/audit/game-checks-baseline.md(23 errors, all runtime label masking of borrowed lore in three games; 32 warnings).
Site
- Site and docs: an honest three.js comparison. The homepage comparison and
/docs/aura3d-vs-threejs.htmlare rewritten as a side-by-side with where Aura3D wins (scene source length in 4 of 5 bench scenes, game kit, safety, agent workflow), where three.js wins (7.7x to 8.7x smaller bundle, first frame, frame time, cold-start authoring speed 4 vs 10 median turns, breadth, maturity), ties, when to choose which, what the evidence does not prove, and how each number was measured; every row names its version and caveat (software GL, one author, n). The code panels are the real bench PBR viewer sources (49 vs 24 lines). Unsupported claims are removed from the comparison surfaces:~120 lines vs 18,83% less code,15 / 15,zero-dependency(the engine depends on 15 sibling packages),14 fragile packages.docs/aura3d-vs-threejs.mdis v3 and the capability matrix is v3 (60 rows; row 16 corrected, since cube, array, stereo and chase cameras exist; new rows for the motion kit, render interpolation,warmPrograms, the judge CLI, cold-start authoring and frame cost). - Site claims corrected (marketing, docs, llms files). The unverified "800K+ catalog assets" / "~850K catalog" figure is removed everywhere (homepage stat, docs, llms-full, CLI index label, template comments) and replaced by the counted 652 admitted assets in the repo manifest; "zero-dependency", "MIT licensed" (the repo has no LICENSE file: copy now says MIT is declared in package.json), "WebGPU compute" and several per-game card claims (Aura Slam World Tour, Apex vehicle count, Thermal Drift cannons) are corrected or softened.
marketing/scripts/check-site.mjsnow fails if the homepage packages or admitted-assets stat disagrees with its counted source or the retracted figure returns. Audit:docs/audit/site-claims.md. - The site states the true game count, generated from one inventory.
docs/workflows/game-inventory.json(built bytools/site/gen-game-inventory.mjsfrom the catalog and the routes the production build serves) lists 26 live games and counts the three V2 builds (Thermal Drift, Apex Overdrive, Grid Dispatch) as variants, not extra games. The homepage ("4 playable games", "Fifteen games"), the showcase index, README,llms.txtand the social-card generator read that number instead of hand-typing it,marketing/scripts/check-site.mjsfails when any user-facing file states a different count, and the showcase index is regenerated bytools/site/gen-showcase-index.mjs, grouped by genre with 1x and 2x card images built from the final screenshots (tools/site/build-card-images.mjs).
Known issues
- Teleoperator: every vehicle is now an original generic design, but the hatch, the wagon-style sedan and the van still read as familiar real shapes, and some Meshy-added emblem-like marks are covered by thin plain discs (flat dots up close).
docs/audit/likeness-brand-audit.mdlists live games that still carry content for an owner's review (Aura Clash face textures, Courier vehicle atlases, a trophy name in Red Zone). Name clearance: the new game names have had a web screen only, not trademark clearance. - Gridlock Courier: after a long jump the road can appear in one screenshot and vanish in the next; the first frames that showed no road were not reproduced after the fixes above and the root cause is still open (4.2.0 work).
- All evidence is software WebGL2; none is real-GPU evidence. The legacy post chain still darkens frames with bloom or vignette on (see 4.1.2).