Changelog - v6.2.0-beta9

Polyphase Engine v6.2.0-beta9

Big systems, big polish. Beta 9 is the largest functional update of the v6.2 cycle so far. Five brand new authored systems, a major step forward for Android, and the PSP build target finally landing clean. If you've been waiting for a "shippable feel" beta, this is the one.

Full Changelog

Headline Features

Loading Menu System

You can now author loading screens the same way you author anything else in Polyphase: as a regular Scene asset. The engine handles the rest.

LoadingMenu.Open("SC_Level2")

That single call spawns your authored loading scene, marks it persistent, queues the gameplay swap, and tears the menu down when the target scene emits Loading.Finished. The loading scene keeps ticking the whole way across the swap, so intro and outro animations don't stutter at the scene boundary.

Designers compose look and pacing entirely from Lua. The engine just orchestrates. Full Loading.* SignalBus channels (Progress.Percentage, Progress.Info, Finished) ship out of the box, and AppSettings now has a "Loading Min Display" knob so a fast load can't flash the menu in and out.

See Documentation/Development/LoadingMenu.md for the full guide.

Transform Animation System

Three new node and asset types for non-bone, non-skeletal motion. The thing you reach for when you want a platform to slide, a door to swing, a UI panel to whip in.

  • TransformAnimationAsset: keyframed transform clip, loopable, retimeable.
  • TransformAnimationNode3D: plays a clip on a 3D node.
  • TransformAnimationWidget: same, but for widgets.

Full Lua bindings, full Timeline integration via the new TransformAnimationClip and TransformAnimationTrack types, and TransformKeyframe is now a first-class Datum value type so you can build and edit clips from script as easily as from the editor.

Audio Analysis API

Real-time audio visualization is in. One platform-independent API on top of Audio.h, working everywhere the engine works: XAudio2, ALSA, PulseAudio, ASND on Wii and GameCube, NDSP on 3DS, console addons. From Lua:

local bass = self.audio:GetFrequencies(20, 250)
local mid  = self.audio:GetFrequencies(250, 2000)
local high = self.audio:GetFrequencies(2000, 16000)

local bins = self.audio:GetSpectrum(20, 20000, 64)

Functions return 0.0 (or zero-filled arrays) when the voice is idle, so you never have to gate visualizer code on IsPlaying(). Works on free voices, Audio3D nodes, and streaming voices (one-line backend hook; shipped for Windows, Linux, Wii, 3DS).

See Documentation/Development/AudioVisualizer.md for the full guide.

Image Plane Feature

Drag a texture into a 3D scene. You get a textured plane. That simple.

The editor auto-generates a paired SM_<base> plus M_<base> for the texture, with sensible defaults (Unlit, Opaque, Center pivot, Aspect-Width). Pivot, size mode (AspectWidth1, AspectHeight1, PixelsPerUnit), shading model, blend mode, two-sided, all editable per plane. Existing image-plane meshes are detected and reused, so you don't get a graveyard of one-off assets.

Asset Fixup Modal

Scenes used to silently break when an asset reference got bound to the wrong type, usually because an import name-collided with an existing asset. Now, on scene open, the engine scans for Asset-typed widget properties whose binding fails its type filter and surfaces them in a single modal with a per-row picker: rebind, clear the slot, or skip. Resolved rows stay visible so you can read what you fixed before closing.

Pair it with the new import-clash dialog (which prevents new collisions) and the whole "where did my texture go" class of bug is gone.

Editor Alert Modal System

The editor can now raise non-fatal alerts without crashing, freezing, or interrupting your flow. EditorShowAlert queues a message; multiple alerts stack into one modal that you walk through. Used internally for the new Node::AddChild self-pointer detection, so instead of crashing on a corrupt pointer, you get a readable alert and the editor keeps running.

Platform Wins

Android Production Pass

Android moved from "it builds" to "it ships".

  • App settings honoured. Package name, app label, icons, orientation, all wired from AppSettings to the Gradle and Manifest layer at build time.
  • Addons work on Android. New InjectNativeAddonsIntoCmake step plus AddonInject.cmake injection into the Android CMakeLists. Addon-backed Lua tables no longer silently degrade to nil on device.
  • Cleaned icon pipeline. Replaced the old ic_launcher.webp set with proper per-density PNGs.
  • Loading menus, transform animations, audio analysis. All work on Android day one.

PSP Build Target Working Cleanly

The PSP build-target addon ("Beta 9 PSP") finally lands clean. Engine-side cleanups landed in Scene.cpp, StaticMesh3D.cpp, SoundWave.cpp, Texture.cpp, World.cpp, Renderer.cpp, HttpClient.cpp, FileWatcher.h. All the platform stubs, big-endian guards, decompression hooks, mutex guards, and HTTP fallbacks that the addon needs to compile and run without engine forks.

If you've been holding off on PSP because the engine kept fighting you, that's over.

Build-Target Addons: Skeletal and Input

  • Skeletal meshes work on build-target addons. Engine SkeletalMesh and SkeletalMeshCompResource now expose the POLYPHASE_PLATFORM_ADDON arms needed for CPU skinning on console addons.
  • Input systems fixed for build-target addons. Console addons can now reach the full input system without the InputConstants.h console fallback gap that made IsJustDown fire every held frame.
  • Non-embedded packaged builds find assets again. UUID-based lookup now works correctly for builds where assets ship on disk rather than baked into the binary.

Gaussian Splatting and Vulkan Addon Handles

The Vulkan backend now exposes a public GfxVulkanAddonHandles surface so addons can submit custom rendering work directly into the engine's pipeline. The Gaussian Splatting addon uses this to draw camera-facing translucent splats correctly through the engine's render order, including translucency sorting.

Smaller But Lovely

  • 3D audio one-shots at a position. Fire-and-forget spatial audio without spawning a node.
  • Audio3D seek. Jump to a specific time in a playing 3D sound.
  • Categorized "Add Node" menu. The Scene Hierarchy + menu now groups 3D and Widget children into sub-buckets, and addons auto-group under Addons/<id> unless they explicitly set a category.
  • Native addon shadow copies. Addons are now staged into a shadow directory before load, so Windows file locks don't pin the original DLL during hot-reload.
  • External Launchers preferences. New LaunchersModule in editor Preferences for managing external launchers and tools.
  • Modal SYS_Exec is gone. Long external commands no longer freeze the editor; SYS_ExecDetached is the new default.
  • Multiplayer documentation. End-to-end guide for authoring a networked multiplayer game in Lua, covering the authoritative-server model, sessions, lifecycle, replication, and RPCs.

Bug Fixes Worth Calling Out

  • Vertex colors imported from Blender glTFs are no longer scrambled. Assimp's normalized USHORT COLOR_0 accessors now decode correctly.
  • HTTP works in Shared editor builds again. The HttpResponse ODR collision between the AutoUpdater and the engine is resolved.
  • Multiple editor crashes fixed. Null-checks in Renderer.cpp collision shape setup, safer Node::AddChild pointer handling, XAudio2 init error paths.
  • Texture save round-trip no longer shrinks editor source. Texture::SaveStream's LQ downsample path now skips Platform::Count and .oct files.