Skip to content

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 19 Sep 14:13
· 1 commit to main since this release

Six days since v0.7.1: 1,854 commits, 1,060 of them in the engine and editor.

This release has two themes. The first is nested prefabs that survive a save. Moving, deleting, duplicating and applying members inside nested prefab instances now round-trips through save and reload. Before, those edits could come back, vanish, or leave two entities sharing one GUID. The second is not losing work quietly. Every action that replaces the open world now asks about unsaved edits. A failed asset load is classified and remembered instead of being refetched every frame.

Dependencies

  • three.js 0.184.0 → 0.185.1. The r185 iOS first-launch black screen is fixed: every async shader compile on a renderer now takes the same lock. r186 was tried and rolled back because its GTAO cannot compile under MSAA. The peer range is now >=0.183.0 <0.186.0.
  • PixiJS, Rapier and Electron are unchanged.
  • Pinned asset toolchain: npm run toolchain:install -- toktx msdf-atlas-gen provisions pinned builds of toktx, ktx and msdf-atlas-gen. Asset conversion no longer uses whatever copy is on PATH, and ffmpeg/ffprobe are pinned the same way.

⚠️ Upgrading from 0.7.1

  • Every entity has a GUID, including ones spawned without EntityAttributes. Older scene entries get a stable derived GUID, so the first save may rewrite older scene files once.
  • Scene format v15. Scenes now save the structure inside nested prefab instances (v14) and prefab member moves (v15).
  • New scenes are <name>.scene.json at every entry point, not <name>.json.
  • Unsaved work is guarded everywhere. Opening a scene from the Assets panel now asks Save / Discard / Cancel, and so does every other action that replaces the world. modoki_prefab edit-exit refuses while prefab edits are unsaved.
  • Reparenting across scenes asks first. Dropping or pasting an entity under a parent in another scene is a prompted scene move. The agent reparent_entity needs moveToScene: true, apply-scene-ops refuses a cross-scene parentId write, and a prefab member cannot be split out of its instance.
  • Resource entities are not tree nodes. Parenting, creating under, pasting under or duplicating a resource entity is refused.
  • loadScene no longer rejects when a scene manager fails to start after the swap. The world is replaced and the failure is reported in startupErrors.
  • entityRef() returns null for a dead handle. OnZone/OnCollision exit callbacks gain selfRef/otherRef for the entity that just left.
  • Agent UI dispatch refuses unreachable controls. It refuses when no control bound to the action is on screen, or when every one is covered by a modal.
  • Prefab link edits: a generic trait edit can no longer add, remove or write PrefabInstance. Use Detach Prefab to cut a link. Nesting a prefab inside an instance of itself is refused.
  • Create and Save As ask before replacing an existing file. Replace keeps the file's GUID, and an agent create refuses an existing asset.
  • MCP changes:
    • the open_*_editor tools take displayName;
    • input_watch takes maxPresses;
    • list replies use returnedCount / totalCount, and entityCount is gone;
    • replies name entities by GUID, and the journal no longer aliases numeric ids: a despawn carries the same ref as its spawn;
    • an entity aim takes exactly one of guid, name or id, and {id} works only for an entity without a GUID;
    • an unknown key in a create-entity spec is refused instead of ignored;
    • write_asset refuses a path that does not exist, and write_asset_meta refuses when the asset is missing;
    • select_sprite_slice, set_collider_edit and set_gizmo validate their input, editor-bound ops refuse when their editor is closed, and discard_asset_edits refuses a path with nothing pending.
  • iOS text interaction is off by default in the web view, which removes the double-tap magnifier. It turns back on while a text field has focus.
  • audioCache.durationSec and videoCache.durationSec are no longer committed to sidecars. They are measured on each machine.

✨ New

  • Prefab member moves:
    • a member moved inside its own instance keeps its identity and is saved;
    • moves show in the Apply dialog under a new Moved category, and Apply re-parents the row in the prefab;
    • Apply fixes member references in every file that uses the prefab, and undo puts those files back.
  • Nested prefabs you drag stay linked:
    • a prefab instance dropped inside another instance keeps its link and becomes a nested instance;
    • an owned nested prefab dragged out stays linked to its own prefab.
  • New capacitor-modoki-system plugin:
    • openAppSettings;
    • requestReview, which asks the OS for its rate-this-app prompt;
    • system.openUrl, which opens an authored https link in the system browser;
    • copyToClipboard, which also works on the web.
  • Ads and attribution helpers are engine modules now: the ad lifecycle, interstitial pacing (with a No Ads gate), the pre-ad No Ads offer and mid-level break flow, and the AppsFlyer attribution lifecycle.
  • Support ID: supportId gives the account uid when the player is signed in, and the app-instance ID otherwise. A ready-made Player ID row view uses it.
  • AudioSource.shuffleStart starts a shuffled playlist on a random clip.
  • UIElement.imageAlign chooses which edge of a cropped image or video backdrop stays in view.
  • NPRPostFX.emissivePassthrough: emissive surfaces glow and bloom under NPR instead of turning dark grey. It defaults to 1; set it to 0 for the old look.
  • Game time waits while the loading overlay is up, and the overlay stays up while a shader compile is holding frames, so a cutscene doesn't start behind it.
  • Android notification icon: set app.notificationIconSource and the build generates the small icon at every density, so reminders no longer show the generic "i".
  • Multitasking device presets in the Game view: Split Screen 360×380, Window 700×450 and Window 1024×560.
  • Inspector GUID in the entity header: it shows whether the GUID is durable, runtime-only (gone on reload) or unsaved. Click to copy it.
  • New engine APIs:
    • requestPrefab, one retry-safe way to spawn prefabs at runtime;
    • worldScoped, module state keyed by the world;
    • EntityTable, packedOf and isPackedAlive, per-entity storage that notices a recycled entity id;
    • parseAssetJson and the load-failure types, so a game's own loader can classify its failures.
  • Modal dialogs block the editor underneath, so shortcuts like Delete and ⌘Z no longer fire behind them.
  • iOS saves stay out of iCloud and Finder backups.

🐛 Fixes

  • Prefabs & nested instances:
    • deleted or moved members inside an owned nested instance no longer come back on reload;
    • two instances no longer share one GUID: a second nested instance at a row is no longer mistaken for the row's own, and a node added in a nested row gets a fresh GUID per instance;
    • a user-added nested instance is no longer dropped on save;
    • a deleted row is no longer brought back;
    • references between a prefab's own members point inside each instance, not at the source entity;
    • references to nodes added inside a prefab template survive save and reload, and duplicating an instance keeps them working;
    • removing a prefab member in a scene takes its nested instance's members with it instead of leaving orphans;
    • Apply to Prefab and prefab refresh keep a scene's nested edits and override changes, and don't duplicate added nodes;
    • refreshing, reverting or applying a prefab instance that lives in a base scene keeps it in that scene;
    • Create Prefab no longer flattens a nested instance when its cache is cold;
    • Create Prefab no longer writes nested instances twice, and it leaves out transient runtime entities and reports what it left out;
    • undoing Create Prefab after Play→Stop keeps a nested instance's link;
    • Detach Prefab, unpack and deleting an owner no longer make moved members vanish on reload;
    • dropping an instance under its own member no longer makes it vanish;
    • a child parented to a prefab instance in an older scene no longer lands on an unrelated entity;
    • saving no longer writes a live entity id into added prefab nodes;
    • editing a pooled prefab no longer blanks its UIEntries view.
  • Scenes & saving:
    • duplicating a scene file gives it its own entity GUIDs, and references to prefab members follow the copy;
    • duplicating or pasting an entity subtree re-points references inside the copy;
    • agent Save As writes a real copy with a fresh scene ID;
    • a base scene kept across a level swap keeps its unsaved state, prefab link and markers;
    • after discardUnsaved, undo no longer brings back discarded entities;
    • a scene manager that fails to start no longer half-unloads the scene.
  • Editor:
    • after an entity is destroyed and its id reused, the SceneView, Hierarchy, Animator and Director follow the right entity: no stale gizmos, collapse state or selection;
    • clicking a label drawn over a sprite in the SceneView selects the label;
    • Inspector number and name fields no longer rewrite themselves or drop characters when the window lacks focus;
    • the Inspector shows a value not yet measured on this machine as missing, with a Re-import hint, instead of 0;
    • Assets panel: the sprite filter lists sprites, a slice-name search finds its slice, and F2 and folder drag work on texture rows;
    • moving or renaming a texture that is open in the Sprite or 9-slice editor keeps its unsaved edits, and a save that finishes after a texture swap no longer closes the new texture;
    • Save and Browse dialogs are sheets of the editor window, so paste works and the editor doesn't freeze;
    • Skin editor: a slow operation no longer lands on a different rig;
    • a re-imported model, skinned GLB, .mesh.json, audio clip or font refreshes every view, including a stopped Game view;
    • re-importing an UltraHDR environment no longer renders it upside down;
    • asset paths that differ only in case repair correctly;
    • a failed build no longer leaves the progress dialog spinning.
  • Assets & loading:
    • a failed asset load is classified: a 404 stays failed instead of refetching every frame or tap, and a network blip backs off and retries;
    • this covers textures, fonts, models, HDRs, audio, video and prefabs;
    • a sprite whose texture was deleted warns [Sprite2D] Unknown asset guid;
    • a failed rigged-model KTX2 encode is no longer cached, so the next import retries it.
  • Rendering:
    • switching post-FX looks no longer leaks GPU textures;
    • editor previews free their environment render targets;
    • shader compiles no longer draw with the wrong render target bound;
    • an empty Renderable3D.material keeps the engine default material across a mesh swap;
    • swapping a primitive for a model frees the primitive's GPU resources.
  • Audio: a playlist whose clip is changed from code continues from the new clip.
  • Cloud sync & accounts:
    • an account deleted on one device is not recreated from another;
    • signing in again with a deleted account's login starts clean instead of uploading the old save;
    • two identical saves no longer raise the fork dialog;
    • PlayerPrefs.clear() also removes corrupt entries.
  • Native / iOS / Android:
    • iOS 16: a failed texture load now settles instead of hanging forever;
    • a file missing from the app bundle is reported as missing, not as an outage;
    • audio resumes after an iOS interruption;
    • the mock IAP store answers entitlements() from the products the console defines.
  • Builds:
    • dynamic MSDF glyphs work in production builds;
    • playable exports build with three r185's KTX2 transcoder;
    • what a build ships no longer depends on the machine's local cache;
    • an auto build number is no longer written into committed files.
  • Agent/MCP tooling:
    • modoki_mutate_scene and modoki_set_transform can edit the prefab-edit world;
    • an apply-scene-ops parentId write goes through reparent, so a member moved out of its instance is unlinked properly;
    • a field write adds a missing trait and reports it in addedTraits;
    • modoki_prefab apply and edit-save return their inert-size warnings;
    • delete ops name every descendant the cascade removed;
    • editor-route failures (a prefab or scene that doesn't parse, a Finder refusal, a sidecar that is too new) answer as coded refusals with options instead of a 500;
    • a filtered read that matches nothing names the unfiltered count and the valid values, and the editor-journal cursor detects a reload;
    • ambiguous-name refusals list GUIDs; scene_query names which physics world is missing; hit_regions treats an empty id list as a miss;
    • modoki_watch frees a despawned series' slot;
    • device tools relay the editor's real refusal codes and options, device input can aim at an entity, device_invalidate_assets reaches audio and environments, and device_handles filters;
    • sim-step refuses instead of clamping.
  • Windows:
    • SDK folder paths with (x86) or non-ASCII characters are accepted;
    • a stored gcloudPath works;
    • Browse… returns a value Apply accepts.
  • Connect Claude: detecting the Claude CLI is time-bounded on every platform and can no longer stall the editor.

⚡ Performance

  • Web builds: the plugin that strips unused code now uses a native filter; the per-module JavaScript call it replaces was 29% of the plugin's time.
  • Missing assets: they are no longer re-downloaded every frame or every tap.

Full Changelog: v0.7.1...v0.7.2