Repository navigation
Releases
Releases · UXCentury/open-bone
OpenBone v0.4.0
Website
- openbone.io: documentation with guides, editor screenshots and live examples you can play (with sound after a tap).
Editor
- Activity panel (bottom dock): every edit with who made it (you, an AI agent over MCP, the editor), MCP connects and disconnects, files received from the MCP project folder, and errors, with filters (All, MCP, You, Errors). Repeats in a row are counted instead of listed, and the tab shows a badge for new entries.
- Connect an AI agent: the { } button next to Connect MCP (and ☰ Menu → Connect an AI agent) shows the MCP config JSON for Claude Desktop, Cursor and other clients, the
claude mcp addcommand and the HTTP command, each with a Copy button. On desktop it can open the current project when the server starts. - Update checker: ☰ Menu → Check for updates (and a button in About) asks GitHub for the latest release. When there is a newer one, an ⬆ Update button appears in the toolbar: on desktop it downloads the installer for your system (Windows .exe, macOS .dmg, Linux AppImage), on the web it opens the release notes. The desktop app also checks once a day.
- Play mode: a Sound row mutes or unmutes everything or one bus, like a page's controls would.
- Bool inputs can mute a bus ("Mutes sound" in the input's dialog): while the input is true, that bus (or all sound) is muted, whoever sets it (your app, page buttons, listeners, scripts); mute actions on that bus set the input too. Every runtime applies it (C++ with Godot, Swift and Flutter, C#, Java, Haxe), and the Windswept example uses it for its music and sound-effect buttons, so
setInput("musicOff", true)from outside the artboard mutes the music.
Web player
- No AudioContext is created before the first click, tap or key press, so browsers don't warn about blocked audio.
- Sound controls outside the artboard:
player.setBusMuted("music", true | false | "toggle"),toggleBus(bus),isBusMuted(bus),busesandsetMuted(muted)onPlayerand<openbone-player>;OpenBone.setMuted/OpenBone.setBusMutedand thesetMuted/setBusMutedbridge commands for WebView hosts. They stay in step with mute buttons inside the artboard. Exported demo pages get a mute button for all sound and for each bus.
Native runtimes
- Mute a bus from outside the artboard:
Instance::setBusMuted/isBusMuted(C++),ob_instance_set_bus_muted/ob_instance_bus_muted(C API),SetBusMuted/IsBusMuted(C#),setBusMuted/isBusMuted(Java, Haxe, Swift, Dart).
MCP
- Live editing with sounds and images: projects the server saved keep relative paths to their art and sound, which the editor couldn't load (silent sounds, missing pictures, load errors). The bridge now sends those files to the editor, and again when they change on disk.
add_input/update_inputtakemutes(a bus,"master"or"").
Install: desktop installers below (Windows .exe/.msi, macOS .dmg, Linux AppImage/.deb/.rpm). Packages: npm @openbone/*, pub.dev openbone, NuGet OpenBone.*, Maven Central io.openbone, Unity (upm branch), Godot addon zip, Swift Package Manager tag v0.4.0.
OpenBone v0.3.0
Editor
- Your own layouts: Menu → Layout → "Save current layout as…" keeps where every panel is docked, its tabs, splits and sizes under a name; your layouts are listed at the top of Menu → Layout (the current one ticked) and switch in one click, with Rename and Delete. They are kept by the editor, so they work in every project, and are in the command palette too.
- The toolbar stays on one row from 1280 px up: the pick filter and the view options (Bones, Mesh, Attachments, Order, 3D) are compact drop-downs (Pick ▾, View ▾, whose labels show anything unusual, like "Pick: Parts" or "View: 3D"); on narrower windows the add buttons fold into + Add ▾, "Connect MCP" shortens to "MCP", and the file name and ⌨ button make room.
- Your own particle presets: "★ Save as preset…" in the particles Inspector keeps an emitter's settings under a name (in the editor, so in every project); they appear with a ★ in "+ Particles…" and "Apply preset…", and "Delete a preset…" removes one. A preset that uses an image as its particle uses the image of the same name in the open project (round particles if there isn't one). + Particles… → Custom… starts an emitter from nothing, a built-in or your own preset, with any project image as the particle, in one step.
- Weights tool view (like Spine's Pies / Overlay / Selected, remembered): each bone gets its own colour, shown as a swatch on the mesh's bone chips (click it to paint that bone). Overlay tints the mesh with every bone's colour blended by the weights as a smooth gradient (off: the painted bone's weights as a smooth heat map, blue 0 → red 1); Pies draws a pie of every bone's share on each vertex; Selected limits the pies to the selected vertices. With vertices selected, each bone chip shows its average share of them.
- Free-form deformation (FFD): the Mesh tool works in Animate mode. Dragging vertices (or the arrow keys) keys a deform at the playhead, so an image can stretch, squash, bend and bounce over time; the mesh itself is untouched. Works with weighted meshes (the vertex lands exactly where it is dropped in the current pose) and soft selection; Delete puts the selected vertices back in that key; adding and removing vertices stays in Setup mode.
- Command palette (
Ctrl/⌘+KorCtrl/⌘+Shift+P): search every action by name and run it, with its key shown, including the right-click actions for the selection (part and bone transforms, lock, trace mesh, show only this). - Hover preview: with the Select / Move / Rotate / Scale / Pose tools, what a click would grab gets a dashed outline (a part) or a glow (the bone that would move), and the status line names it. Pick filter in the toolbar (Pick: Bones / Parts, remembered) rules out bones or parts for viewport clicks.
- Shift-press on something already selected starts a drag (Shift then snaps it); only a Shift-click without moving takes it out of the selection.
- Each tool's status line says what it does and what Shift / Ctrl change (for example "Ctrl/⌘-click: add a vertex"), plus the palette's key.
- Right-click a part for Trace mesh…, Edit mesh points and Re-trace outline… (they were only in the Inspector).
- The view is remembered per file: eyes, locks, show-only-selected and the camera (pan and zoom) come back when a project is opened again.
- The grid and origin lines are drawn over the art (they are for lining parts up) and under the bones and handles; they used to be hidden behind the pictures.
@openbone/render-canvashas abeforeOverlayshook for this. - Lock (Skeleton tree, a lock next to each eye;
Lfor the selection; right-click → Lock): a locked bone or part can't be clicked in the viewport or the 3D view, so the background stays put while you work on the character. A locked bone locks everything under it (shown dimmed); select locked items in the tree. View menu → Unlock all. Editor-only, like the eyes. - Show only selected (
Shift+H, the ◎ button in the Skeleton header, right-click → Show only this): hides every part except the selection (a selected bone keeps everything under it); press again for Show all, which brings back the eye states from before. - Bone | Part switch (toolbar next to Comp, shortcut
A, remembered): in Setup mode it decides what dragging a picture transforms with the Move, Rotate and Scale tools. Bone moves, rotates or scales its bone; Part moves, rotates or scales the picture itself, around its origin, even where the bone is drawn across it (clicking a bone away from any picture still grabs the bone). In Part mode selected parts turn or scale together around the grabbed one, Shift snaps to 15° / 10% steps, each drag is one undo step, and the viewport status showsSETUP · PARTSand the angle or percentage. Animate mode always poses bones. In Part mode a selected part is highlighted on its own and gets its own gizmo at its origin (the point it turns and scales around): a dashed orange ring with a dot showing where the part points (Rotate), red / green handles along the part's own axes (Scale), arrows (Move); they can be dragged from outside the picture. The bone's handles are hidden. While a ring is dragged (a part's or a bone's), a wedge shows the turn and a label the change and the result (+40.1° · 130.1°); scaling a part shows its percentage. - Mesh tool cursors: holding Ctrl/⌘ shows a crosshair with a plus where a click adds a vertex, and hovering a vertex shows a move cursor.
- Re-trace outline… works on weighted meshes: the new mesh is bound again to the same bones, with as many influences per vertex as before (it was disabled with no explanation). Linked meshes, and meshes other meshes link to, say why they can't be re-traced.
- Select several parts: Shift+click adds a part to the selection (or takes it out), Ctrl/⌘+click takes it out, in the viewport, the Skeleton tree and the 3D view (bones worked this way already; in the 3D view Alt+Shift+click adds bones). Every selected part is outlined; dragging one of them with the move tool, or the 3D gizmo, moves them all by the same offset, and the 3D gizmo's Z arrow moves them through the draw order together, each as one undoable edit.
- 3D view (View → 3D view, toolbar,
Shift+Z): the scene as a stack of layers you orbit around, like an engine's scene view. Every part sits on its own outlined plane, spaced by draw order; the bones are solid, lit 3D bones at the depth of the parts they carry; an inset shows the normal front view. A move gizmo sits on the selection: red X and green Y move a part (its image on its bone, Setup mode) or a bone (setup pose, or a key in Animate mode), blue Z moves a part through the draw order; Shift snaps to 10 px. Press a part to select it and drag it through the stack to change its draw order (one undoable edit, previewed live, also in the front inset); drag empty space to orbit; Alt+click selects the bone under a part. Depth spacing, outlines, bones and scenery can be toggled. It follows the live pose in Setup, Animate and Play. three.js loads only when the view opens (needs WebGL). - Order view (View → Order view, toolbar,
Z): the character turned to face you, with the draw order as left-to-right depth. Every part stands in its own column at its real height, from the back-most on the left to the front-most on the right, so a part in the wrong layer stands out; drag a part left or right to move it in the draw order (one undoable edit). Backgrounds that span the artboard are left out. - Attachments toggle (View → Attachments, toolbar,
H): hide every attachment and show only the bones, on a dark artboard so they stay readable. - Pen tool (
N, ✒ in the toolbar) for paths: click to place knots, drag to pull out handles, click the first knot to close, Enter or Esc to finish. It creates a slot and path on the selected bone, or, with an end knot of an open path selected, keeps drawing that path. Drag anchors (handles follow) and handles; handles are smooth, mirrored or broken per knot (Alt-drag breaks a handle, Alt-drag an anchor pulls out new ones, right-click a knot to pick a mode or reset its handles). Click the curve to add a knot without changing its shape, Delete removes knots, the panel and context menu toggle Closed. Anchors snap like bones. Weighted paths are re-bound through their bones when knots move; in Animate mode dragging knots keys the path's deform. Paths draw in their colour, the selected one highlighted, and not at all when their slot is hidden. - Inspector: "Bind knots to bones" for paths (selected knots or all: bind by distance or 100% to a bone, per-bone weight sliders, Unbind).
- Bounding boxes: edit points with the Pen tool (drag, click an edge to add, drag inside to move all, Delete), a colour, a translucent fill in the viewport, "Trace from image…" (wraps the box round the visible pixels of an image or mesh, with a corner count) and Rectangle / Ellipse presets. Undoable, one step per edit.
Examples
- Knight and Walker: limbs are layered the way the art is drawn (upper arm over the forearm's open top, thigh over the shin's top, boots under the shins), the knight's shoulders sit in the breastplate's armholes, his knee guards sit at the knees, the cape hangs from behind the shoulders (no floating clasp), the helmet sits on the shoulders, and the far hand is a mirrored fist so he has a left and a right hand.
openbone renderno longer draws click areas (bounding boxes) into the picture;--bounding-boxesshows them.
Format
- Bounding boxes take an optional editor
color.updateAttachmentwithweights: nullunbinds a path.
Runtimes
- Unity: text outlines are drawn (TextMesh has none: a ring of outline-coloured copies under the fill, like MonoGame); outlined titles and subtitles lost their stroke before.
MCP
- Video exports with sound, and MP4 / WebM (
export_file,openbone export): AVI and MOV carry the sound the animation or sta...
OpenBone v0.2.0
Native runtimes for C++ (Godot, Cocos2d-x, SDL2, SFML, OpenGL, Unreal), C# (Unity, MonoGame), Java (libGDX, Android), Swift, Flutter and Haxe, all checked against a shared conformance suite; sound in the engine integrations; desktop installers for Windows, macOS and Linux; WebM video export; and the rest of the Spine-style rigging tools.
Native runtimes
- GLFW / OpenGL 3.3 sample (
runtimes/cpp/engines/glfw): the WebGL2 renderer's shader and blending in plain OpenGL (two-colour tint, premultiplied pages, all blend modes, stencil clipping), mouse input, and a hidden-window--out frame.pngmode. - Sound in more runtimes: the Swift
OpenBoneView/OpenBonePlayer(newOpenBoneAudio, AVFoundation;OpenBoneDocumentgainsaudioAssets,audioBuses,audioMaster), the libGDX module (OpenBoneAudio), the AndroidOpenBoneView(SoundPool / MediaPlayer,SoundSource) and the SDL2 and SFML samples play the document's sounds (on by default,isAudioEnabled/--muteto opt out; audio callbacks still get every command), on shared, unit-tested gain / voice / fade logic (OpenBoneAudioMixer, JavaAudioMixer,engines/common/openbone_audio.hpp). Unreal still only emits audio commands. - MonoGame integration (
runtimes/csharp/monogame):OpenBone.MonoGamefor MonoGame 3.8 DesktopGL —OpenBoneRenderer(DrawUserIndexedPrimitives, premultiplied blend modes, stencil clipping, two-colour tint through a GLSL effect built in code with aBasicEffectfallback, optional SpriteFont text),OpenBoneMonoGame(load, animations or state machine, mouse / touch → listeners, events) andOpenBoneSoundPlayer(SoundEffectInstancewith bus × master volume, log2 pitch, loops and fades), a DesktopGL knight sample and window-less tests (also in CI). - Haxe runtime (
runtimes/haxe): a pure Haxe 4.3 port of the runtime with no dependencies (.obone/.obonbloading, skins and skin bones, every constraint in custom order, sliders, physics, particles, sequences, packed/trimmed/polygon atlases, text templates, the draw list, state machines with listeners and bindings, events, audio commands) and JS number semantics on every target. All 82 conformance cases pass on the JS target (scripts run on its JavaScript engine throughJsScriptHost); on eval and Python the 6 scripted state-machine cases are skipped and the other 76 pass. - The Flutter plugin moved from
runtimes/darttoruntimes/flutter/openbone: Flutter 3.47's Swift Package Manager support fails when a plugin's folder name differs from its package name (flutter#186881). - Java runtime on Gradle 9.9 and Android Gradle Plugin 9.5 (Kotlin 2.4 through the Kotlin Android plugin), without Gradle 10 deprecations.
- Swift Package Manager for the Flutter plugin on iOS and macOS (
runtimes/flutter/openbone/darwin/openbone/Package.swift, with iOS and macOS sharing onedarwin/folder and podspec), so Flutter no longer warns thatopenbonelacks SPM support; the podspecs stay for CocoaPods. - Sound in the native engine integrations: the Flutter
OpenBoneWidget(newOpenBoneAudio, flutter_soloud; the plugin now needs Flutter 3.41+) and the Cocos2d-xOpenBoneNode(cocos2d::AudioEngine) play the document's sounds, like the GodotOpenBoneSprite. The C API gainsob_document_audio_asset,ob_document_audio_busandob_document_audio_master, and the DartOpenBoneDocumentexposesaudioAssets,audioBusesandaudioMaster. The Flutter example bundles its sounds. - C++ runtime (
runtimes/cpp): a native C++17 port of the runtime with no engine dependencies —.obone/.obonbloading, skins and skin bones, every attachment, animation mixing, IK/transform/path/physics in constraint order, sliders, particles, text templates, the draw list (clipping, sequences, packed/trimmed/polygon atlases, two-colour tint), state machines with listeners and bindings, events, audio commands, and scripts in embedded QuickJS. Passes all conformance cases (CTest). A stable C API (openbone.h,libopenbone) for FFI, a Godot 4 GDExtension (OpenBoneSprite, checked in headless Godot), SDL2 and SFML sample renderers, an Unreal Engine 5 plugin (as source) and a Cocos2d-x 4.0 node (built and run on Linux; it now binds its textures through the program state). - C# runtime (
runtimes/csharp):OpenBone.Runtimefor .NET Standard 2.1 / .NET 8, a native port of the runtime (.oboneand.obonbloading, skins and skin bones, every attachment, mixing, constraints in custom order, sliders, physics, particles, text templates, the draw list, state machines with listeners and bindings, events and audio commands) that passes every case of the conformance suite (dotnet test). Scripts run in Jint (OpenBone.Scripting.Jint) with the sameobAPI and limits as the QuickJS host. - Unity package (
runtimes/csharp/unity/com.openbone.runtime): ScriptedImporter for.obone/.obonb, OpenBone Animation and OpenBone State Machine components (UnityEvents, EventSystem or mouse pointer input), a mesh generator with blend modes, stencil clipping, two-colour tint and premultiplied pages (OpenBone/Skeletonshader), and an AudioSource bridge. Built withruntimes/csharp/unity/build-package.py; tested in Unity 6 (6000.6.8f1) with every example; it now declares itscom.unity.uguidependency, imports art and sounds in any import order, clamps texture edges, and hasStageBoundsfor framing a camera on the document's stage. - Java runtime (
runtimes/java): a Java 11 port of the runtime with no dependencies (.obone/.obonbloading, skins and skin bones, every constraint in custom order, sliders, physics, particles, sequences, packed atlases, text templates, draw list, state machines, bindings, events, audio commands), state machine scripts in QuickJS (openbone-scripting), a libGDX renderer with an LWJGL3 sample (openbone-gdx), and a Kotlin Android library withOpenBoneView(openbone-android). JUnit runs all 82 conformance cases on the JVM; an instrumented test runs them on Android. - Swift runtime (
runtimes/swift): a SwiftPM package that compiles the C++ runtime from source and wraps its C API —OpenBoneDocument/OpenBoneInstance(.obone/.obonb, skins, animation tracks, state-machine inputs, triggers and pointer, event / audio / state / log callbacks, bones, slots, zero-copy or copied draw list), ARC-owned handles.OpenBoneView(Metal, UIKit and AppKit) and SwiftUIOpenBonePlayerdraw it with blend modes, stencil clipping, two-colour tint, premultiplied pages, particles and CoreText text, and send touches / the mouse to listeners; plus a SwiftUI sample.swift testruns all 82 conformance cases (checked on Linux; the views have not yet been run on Apple hardware). The C API gainsob_instance_slot_count/ob_instance_slot/ob_instance_find_slot. - Flutter / Dart runtime (
runtimes/flutter/openbone): theopenboneFlutter FFI plugin wraps the C++ runtime's C API withdart:ffi(ffigen bindings) and buildslibopenbonefor Android, Linux and Windows (CMake) and iOS/macOS (CocoaPods). Pure-DartOpenBoneDocument/OpenBoneInstance(skins, tracks, state machine inputs, triggers and pointer, event / audio-command / state streams, draw list; native memory freed bydisposeor finalizers) andOpenBoneWidget+OpenBoneController(Ticker-driven,Canvas.drawVerticeswith blend modes, clipping, two-colour tint and premultiplied pages, gestures → listeners).flutter testruns all 82 conformance cases; the example runs on Linux desktop and an Android emulator (iOS, macOS and Windows not built yet). C API additions: slot accessors (ob_instance_slot_count/ob_instance_slot/ob_instance_find_slot, shared with the Swift package) andob_particle_dot_alpha; CMake optionsOPENBONE_BUILD_STATIC,OPENBONE_INSTALL.
Editor and rigging
- Dopesheet: multi-key selection (Shift/Ctrl-click, Shift-drag box, Ctrl/⌘+A), drag and arrow-key nudge of the selection, copy / cut / paste at the playhead (across animations), scale in time, curve and delete for all selected keys. New ops
transformKeys,pasteKeys,deleteKeys(also MCP tools). - Compensate (
J, toolbar ⇲ Comp): transform a bone while its child bones keep their place. - Linked meshes (
addLinkedMesh): share another mesh's geometry and weights with a different image, optionally following its deform keys. - Runtime fixes ahead of the native ports: full-weight rotation keys set the keyed value; draw-order keys keep unlisted slots in place (like Spine); blend states report their stronger animation's progress (exit times, on complete); transitions to deleted states are skipped; constraint results written to world transforms survive later constraints (
syncApplied); physics stretch uses the world rest length; additive sliders mix their colour and constraint keys; fully transparent shapes aren't drawn; no NaN from text-driven bindings or short deform keys. - Skin bones and skin constraints:
SkinData.bones/constraints; anything a skin lists is active only while a skin listing it is set (inactive bones and their children are not posed or drawn, inactive constraints are skipped). OpsaddToSkin,removeFromSkin; Inspector "Only in skins" on bones and constraints. - Inherit timeline:
{target: "bone", property: "inherit"}with steppednormal | onlyTranslation | noRotation | noScalekeys; keyable from the Inspector's Inherit field in Animate mode. - Constraint order: optional
orderon every constraint, applied as one sorted list (default unchanged: IK, transform, path, physics). OpsetConstraintOrder; Inspector "Constraint order" list with ↑↓. - Reference scale:
skeleton.referenceScale(default 100). Physics gravity and wind and IK softness scale with the skeleton's size relative to it, so a rescaled rig behaves the same. Document inspector "Ref. scale". - Two-colour tint: a keyable ...