Skip to content

Releases

InsideDev 0.11.0

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 `hidde...
Read more

InsideDev 0.10.0

Choose a tag to compare

@sashaok123 sashaok123 released this 04 Nov 17:06

A 360 degree panorama command, a much cheaper muter, less garbage per frame

Everything new runs only when you call it, and the game sound is still never muted unless you start InsideMuter yourself. One
built-in limit changed for everyone: a detached MCP job may now run 45 minutes instead of 10.

  • 360 degree panorama (pano, with Play). One console command writes an equirectangular PNG that panorama viewers open
    directly, with a JSON file that says where the eye was. Each of the six cube faces is an ordinary game frame, so the picture
    is what a screenshot would show there. A 4096x2048 panorama took 2.3 to 2.7 s in all, of which the picture jumps around for
    0.2 to 1 s (13 frames at a 2560x1440 game view), tried at places along a long bunker route in a mod scene.
  • Limits for a first-person camera's free look (campath mount). Two new optional arguments clamp how far the head may tilt
    the view up and down outside the timed looks, for example on a ladder, while a timed look can still reach as far as
    pitch_max. Leave them out and nothing changes.
  • InsideMuter 3. The optional muter costs about 3 % of a core instead of 40 to 60 % (measured without the game, 25 s test:
    62 % against 2.7 %), with the same 50 ms mute poll and the same heartbeat.
  • Less garbage every frame in the core. The main loop keeps its delegates instead of making about 2 KB of new ones per frame,
    and the Wwise trace went from 11.9 KB to 0.0-0.2 KB per call in a heavy mod scene. No behaviour changes.
  • A better profiler. perf says how many garbage collections ran since perf reset and the longest pause among them, names
    the MCP server's parts (mcp.log, mcp.pump, mcp.discovery, mcp.sweep), and perf hide / perf show switch the renderers
    of a part of the scene off and on to measure what they cost.
  • Long MCP jobs are no longer cut at 10 minutes. A lockstep pass runs below real time on a busy machine: a 431 s take needed
    about 660 s of wall clock and was cut at 600 s. The other side: a job that hangs holds the control lane longer; restore or
    jobs {op:"cancel"} ends it at once.

New pitfalls from real filming are in the docs, each marked observed or inferred: the player-side clamp on keyed cameras, holds
under catmull, the plan pass and pinned CPU cores, and first-person flicker with a far clip.

How to use it all, step by step: docs/PLAY.md sections 4.7, 4.8 and 7.8, docs/MCP.md sections 8 and 13.1, docs/AUDIO.md section 11, docs/MULTICAM.md sections 12 and 16.

Everything you need is in the zip: copy bin\InsideDev.dll, bin\InsideDev.Mcp.dll and bin\InsideDev.Play.dll over the old ones in <game>\_mod\ (and tools\mcp\InsideDev.McpStdio.exe if you use the stdio launcher, tools\muter\InsideMuter.exe if you use the muter).

InsideDev 0.9.0

Choose a tag to compare

@sashaok123 sashaok123 released this 30 Oct 07:15

Film a planned camera over live play, from the game's own picture

Two console commands of the Play extension turn a camera plan into a real film of the running game. Both run only when
called and are stopped by restore or a game quit; nothing changes for anyone who does not use them.

  • Live director camera (campath). The main game camera follows a pose path planned in advance (mcam passes writes
    one for every camera of a MultiCam spec, or any script can write the two CSV files) while the game itself plays. Every
    frame is the game's own picture: live particles, shaders animated by time, mod effects and temporal anti-aliasing,
    which a replay of a recording cannot fully rebuild. The pose goes on the camera in Camera.onPreCull, after the game's
    camera script, so the game's camera logic, its culling and the input are untouched. In director mode the plan also
    drives the clock: the game is held still during the plan's pauses and runs at the plan's speed otherwise, with the drift
    corrected (measured under 0.04 s). campath mount rides the camera on a transform, for example the boy's head for a
    first-person pass, with optional smoothing of the head bob, a level horizon and timed looks at points or objects.
  • Video of the game's own frames (grec). At the end of every n-th rendered frame the back buffer is copied on the
    GPU by the native InsideReadback plugin; a background thread hands the frames to a separate ffmpeg process that
    encodes them with NVENC H.265. Windows over the game, focus changes and other programs never reach the file, unlike the
    desktop recorder of 0.8.0. 2560x1440 at 30 fps: 3222 frames grabbed, 0 dropped (laptop, RTX 3070 Laptop GPU).
  • Input tracks wait for the director camera. While campath holds the game still, an input_track playback no longer
    ends as stalled.

Where the work runs. The heavy part of grec runs off the game's main thread: the copy happens on the GPU on the
render thread, the hand-over on a background thread, the encoding in a separate ffmpeg process on the video engine of the
graphics card, so Windows spreads it over other CPU cores and the game keeps its frame time. Anything that touches game
objects (the camera pose, state, input) still runs on the game's main thread, as Unity 5.0 requires. Nothing is pinned to
a particular CPU core.

How to use them: docs/PLAY.md section 4.6 and workflow 7.7.

Everything you need is in the zip: copy bin\InsideDev.dll, bin\InsideDev.Mcp.dll and bin\InsideDev.Play.dll over the old ones in <game>\_mod\ (and tools\mcp\InsideDev.McpStdio.exe if you use the stdio launcher).

InsideDev 0.8.0: the editor and its AI tools no longer slow the game down

Choose a tag to compare

@sashaok123 sashaok123 released this 28 Oct 14:57

the editor and its AI tools no longer slow the game down

InsideDev used to cost the game most of its frame time. Every slowdown was found with measurements, not guesses, and
rewritten at its cause. Same place in the game, fresh start each time, laptop with a Core i7-11370H and an RTX 3070 Laptop
GPU at 2560x1440:

0.7.0 0.8.0
Game fps with the default overlays (trigger boxes, labels) 45 to 106 146 to 174
InsideDev's own time per frame while an AI agent works (perf) 7.2 ms, peaks 21 ms 0.57 ms, peaks 6.7 ms
Trigger and collider overlay per frame about 13 to 17 ms about 3 ms
Agent perception scans per frame, for 90 s after every tool call 6.6 ms 0.13 ms
A 53 s test pass filmed for review over 15 min (a screenshot every few steps) 53 s (real-time H.265 video)
One screenshot written to a file 2.0 to 3.1 s 0.6 s with fast:true
vSync on: a frame a little over 16.7 ms halved the game to about 30 fps off from the start

How they were found. The built-in profiler (console perf) splits InsideDev's time per subsystem, and the Play
extension's ticks now appear in it one by one (play.perception, play.stepper, play.changelog ...). Every overlay was
switched off and on alone on a fresh start, and every fix was measured again in the game.

What was wrong, and the fix:

  • Agent perception scanned the whole scene one game type at a time, every other frame. For 90 s after any MCP call
    the caches behind observe ran FindObjectsOfType for one of about 40 game types every other frame, and every such call
    walks all ~25 000 objects of the loaded levels: 6.6 ms of every frame, plus a garbage collection every few seconds on a
    450 MB heap with pauses up to 0.8 s. Now one FindObjectsOfType(MonoBehaviour) pass fills every type at once (each
    concrete class is matched to the tracked types once and remembered), and nothing runs in the background: observe
    refreshes what is stale when it is called, while the game waits for the agent anyway.
  • The trigger and collider overlay was rebuilt from nothing every frame. For every collider of every loaded level it
    asked the engine, every frame, whether the object was active and enabled and where its bounds were, then projected each
    box with 24 Camera.WorldToScreenPoint calls (120 for a sphere), and it re-read every collider's components every 10 s.
    Now each collider keeps its object, shape, world corners and bounds and asks the engine only every 8 frames, staggered;
    frustum culling and the projection run in C# from one view-projection matrix per frame, and a rescan classifies new
    colliders only. The same projection now draws savepoints, links and hidden markers.
  • vSync halved the frame rate. A frame a little longer than 16.7 ms waited for the next screen refresh, so the game
    sat at 30 to 37 fps. InsideDev is a development tool, so it keeps vSync off from the start (play.vsync_off=0 in
    editor.cfg gives the game its own vSync back).
  • Screenshots were the filming method. Every one is a PNG the game encodes on its main thread and the server decodes
    again to check for a black frame. Passes are now filmed as video instead, and a single shot can skip the decode.

New:

  • Real-time recorder: time {op:"record"} and {op:"record_stop", review_fps}, console rec start / rec stop.
    ffmpeg's ddagrab (DXGI Desktop Duplication: the graphics card copies the screen) and NVENC H.265 (preset p6,
    tune hq, cq 16, about 18 Mbit/s at 2560x1440 30 fps) film the game window, so the game's main thread does no capture
    work. The window and its monitor are found from inside the game; raise lifts the window to the top without taking
    focus; record_stop can cut JPG review frames. No library was added to the tool: ffmpeg 6.1 or later is an external
    program (on PATH, in <game>\_mod\ffmpeg\ or at INSIDEDEV_FFMPEG), and the encoder needs an NVIDIA GPU.
  • Frame meter: time {op:"state"} reports fps and frame_ms_max, the longest frame of the last second.
  • vSync switch: console vsync off|on|status, time {op:"vsync"}.
  • Fast screenshots: screenshot {mode:"path", fast:true} returns once the file is written.

Install

Copy bin\InsideDev.dll, bin\InsideDev.Mcp.dll, bin\InsideDev.Play.dll into <game>\_mod\ and tools\mcp\InsideDev.McpStdio.exe over the 0.7.0 files. For the recorder, put ffmpeg.exe (6.1 or later, with ddagrab) on PATH, in <game>\_mod\ffmpeg\ or point INSIDEDEV_FFMPEG at it.

InsideDevTool-0.8.0.zip sha256: 6bc5c424d71dc9ce1b55737a8a537aa46bf804109a1fa9056038fc7ddb2e8bed

InsideDev 0.7.0

Choose a tag to compare

@sashaok123 sashaok123 released this 27 Oct 17:58

Everything new is off until you use it; an existing install behaves as before after the update (the game sound is never muted, nothing records, no new hotkey acts unless you copy the module that has it).

What's new

  • MCP character control (InsideDev.Play.dll, optional): an AI assistant plays INSIDE through MCP. It sees the scene as JSON (the boy, nearby objects with ids and actions, hazards, the checkpoint), presses the game's controls for exact logic steps, walks to points, uses objects, waits for conditions, handles checkpoints and menus, reads playbooks and records input tracks. Needs only the MCP server. Connect to http://127.0.0.1:47811/mcp/play
  • MCP server: play / dev / all profiles (/mcp/play, /mcp = /mcp/dev, /mcp/all), jobs with progress and cancel, one JSON result shape, tool allowlist and token, plain POST /cmd, GET /state, GET /ping for scripts, automatic restore of the game 600 s after the last tool call. Existing clients keep the same address and tool names
  • Scene recorder (srec): records what moves in a scene into a take folder; the viewer holds the frozen scene at any time of the recording while you fly the free camera
  • MultiCam (mcam): films one scene with many cameras at once, or records it once and films every camera from the recording; example specs in specs\; optional InsideReadback.dll for faster replay grabs
  • Game audio capture (acap): the game's sound to WAV with sync markers; plays normally by default. The optional InsideMuter.exe mutes the game in Windows while it runs and is only for silent captures
  • Lab modules (InsideDev.ReplayLab.dll, InsideDev.Det.dll, optional): engine measurements for recording and replay, input replay determinism test
  • Python tools (tools\*.py): command-line control, recording reader, MultiCam spec checker, compositor and QA, audio alignment; guide playbooks (guide\) for the MCP guide tool
  • Docs: docs\AGENTS.md is the entry page for AI agents; full references in docs\

Install

  1. Copy bin\version.dll next to INSIDE.exe and bin\InsideDev.dll (plus bin\InsideDev.Mcp.dll for MCP) to <game>\_mod\
  2. Optional: bin\InsideDev.Play.dll and guide\ (to <game>\_mod\guide\) for character control, the lab DLLs to <game>\_mod\, bin\InsideReadback.dll to <game>\INSIDE_Data\Plugins\
  3. Start the game; F1 opens the editor; MCP clients: see tools\mcp\clients\ and the README

SHA-256

File SHA-256
bin\version.dll (unchanged) 5b195e16022f7011be3f4fb891294630120dbbe70197382ad93a2d8ba34272f6
bin\InsideDev.dll 81c642d32325072ed4b451e8db015789d5b735ea4dbf7305bd8dda0bc2e9bd23
bin\InsideDev.Mcp.dll 55a3a3dabdc0680a260aa30a8aee30ec48da62acbe8d8c3f7699bcac20cf06ba
bin\InsideDev.Play.dll eb8fa4a912691811bf3a7a8cdaf887144300a8ead07dc788fe9044fd93dc0168
bin\InsideDev.ReplayLab.dll e313f2f419b1c311943ea2c4382a5f8bb14ac11d469254ffe2afee01dc70f81d
bin\InsideDev.Det.dll f76a88e192fec3ea3fb057aac75b30030c174730412dcef1d736bd64f1d17f00
bin\InsideReadback.dll bae87e0b2692ddf2831d62d458ce275fc24c36a48756992b2116dd043d425373
tools\mcp\InsideDev.McpStdio.exe 276744733eebf6dafec0d5d11a36a0e48b631a6a73b07ac585a7905ce8ddb7e9
tools\muter\InsideMuter.exe 1a1e9889dec08b2a38a3981165060888cbd015508a09c1772c9c83a505e11461

Everything you need is in the zip.

InsideDev 0.6.0

Choose a tag to compare

@RedMatterGG RedMatterGG released this 25 Oct 04:03
4963684

Everything you need is in the zip.

First release

Choose a tag to compare

@RedMatterGG RedMatterGG released this 07 Oct 08:28

Drag and drop version.dll to the game root folder (INSIDE), meaning next to the INSIDE.EXE, create a folder called _mod also in the root and paste InsideDev.dll and start the game, the tool should create the _mod folder by itself if you launch it without InsideDev.dll

Your antivirus may flag version.dll, whitelist it if it does so.

InsideDev.dll:
https://www.virustotal.com/gui/file/4578e7b6985f2b4fcb1f22b45f148c70ec3d5119c2e10e98ab6f3c2d7bc7eb16

Version.dll:
https://www.virustotal.com/gui/file/5b195e16022f7011be3f4fb891294630120dbbe70197382ad93a2d8ba34272f6