Skip to content

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