spawn
playmake
Ctrl+K
sign in
make a game
PlayMake
spawn / aboutwhat we're building

pinned

start herewhat spawn isfaqfrequently asked questionsguidebring a game you already madethe betthe spawn bet

updates

engine v6.0One Place3w agoengine v5.2Lume2mo agoengine v5.1Connection3mo agoengine v5.0For Real3mo agoengine v4.6Atelier4mo agoengine v4.5Surface Tension4mo agoengine v4.4Solid4mo agoengine v4.3Groovy4mo agoengine v4.2Continuum4mo agoengine v4.1Foundations5mo agoengine v0.1Genesis5mo ago

pinned

start herewhat spawn isfaqfrequently asked questionsguidebring a game you already madethe betthe spawn bet

updates

engine v6.0One Place3w agoengine v5.2Lume2mo agoengine v5.1Connection3mo agoengine v5.0For Real3mo agoengine v4.6Atelier4mo agoengine v4.5Surface Tension4mo agoengine v4.4Solid4mo agoengine v4.3Groovy4mo agoengine v4.2Continuum4mo agoengine v4.1Foundations5mo agoengine v0.1Genesis5mo ago
← All posts
← All posts

Engine v5.2.29

August 17, 2026

A patch in the Lume line.

Everything since 5.2.26 in one release: big worlds stop melting down in multiplayer, Savi sees when and why the engine slows something down on purpose, missing and ghost objects repair themselves, and script math is exact again.

what's new

  • Big long-lived worlds no longer melt down in multiplayer. When a world grew past an internal size ceiling, joins behind the scenes failed over and over — each attempt paying a huge download — and all that churn kept disconnecting the actual players, resetting them to spawn and timing out saves. Those joins are now as cheap as a player's, and when something does fail to join, it retries politely instead of hammering the room.
  • Savi's helpers now enter big worlds the cheap way players do. Instead of downloading the entire world just to get in the door, they join instantly with the essentials and stream the rest in behind the scenes — so a large world's helper shows up in seconds instead of paying a giant download at the doorstep.
  • A player whose game freezes for a while (heavy tab, background throttle, giant world load) now snaps to the room's CURRENT state when it thaws, instead of replaying minutes of stale multiplayer history — a window during which their client silently dropped other players' actions.
  • Remote players and NPCs recover to their live positions faster when a busy room backs up. When chat and world updates interleave with movement, a slow device now skips straight to each mover's latest pose instead of replaying a backlog of stale ones.
  • Bots and props no longer freeze or snap backwards for some players when players come and go. Players whose view of the room was a beat behind used to lose the latest bot and prop updates at that moment — now those updates are kept and applied, so everyone sees the same world through the change.
  • Saves and loads that run when a player joins no longer fail during the room's first moments. Every boot had a short window where the room was still connecting; a script reading its saved data there got errors and fell back to defaults, and saved terrain edits waited on a retry instead of loading cleanly. The engine now holds those reads until the connection is ready and runs them immediately — and if the room genuinely can't connect within 30 seconds, the script gets one honest error saying the call was never sent, so retrying it is safe.
  • When the engine slows something down on purpose, Savi can now see exactly what and why. If the engine parks heavy shader work to keep a session playable, that shows up as a named fact — which safeguard engaged, how much it's holding, since when, and whether it will come back on its own — so "why does my game look different on that phone" gets a straight answer instead of a mystery hunt.
  • Five more engine safeguards now explain themselves instead of looking like bugs. When a game runs slow because the device can't keep up (dropped sim ticks), when multiplayer movement snaps to the latest position under backlog, when terrain is slow to build on an overloaded device, when a run_script times out, or when textures unload under memory pressure — each now shows up in Savi's health check as a named fact with the real cause. The run_script one matters most: a timeout on an overloaded machine now says the machine was overloaded and your script is not proven at fault, instead of wrongly blaming your code for a busy loop.
  • A UI whose script library outgrows the mount budget now tells you, instead of silently keeping the old UI alive. If your ui.js and the modules it requires grow past the UI size cap, you get one loud fault naming the measured size and the budget, the receipts read "mount dropped over cap" instead of "sent", and trimming or merging lib modules re-mounts immediately — no dummy edit needed. The module-count ceiling also rose 256 → 4096, so the byte budget is what governs.
  • Clearer answer when a script destroys a generated piece of a wall or road. Fences, walls, and roads generate their segments automatically; those segments disappear (and come back) with their parent. When a script tries to destroy one that's already gone, the engine now explains that instead of guessing the script used a wrong id format.
  • Scripts that touch an object living in another area now get told exactly that. Writing to an entity that lives in a different place used to fail with a generic "not found" that read like a typo; now the error names the entity's real place and states the rule — writes only apply within the calling place — so you stop hunting for id typos that aren't there.
  • Animation channels playing your authored clips now report how long they run. getChannel().duration used to read null forever for authored clips — finished never fired and progress sat at 0 — so scripts couldn't sequence off a clip's end. All three now answer from the clip's own minted timing; a duration you set by hand still wins.
  • Model references pasted as bare upload filenames now just load. A ref like public.aHR0….glb (the canonical import filename without the /cdn/ prefix) used to sit as a permanent placeholder while the scene note claimed the model had been declared dead. It now loads the model it names — and references that genuinely can't resolve say so honestly: "no request was ever made", never a fabricated death verdict.
  • Savi can see broken shaders, looks, and script errors in multiplayer worlds again. When a look, material, or texture script fails on someone's screen in a multiplayer room, Savi now gets the actual error (in her logs and as a heads-up message) instead of nothing — so she fixes your one-line bug instead of chasing a phantom engine problem.
  • Savi can no longer mistake a silently frozen game tab for the live world. When a tab's connection looks alive but has stopped receiving updates, her scene captures now carry the world version they were rendered from, so she says "your tab is showing an old version — reload to catch up" instead of describing the stale frame as current and rebuilding things that already exist.
  • A silently frozen game tab now heals itself instead of gaslighting the session. When a tab's world stops updating while its connection looks alive (the "everything I ask Savi to build never shows up" freeze), Savi's tools now detect the frozen version, save a diagnostic snapshot of the tab, and quietly direct it to re-sync — or, if that fails, to rebuild its game session in place — instead of describing a stale world as current and rebuilding things that already exist.
  • Objects stop silently going missing — and destroyed ones stop haunting the screen. When a create, destroy, look change, or effect got lost on the way to a player's screen, that player used to see a permanently stale world until they reloaded: new buildings invisible, destroyed enemies still drawn, finished effects fogging the screen forever. The engine now compares what the screen holds against what the game says exists, every second, and repairs exactly the difference within a few seconds — both directions, without touching anything that's healthy.
  • Edits and heals now stick in empty rooms: when Savi (or you) fixes an object and saves, the fix survives everyone leaving and coming back — the room no longer resurrects the object's old position or state from stale multiplayer history at the next join.
  • api.getPlayers() can no longer be broken by tag writes. A script that overwrites or wipes a player's tags used to make that player vanish from getPlayers() (while they kept playing, visibly in the world) — and a non-player session body mis-tagged "player" could show up in rosters and counts. Player enumeration now reads the platform's own record of who each session is, so getPlayers() always returns exactly the connected players — whatever your scripts do to tags. tags: ["player"] queries still work exactly as before for your own gameplay logic.
  • Long play sessions on phones stop eating memory until the game dies. Every shot, hit, and pickup sound used to leave a little audio machinery behind forever, and long iPhone sessions grew until iOS killed the tab. Finished sounds now clean up after themselves, and several behind-the-scenes buffers that were sized for desktops now use phone-sized versions on phones.
  • Long music tracks stream instead of sitting fully decoded in memory. A track past ~43 seconds — or a looping one past ~22 — now plays as a stream with a tiny memory cost, at worst a small seam when a very long loop wraps. Short loops and stems still loop seamlessly, exactly as before.
  • Less wasted work every frame. The engine stopped re-sending unchanged particle, terrain, decal, and lighting data to the GPU every frame — particle-heavy and effect-heavy scenes get that budget back.
  • Voxel worlds with heavy terrain generators no longer grow holes and see-through ground around the player. Chunk builds that used to be silently thrown away after 10 seconds — because the engine bundled far-apart chunks into one oversized job — now build one chunk at a time and land.
  • Walking across a voxel world stays smooth. A slowdown we found in testing before this release, where streaming in new ground could grind the whole game, is fixed.
  • Math.floor and friends are exact again in scripts and behaviors. Math.floor, Math.ceil, Math.round, and Math.trunc now return exactly the number you'd expect on big values — Math.floor(334350000) is 334350000 again, not 334350016. Integer math, indexing, and anything built on flooring big numbers works the same in your script files as it does everywhere else.
  • Numeric constants in your scripts are exact now — physics constants survive to the last digit. 6.674e-11 is exactly 6.674e-11 in behaviors and required modules, 0.1 + 0.2 is 0.30000000000000004 like everywhere else in JavaScript, and a constant compared against the same constant from another file is byte-identical. Your source numbers are never rounded behind your back anymore.
  • First-person and aim-over-shoulder games shoot down the crosshair on phones. Tapping the fire button used to send the shot toward your thumb instead of where you were looking; the crosshair is now the aim on touch exactly as it is under the desktop pointer lock. Cursor cameras (pointerLock: false) still aim at the finger.
  • Your character stops walking when a chat box grabs the keyboard. Before: holding a movement key at the exact moment any text field in your game took focus (a chat composer opening on Enter, for example) left the character walking in that direction forever — the release landed in the text field and the game never heard it. Now the engine clears held keys the moment a text field takes focus, the same way it already did for the platform's own text fields. Any script watchdogs you built to zero stuck movement when your chat opens are no longer needed.
  • Savi's builder body no longer materializes inside your face. In first-person games her body used to appear exactly at the spawn point — inside your camera — every time she came to work, until a correction kicked in seconds later. She now arrives a polite conversational step away, already facing you.
  • Asking Savi to replace the world now works in multiplayer rooms. "Start over from the 2D platformer starter", "wipe this and make it a UI game" — these used to fail in multiplayer while working fine solo. Now they work everywhere; other players in the room still can't trigger a world wipe from their side.
  • Shader materials the engine parked for performance now always find their way back when the scene calms. Before, if frames dipped right after the engine re-enabled a parked material, that material stayed on its plain fallback until a full page reload. Now the engine just waits longer between retries (doubling up to about a minute of steady frames), so a scene that calms down gets its look back on its own. And lag from game logic — lots of moving objects, heavy scripts — no longer counts against a material being probed back; only real GPU cost does.
  • Players whose device genuinely can't run Spawn now hear the truth instead of "Update your browser". Phones and computers whose graphics are below Spawn's floor used to be told to update a browser that was already current — forever. Now they get an honest answer: this device can't run Spawn, here's what's worth trying. Machines where a browser setting is the real fix get the setting steps instead.
  • Phones and browsers that can't start 3D now get an honest answer instead of an endless reload loop. When a device's graphics can't run a game, the loading screen now explains what's going on and what to try — before, it said "reloading usually fixes it" forever on a device where reloading never would.