Changelog¶
What changed for someone using arena-composer: the arena-* commands, the editor panel, the MCP
tools. The format follows Keep a Changelog; versions are
the wheel's, from Cargo.toml, and each is a GitHub Release whose notes are its section here.
Unreleased¶
0.5.0 - 2026-10-27¶
Added¶
- arena-composer is on PyPI, and goes into Arena's venv
with
uv pip install --python <Arena's venv>/bin/python arena-composer, where it took downloading a release's wheel from GitHub. - A click on an object in
arena-view's 3D view picks it, as a click on its node in the graph does: its card opens in the panel and its node is outlined in the graph. A click on a counter picks the reference to its top, the node things stand on, not the room around it. Hovering outlines what a click would pick, a double click brings the camera round to it, and a click on the backdrop drops the pick. - A right click on an object in the 3D view opens a menu for it: the relations naming it, each drawn
in the view while hovered and opening its card when clicked;
+ relation, which adds one with the object as its subject, its kind and then its reference picked from submenus; andremove, for an object, an object set or an object reference. check_spec, and every edit, refuse a spec that Arena only refused minutes into a build, once Isaac Sim had started: a task param naming a node of another class than the task needs, such as anOpenDoorTaskon a banana, aPlaceUprightTaskon a bottle that is notPlaceable, or an object reference without the joint param that makes it openable; aTurnKnobTasklevel the knob has not got; aPickAndPlaceTaskinto an articulated destination, such as a microwave; aNoTaskbeside other subtasks; a lift task whose object has no initial pose; and a tuple param short of numbers, or a range given as[max, min]. Each line names the entry to fix and, where there is one, what would do.- They also refuse what Arena dropped without a word: a key no field reads, such as
openable_joint_namebeside a reference'sprim_pathrather than under itsparams, orparms:; and a name inplacer_params.enabled_checksorrequired_checksthat no check has, which turned that check off. describe_scenereports the world. Each asset has its box in the world,bbox_minandbbox_max, the one the checks use, and itsyaw_rad. Aframeblock gives the up axis and the robot's forward and left. It gave only each asset's origin and size, so agents guessed a table's edges from an origin 0.2 m short of them, and the robot's left from a render.arena-resolve-layoutgives the same boxes asworld_bbox_minandworld_bbox_max, beside the local ones.describe_sceneandarena-resolve-layoutlistwarnings: what passes every check and still cannot work in the sim. That is an object no relation places, which spawns at the origin; a relation on an anchor, which the solver ignores; the robot's origin inside an anchor's box, as ontable_oak_robolab; and a background whose root is a rigid body nothing holds up, astable_oak_robolab's is, so nothing on it settles. Each of these passed all eight samples.list_kindssays the class each task param that names an object needs, asneeds:OpenableforOpenDoorTask'sopenable_object,TurnableforTurnKnobTask'sturnable_object,EmbodimentBase, the robot, forLiftObjectTaskRL'sembodiment, andAsset, any entry, for most. A list of ids underother_paramssays it too. It said onlynode_ref, so agents learnt the class fromcheck_spec's refusal.arena-view's panel has a header that pages the view through the layouts a solve draws, one per env, five by default (--samples N), and says whether each passes the checks or which it fails. A page stays turned across edits, so the layout on screen moves only as far as an edit moves it. It drew one layout, and another took a restart with another--seed.- The header's ⟳ solves again from a new random seed, and every solve after keeps it, as
--seedwould. The seed is shown beside it, to pass back as--seed. arena-resolve-layout --samples Nlists every sample's layout underlayouts, each with its verdict and failed checks, where it counted them.arena-view's panel marks the card of an entry that is wrong with a ⚠, and hovering it says what, incheck_spec's words: in red what the build would refuse, such as a param a relation does not take, and in amber what the solve warns of, such as an object nothing places. A spec edited by hand is checked as an edit from the panel is. The panel heard of one only where the solve failed, in a toast naming no entry, and not at all where the solve passed, as it does for a task param naming a node of the wrong class.
Changed¶
- The MCP server and the
author-arena-specskill have an agent render a scene more readily: when the user reports that something does not look as it should, when the scene description leaves it unsure, or to make sure an edit went as meant. It had rendered only for questions of shape or contact. A render is still optional, skipped when the description already answers. -
The spinner saying a solve is under way is in the panel's header, where the ⟳ is, rather than over the corner of the view.
-
The line for a task kind that cannot be a task's only subtask, such as
GoalPoseTask, no longer suggests making it one of several, which sent agents padding it with aNoTaskthat does not build either. - A subtask added or switched to another kind in the panel names, in each param that takes a node,
the first node of the class its kind needs, such as an Openable for
OpenDoorTask, where it named the first node of any class, which did not build.
Fixed¶
- Assets are drawn in the colours Isaac Sim draws them in, in the window,
arena-renderandrender_views. Colours were read as sRGB where USD authors them linear, so every flat colour drew too dark. OmniPBR materials draw their texture alone rather than tinted by the colour beside it, which turneddex_cube's yellow faces dark green andgrey_bin_robolabdark red, and an untextured one starts from OmniPBR's dark grey where it drew white, as the milk jug did. A glow is drawn only where the material turns emission on: the office table's frame and some Lightwheel faucets drew salmon pink. A roughness past 1 is clamped, as Isaac Sim does, where agibot drew white all over. - An asset whose USD says it is Y-up is drawn as Isaac Sim spawns it, as authored: the factory
pegandholelay on their side. - Metal in Lightwheel's kitchens and other OmniPBR assets is drawn as metal, as Isaac Sim draws it: an ORM map's metallic and roughness count by the material's own influences, and only where it turns the map on. They were multiplied by its constants, usually 0 and 0.5, so stoves, sinks and fridges drew as grey plastic. The map's occlusion no longer darkens the colour, which drew every kitchen cabinet near-black, and a restyled kitchen's cabinets keep their colour, which its colour map, read as a normal map too, turned grey.
- The window,
arena-renderandrender_viewsdraw a scene about as bright as Isaac Sim draws it under Arena's dome light, where an object close-up came out 1.6 times brighter. - Colour textures stored as 16-bit PNGs are drawn in the colour space their material names, where they drew washed out: robolab's fruit, and Lightwheel's microwaves, coffee machines and toasters. One that names none is read as Isaac Sim reads it, by its bit depth.
- UDIM textures, one image per tile of the UV map, are drawn: Fourier's GR1T2 and SimReady's eggplant, bok choy and plywood crate drew untextured.
- OmniPBR's separate metallic and roughness maps are read. A material that turns on a map it lacks is drawn as Isaac Sim draws it, as if the map were black: robolab's fruit are glossy.
- SimReady props' metal is drawn as metal. Their UsdPreviewSurface takes metallic and roughness from a map, which was multiplied by 0 and 0.5.
- A robot's metal, and the sides of things the light does not face, are drawn brighter, closer to
Isaac Sim: the window,
arena-renderandrender_viewslight a scene with a sky that metal reflects, in place of a flat fill that lit shaded sides at half their colour and metal dimly. check_specsays where a misspelt object or background param shows: it passes the check, anddescribe_scene,arena-renderand the window stop on it seconds in, withTypeError: object.__init__() takes exactly one argument, which names neither the param nor the object. It said the build would find it, once Isaac Sim had started. Theauthor-arena-specskill's playbook says what to fix for that line.arena-render's andrender_views'top,frontandsideviews see into a room. They leave out the background's pieces that stand between them and everything the spec places, and from above the cabinets hung over the objects too. A Replicator kitchen was drawn from all three as its grey outside, and a Lightwheel kitchen from the side as its outer wall.- A background whose USD carries its own lights, such as a Replicator kitchen or the packing table,
is lit like the others in the window,
arena-renderandrender_views, where it was flat grey: those lights are not drawn, and the light that stands in for Arena's now stands in for them too. - A check for a relation kind the spec does not use is listed in
placement.not_run, as 0.3.0 said it would be, where it read as passed: a spec with nonext_toreportednext_to: true. - A task param typed with a project's own asset or affordance class is a node, as Arena reads it:
the panel picks it from the spec's ids, and
list_kindslists it as anode_ref. Only Arena's own classes counted, so the panel had no control for it.
0.4.0 - 2026-10-20¶
Added¶
- Hovering or pinning a
clutter_onrelation in the panel draws the region its subject is dropped from: the middlespreadof its support's top, andclearance_mabove that, the floor the subject's bottom has to clear.
Changed¶
- A node's card in the editor panel wears the colour its node has in the spatial graph: a stripe down its left edge, a tint over the card, and its icon in white, as the graph draws it. Its summary, after the id, is no longer greyed out. Relations, the task and subtasks are not nodes and stay grey.
- arena-composer runs on IsaacLab-Arena's main branch from 2026-10-13 on (#1430; tested at dc77564), where Arena rewrote its history without Isaac Cap and moved the placement APIs, and no longer on the Arena 0.3.0 ran on. Both call themselves version 0.3.0, so the install cannot tell them apart. Arena's 0.3.1 release is not supported: it predates #1430.
- A spec's placement settings are its
placer_params, as Arena now reads them:enabled_checksandrequired_checksdecide what a solve checks, anddescribe_scenereports the rest inplacement.not_run. A spec still onplacement_validatorsis refused with Arena's line saying to move them. --seed, andseedondescribe_sceneandrender_views, default to the spec'splacer_params.placement_seed, and to 42 only where the spec has none. A seed given still wins, as Arena's--placement_seeddoes, andplacement.seedsays which one ran.get_prim_treegives a relativeprim_pathunder an object too, as under the background: Arena now expands it under the reference's parent.- Arena's new kinds are listed and edited like the others: the
clutter_onrelation, theObjectInTasktask, and theclutter_on_relationcheck.
Fixed¶
- The window,
arena-renderandrender_viewsdraw a robot at the joint positions it starts at, which Arena bounds and places it by, rather than at the pose its USD file is authored in; that includes aninitial_joint_posethe spec gives a DROID or a Franka. The KUKA-Allegro stood 1.6 m tall where Arena had placed it folded forward, 0.84 m tall and reaching 0.57 m, so props kept clear of an arm the picture did not show. The GR1's forearms and the Franka's arm moved too. - Isaac's Seattle lab table, the
tablebackground, is drawn where Arena solves it. Its USD stands its root 0.55 m along x, which the panel andarena-renderdrew and Arena's box leaves out, so props solved onto the table stood beside it. An asset's root now keeps only its rotation, as in Arena's box. - An object reference to a prim with no default-purpose geometry, such as the Seattle table's
Collisions/Cube, a proxy, is refused before the solve with a line naming the prim and the purpose its geometry has. Arena bounds only default-purpose geometry, and its solver stopped onNon-finite solver outputfor such a reference that a relation names, or on an interval assert for one it avoids as an obstacle. get_prim_treeno longer lists those prims, about half of a Lightwheel kitchen's, its colliders, which are guides.
Removed¶
- Registering Isaac Cap's assets and tasks: Arena no longer has them, nor its gear insertion and syringe sort specs.
0.3.0 - 2026-10-07¶
Added¶
- The editor panel shows the background, object sets, object references and the task — its description, its composition and a card per subtask — where it showed only the robot, the objects and the relations.
- The asset browser docks under the 3D view, as Isaac Sim's content browser does, and folds down to its header. A folder tree files Arena's assets by role and SimReady props by their folders on the bucket, each folder with how many assets match the search. The grid shows each asset's picture, name and how many the scene already holds, at a size the slider sets.
- A details panel beside the grid describes the asset picked: where it comes from, its registry name, physics type, folder, USD path (with a copy button), its tags (a click searches by one) and which of the scene's nodes use it.
- Backgrounds and robots are in the asset browser, and the details' button makes one the scene's.
- The details' add button stands the new object on the anchor or on any node picked beside it.
- A graph tab beside the asset browser draws the spec as Arena's review GUI does: a node per id, an edge per relation from its subject to what it names, and a chip for each relation that names no other node. A click on a node, chip or edge opens its card in the panel and scrolls to it, and hovering one shows it in the 3D view. Drag to pan, scroll to zoom, double-click to fit.
- arena-composer is licensed under MIT OR Apache-2.0, at your option, and the wheel says so.
- Every command registers the Isaac Cap assets and tasks Arena's own CLI registers, so its gear
insertion and syringe sort specs open and describe, and
search_assetsandlist_kindsfind them. Thegear_insertion_v2specs still name assets nothing registers. --import MODULEonarena-viewandarena-resolve-layout, andARENA_COMPOSER_IMPORTSfor all three commands, import a project's own modules first, for the assets and kinds they register. A module that does not import, for whatever reason, is named, with where it was named.arena-composer init --import MODULEwrites the variable intobin/arena-mcp, since an MCP client starts it with almost no environment.check_spec, an MCP tool that validates a spec as Arena will read it — in milliseconds, with no solve and no asset read — and reports what the edit tools would refuse, for after a hand edit.list_kinds, an MCP tool listing the relation and task kinds a spec can name: the params each takes, the ones no form edits — a tuple range, a list of ids — by type, and which Arena marksagent_ready.describe_sceneandarena-resolve-layoutreportplacement.not_run: the checks a solve did not run — the ones only the simulator decides, physics settling and IK reach, and the ones for relation kinds the spec does not use — so a dry pass reads as necessary, not sufficient.samplesondescribe_scene, and--samples Nonarena-resolve-layout, solve that many layouts at once, as Arena draws one per reset, and report how many passed, which failed, how often each check failed and how many of the layouts differ. The first is still the one described. A scene where nothing has a relation reports every sample passed and every check innot_run.get_prim_tree, an MCP tool listing the prims in the background's or an object's USD that an object reference can name — a tabletop, a drawer — each with theprim_pathto write, its physics type and, for a jointed body, its joint names. It filters by text and by type, since a kitchen has a thousand.arena-composer initlinks theauthor-arena-specskill into.agents/skills/and.claude/skills/. It is the procedure an agent follows to write a spec with the MCP tools, from the scaffold to every sampled layout passing, with a playbook for the errors and failed checks it meets on the way. The link follows the install, so a new release updates it.arena-composer new PATHwrites a task YAML atPATH, and the scene it includes, holding a pick-and-place that validates, solves and builds. The scene goes in thescenesbeside atasksdirectory, else beside the task.arena-render SPEC...draws specs with no window and no display: it solves each layout and writes a PNG per--view—default, the perspective the window opens on, and the orthographictop,frontandside— as<spec>-<view>.pngunder--out-dir, printing each path. Several specs share one import of Arena. One that does not build is skipped with its reasons, the rest are drawn, and the run exits 1; a layout that fails placement is drawn all the same, with the checks it failed.
Changed¶
- A refused edit and
check_specname the file to fix when the spec includes a scene — for a key neither file has, the one holding its kin, so a missingtaskis the task file's — and an asset name, relation or task kind, or id that nothing declares comes with the closest that do. A name nothing registered is close to says how to import the module that registers it, and an unquotedonsays to quote it. - Edits and
check_specrefuse what Arena only finds when it builds the scene, after the sim has started: a required param a subtask, relation, embodiment, background, object or object reference lacks —num_levelson a turnable reference — and one a subtask, relation or embodiment does not take, with the one probably meant; most objects and backgrounds take any param, so a misspelt one there still reaches the build. An id in a list param,pick_up_object_listamong them, that the spec does not declare; an object reference with noprim_path, or an affordance on one that is not an articulation; and anenv_cfg_overrideArena would refuse, a field undersimits physics backend lacks among it. A spec that already has one is still edited. - So is an atomic task whose kind takes no description, which Arena passes every atomic task:
NoTask,LiftObjectTask,SortMultiObjectTask,GoalPoseTaskand two more build only as one of several subtasks, and stopped the sim with aTypeErroras it started. - So is a param Arena passes itself — a relation's reference, as
parentforon, or an atomic task'stask_description— which the build would get twice. check_specand a refused edit list a duplicate id, a duplicatecli_override_specsarg and atask.compositionthat does not fit its subtask count beside the spec's other problems, each at the entry to fix, where Arena reports them only once every other problem is fixed, and stops at the first. A rename to an id in use is refused on a spec with other problems too, where it merged the two entries.- An edit replaces each file it changes whole, where it wrote into it, so
arena-view, Arena or an editor never reads half a file. A write that fails, a full disk, is a refusal. describe_sceneandrender_viewsreport progress every ten seconds while a solve, a download or a render runs, where a long one looked frozen.- The MCP tools that write nothing —
search_assets,describe_scene,render_views,check_spec,list_kinds,get_prim_tree— declare themselves read-only, so a client may run them without asking. arena-mcpanswers its handshake about two seconds sooner: Arena's solver is imported by the first tool that needs it, not at start.- Every entry in the editor panel is a card, after Blender's modifier stack: it folds, its header names it, and its × removes it. A folded card sums up its entry beside the name, and an object's card shows its asset's picture.
- An id is renamed by typing into its card's header, where it took a double-click on the name.
- Renaming the robot's or the background's id renames the relations and task params naming it too, as renaming an object does.
- Switching the background's asset drops the params the new one does not take, as switching the robot does.
- Adding a second subtask to an
atomictask makes itsequential, and removing back down to one makes itatomic, so the task stays valid at each step. - A click on an asset in the browser picks it and shows its details, where it added it. A double click adds it, and a drag onto the layout still does.
- The 3D view is framed in what the panels leave, as a window that size would be: a taller asset browser zooms the layout out rather than covering it.
- The status line moved to the top-left corner, above the asset browser.
- Errors — a refused edit, a spec that will not build, a failed reindex — pop up in the bottom-right corner of the 3D view, where they were lines at the top of the panel. Each stays until its × is clicked, and its text can be selected or taken whole with its copy button.
- The panel no longer opens with the environment's name; the window's title carries it.
render_viewsreports its two steps — resolving the spec, drawing the views — as MCP progress notifications, which reach a client that asked for progress on the call. They went out as log messages, which the protocol has deprecated: a current client receives none unless it opts in per request, and the SDK warned on every one.
Removed¶
- The
bin/arena-mcpthatarena-composer initwrites no longer accepts the Isaac Sim EULA for you by exportingOMNI_KIT_ACCEPT_EULA: none of thearena-*commands start Isaac Sim, so none need it. A launcher written before keeps the lines until it is deleted andinitruns again.
Fixed¶
- An edit on a spec that is already broken is refused only for the problems it introduces, and
reports what was wrong before as
remaining_errors— on the refusal, and on the edit that landed;arena-viewprints it on stderr for an edit from the panel. Adding the first of two objects a task names no longer deadlocks on the second, from the panel or fromadd_object. An edit that makes a pair read again — a hand edit left a key in both files — lands, with all that is wrong asremaining_errors; and of two entries wrong the same way, the refusal names the one the edit touched. - Renaming an id carries it into every slot Arena checks — an object reference's
parent_id, a CLI override's target, a task param that lists ids — and into the prim path of a reference inside a renamed object, where the spec went on naming the old id and stopped loading. - Removing an object, from its card, the MCP tool or
apply, also removes the object references inside it and their relations, where it left them dangling and the edit was refused. - Removing the last entry of a list that holds a comment no longer writes a file that does not parse.
- A small float an edit writes,
0.00001, goes out as1.0e-05, which Arena reads as a number. It went out as1e-05, which Arena reads as a string. - A spec listing a light or a ground plane as an object resolves, in
arena-view,arena-resolve-layoutand the MCP tools, where it was refused: the asset stays where it is configured, out of placement as in the sim, and is drawn as nothing. A relation naming one is refused with its index. A spec's own light lights the window as the light Arena injects does. - A number typed into the editor panel was saved even when escaped from, and saved twice when entered.
- The status line drew its separators as boxes.
arena-viewno longer exits at startup when api.lightwheel.net cannot be reached, and starts about seven seconds sooner when it can;arena-mcp's firstsearch_assetsgets the same. A spec that places one of Arena's Lightwheel assets still needs the network to build.- 70 of the 100 Lightwheel kitchen backgrounds,
lightwheel_kitchen_l_shaped_coastalamong them, build:arena-view,arena-resolve-layout --payloadandarena-mcp'srender_viewsfailed on them withSingular matrix. - Picking a SimReady prop in the asset browser no longer squeezes the grid of tiles down to a column: the details beside it widened to fit the prop's folder on one line, and now wrap it.
- A change to the spec on disk that Arena cannot build — a hand edit, or an agent's — shows why as
a toast in
arena-view, as a refused edit from the panel does, where the window used to keep the last layout without a word. The form follows the file where it still reads. - An edit from the editor panel is solved once, where
arena-viewsolved it again when it noticed the write on disk. Solves no longer overlap either, so one from an older version of the file can no longer land last and stay drawn. - A change to the spec made while
arena-viewwas still solving its first layout is solved once the window is up, where it used to go unnoticed until the next change. - An edit from the editor panel on a spec that no longer parses — a
task: [left by a hand edit — is refused with the reason as a toast, where it used to end the loop serving the panel: every edit and reindex after it in thatarena-viewsession went unanswered. - The MCP edit tools —
add_object,remove_object,set_embodiment— answer a spec that does not parse with{"ok": false, "errors": [...]}naming the file and the line, where the client saw onlyError executing tool.arena-resolve-layoutandarena-view's toast name the file in that error too. - The MCP tools' other refusals reach the agent again — no spec at the path, a scene passed where
the task was asked for, an unknown view, a spec that does not read, validate or build, a render
that logged an error — where the client saw only
Error executing tool: themcpSDK withholds the message of any exception but its ownToolError.describe_sceneanswers a spec that does not build as a refused edit does,{"ok": false, "errors": [...]};render_viewsfails with the same lines. - Two MCP tool calls at once no longer write the solver's output into the protocol stream, or
refuse a valid spec with
Unknown task kindon a server's first calls: the server runs one tool at a time. add_objectandremove_objectanswer a spec a hand edit left misshapen —embodiment: null, arelationsthat is not a list — with a refusal, where the agent got a bareError executing tool.- Lightwheel kitchens with the marble countertop, such as the ones
kitchen_bench_lightwheel_open_microwaveandkitchen_bench_lightwheel_pick_and_placeuse, draw their counters, andarena-renderandrender_viewsno longer fail on them: the texture is a 16-bit greyscale image, which the renderer could not sample. - Fourier's GR1 humanoid (
gr1,gr1_joint,gr1_pink) is shaded smooth, as Isaac Sim shows it, where it drew in blocky light and dark patches: a mesh that authors no normals and is a subdivision surface, USD's default, gets smooth ones. Its textures are still not drawn. - The window and the renders frame what is drawn, where a background's light, stray vertices or ground plane shrank the scene to a speck in a large dark frame: the replicator kitchens, galileo and packing_table among them. A spec that stands objects on packing_table or galileo as a whole still has Arena place them hundreds of metres away, and the frame takes them in.
0.2.0 - 2026-09-28¶
Added¶
- Pick the robot in the editor panel, from the registered embodiments, and over MCP with
set_embodiment. The robot's id stays, and the params the new one does not take are dropped.
Fixed¶
- A spec naming something other than a robot as its embodiment is refused when edited, rather than failing when the scene is built.
0.1.0 - 2026-09-27¶
Added¶
- The first release on its own:
arena-view,arena-resolve-layout,arena-mcpandarena-composer init, as a manylinux wheel attached to the GitHub Release.