Skip to content

InsideDev 0.11.0

Latest

Choose a tag to compare

@sashaok123 sashaok123 released this 11 Nov 15:46

Faster, safer and easier to drive: the whole tool reviewed line by line

0.11.0 is a review of every part of InsideDev: about 92,000 lines of C#, 14,000 lines of Python, the loader and the
native readback plugin. The goal was a tool that costs nothing while you do not use it, records without slowing the game
or drifting from game time, and that people and AI agents can drive without traps.

Existing commands, MCP tools, config keys and file formats keep working. Where a default changed, it is listed under
"Changed defaults" below, with the key that brings the old behaviour back.

Speed

  • Nothing runs while nobody uses the tool. With the editor closed and no client connected, 0.10.0 still scanned the
    scene, traced sound events, monitored signals and rebuilt overlay text every frame: 1.2 to 2.8 ms per frame and 17 to
    23 garbage collections a minute in our test scene. Now every scanner and monitor sleeps until a panel, a command or a
    client needs it, and catches up when it wakes: 0.03 ms per frame and no garbage collection in 95 s in the same scene.
    background always (or background=always in editor.cfg) brings the old always-on behaviour back.
  • No more hitch every 10 seconds. While an agent or the editor kept the object database awake, it searched every
    root of the scene every 10 s (20 to 30 ms in one frame). It now does that only after a level streams in, and once a
    minute as a safety net (db.rootRefresh).
  • Mods only work in their own level. A mod's operations are grouped by level. They are looked up once when their
    level loads, only inside that level, retried a few times for late content, and left alone until the next load. With
    three mods enabled and two of their levels not loaded, all mods together cost 0.0016 ms per frame; entering a mod's
    level applied it in 2.5 ms, and a respawn applied it again. Extension modules can declare their levels
    (IInsideDevLevelScoped) and are then only ticked there; LevelGate is part of the core for mod authors. mod list
    and ext show each mod's levels and cost, and the log names an extension whose tick is slow.
  • Screenshots in a fraction of the time. The MCP screenshot no longer writes a full-size PNG to disk and decodes it
    again in managed code: the frame is read once, scaled and encoded by Unity itself. 960 px: 2.25 s before, 0.09 s now;
    1920 px: 3.9 s before, 0.31 s now. New format: "jpeg": a 1600 px shot is 121 KB in 0.12 s.
  • Faster calls. One main-thread hop per MCP call instead of two or three, a cached tool list, buffered HTTP. observe
    33 ms before, 8 ms now; a console command 18 ms before, 8 ms now; geometry 72 ms before, 8 ms now; find_objects 36 ms
    before, 13 ms now.
  • Recording does not hold the game back. grec writes frames straight from the readback buffer and a slow encoder
    never blocks the render thread; MultiCam's writer has a bounded wait; the scene recorder scans the scene once at start
    and samples only what changed; director holds are hard links instead of copies (500 holds in 0.1 s). With srec and
    grec recording, the game held 59.8 fps (vSync 60) against 56.5 before; srec starts and stops in under 0.2 s.
  • Python tools. Seeking back in a take video 9.9 s to 1.0 s, grade statistics 12.6 s to 2.2 s per 600 frames,
    ffmpeg does the scaling, one ffmpeg helper that always cleans up its child.

Recording you can trust

  • Video length equals game time. 0.10.0 fixed the file rate once and wrote one frame per grab, so a minute of play
    came out about 3.5 s short and the sound no longer lined up. Now frames are placed by game time: a 120 s recording
    under load gave 120.13 s of video for 120.10 s of game time. A <file>.times.csv next to the video gives each frame's
    game time for exact audio alignment.
  • Recording while an agent drives. The time an agent's game stands frozen between calls is left out of the video, and
    stepped runs are recorded without lost frames (0.10.0 lost most of them).
  • The game's own picture, also under other windows. time {op:"record"} and rec start now record the game's own
    frames. Tested with a window covering the game: none of it in the video. Desktop capture is still there as
    source:"desktop" / rec start ... desktop.
  • A failed ffmpeg (no NVENC, odd window size, full disk) is reported at once and capture stops costing frame time.
  • ffmpeg can no longer outlive the game: child processes are tied to the game process.
  • A take folder that already holds a recording is not overwritten unless you add overwrite=on.
  • The scene recorder stops cleanly on a full disk, checks free space before it starts (record.minFreeMB), and reports
    its state in srec status json.
  • A level load during a replay no longer freezes the game.

Security

  • The MCP server refuses requests from web pages. A page in your browser could send commands to the game while it was
    open, through an Origin: null request. Requests with a foreign Origin, a cross-site fetch, a wrong Host (DNS
    rebinding) or a non-JSON MCP body are now refused. Local clients (the stdio launcher, inside_ctl.py, scripts) are not
    affected.
  • No MCP call can start a program of its choice any more: ffmpeg is found by the tool itself (ffmpeg.path in
    editor.cfg, INSIDEDEV_FFMPEG, _mod\ffmpeg, PATH).
  • reflect calls go through an allow list; calls that write files, start processes or change the registry are refused.
  • A deeply nested JSON body can no longer crash the game (tested with 200,000 levels).
  • The Mono debugger port of the loader is opt-in (_mod\debugger.flag).

New commands and tools

Command / tool What it does
doctor [json] one self-check of every part: loader, modules, versions, ffmpeg and encoders, disk space, minimized window, time scale, background mode
help <command> usage of one command; help lists every command
cfg [get / set / reset] [json] every config key with its value, default and meaning (103 keys), changeable while the game runs
background [auto / always / off] when the background scanners run
quit closes the game cleanly
labels types <n / all> how many component names a world label shows (the rest as "+N"); labels no longer overlap
state json, where json, perf json, mod list json, srec status json, acap status json, mcam status json, cam status json machine-readable status
GET /status server state without waiting for the game's main thread
POST /cmds several commands in one request and one frame
film (MCP) panorama, game-frame recording and the live director camera with structured results
observe {detail:"delta"} only what appeared, disappeared or changed since the last observation
act {seq:"R1.2 J R0.4+J"} the short input grammar of ctl seq in act
wait_ready_s on act / move_to / interact wait for the game to take input instead of being refused
checkpoint {op:"goto", name} load a checkpoint by name
restore {dry_run:true} what a restore would undo, without doing it
mcam replay ... resume skip camera passes that already finished
srec load <dir> play, srec reload fewer steps for the common loops
inside_ctl.py wait / snapshot / doctor wait until the game is ready, read state, self-check from outside
mcam_compose.py doctor, --resume check ffmpeg and encoders before a compose; skip finished outputs
InsideMuter status / unmute / stop the muter can be asked and stopped; it gives back the sound it muted

Fixed

  • A mod file with a JSON error was replaced by an empty file when you ticked its checkbox; now it is left untouched and
    the error names the line and column.
  • After 400 log lines, file-bridge commands answered with empty text and the Console tab stopped updating.
  • The audio catalogue lost rows every 10 seconds of normal play.
  • After picking an entry in the command palette, the game's keys stopped working until you clicked the game.
  • World labels listed every component on one line, ran off the screen and covered each other.
  • acap status could mute the game; acap's volume rule could end up in a recorded mod.
  • A scale-only change was recorded up to 8 seconds late.
  • move_to timers ran several times too fast with vSync off, and a goal inside a gap made the body jump it back and
    forth until the step limit.
  • The observation after an action could miss objects that appeared during it.
  • Numbers in replies and files used a decimal comma on non-English Windows (for example cam printed (1,23, 4,56, ...)).
  • The stdio launcher dropped inside_status from its tool list once the game was up.
  • mcam_spec_check.py disagreed with the game in about 20 rules and did not start on Python 3.9 to 3.11.
  • mcam_audio.py fix could cut a WAV file short without a backup.

Changed defaults

What 0.10.0 0.11.0 Old behaviour
Background scanners always on only while the tool is used background=always
Recording into a folder that holds a take overwritten refused overwrite=on
Mono debugger port 55555 on off _mod\debugger.flag
Requests with a foreign or null Origin accepted refused none (use a local client)
time {op:"record"} / rec start source desktop game frames source:"desktop"
InsideMuter on exit leaves sessions muted un-mutes what it muted --keep-muted
reflect call deny list allow list none
World labels every component 3 names and "+N" labels types all
play.vsync_off=1 vSync off from game start off only while an agent works or the clock is held play.vsync_off=2
Passive hidden-object scanner always on off until the Hidden tab or hidden on hidden.passive=1
A bare file name for grec / pano the game's working folder <game>\_mod\recordings a full path
Example mods in mods\ two shipped enabled all shipped disabled enable them in the Mods panel

Install

Everything is in the zip. With the game closed: version.dll next to INSIDE.exe; InsideDev.dll, InsideDev.Mcp.dll and InsideDev.Play.dll in <game>\_mod\ (the lab modules InsideDev.ReplayLab.dll and InsideDev.Det.dll only if you use them); InsideReadback.dll in <game>\INSIDE_Data\Plugins\; tools\mcp\InsideDev.McpStdio.exe if you use the stdio launcher, tools\muter\InsideMuter.exe if you want the game muted. The Steam client must be running, or the game closes itself about two seconds after start. Then type doctor in the console: it checks the install. The README has the full table and the first-run steps.

Tested

In the game, in the same scene and back to back with 0.10.0: idle cost, call latency, screenshots, recording length against game time, recording with another window over the game, recording while an agent drives, mods in loaded and unloaded levels, level loads during recordings and replays, deaths and respawns, swimming, the security refusals, the stdio launcher, and a clean install from this zip. Five independent reviews of the riskiest changes were done before the release and their findings fixed. Not tested: game sound capture together with video (the test machine had no audio output device), and a session of an hour or more.