Skip to content

Operations

Tom_XV edited this page Sep 23, 2026 · 6 revisions

English | 日本語

Experimental. This came in with framework 1.4.0 and may change or go away in a later version.

Operations is a registry in the core (DragNWash.ModFramework, class Operations). It lists what each library and mod can do, by name, with plain arguments. The Console's op command and the Bridge's MCP tools both run on it, and those tools are how AI clients (Claude Code, VS Code, Cursor) on this computer read the game. The core only keeps the registry, and each library registers its own operations.

The design is in docs/API_PLAN.md (stage 1).

What an operation is

Part Meaning
Name library.noun.verb, lower case, no spaces: inspector.member.get, saves.flags.list
Description One line on what it does, for people and AI clients
Parameters Each with a name, a type (String, Number or Boolean), whether it is required, a description and, when only some values are accepted, the choices
Kind Read (changes nothing) or Write (changes something in the game)
Returns One line on what it returns
Owner The GUID of the mod that registered it

Vectors and colours travel as text, written the way the Inspector's rows show them.

Registering one

Operations.Register(MyMod.Guid, "mymod.items.list", "The items my mod knows, optionally only those whose name contains a text.",
    OperationKind.Read, "a list of { name, count }",
    args =>
    {
        string filter = args.String("filter");
        int max = args.Int("max", 20);
        return Items(filter, max);   // lists, dictionaries, text, numbers, true/false
    },
    Operations.Parameter("filter", OperationType.String, "Only names that contain this."),
    Operations.Parameter("max", OperationType.Number, "At most this many (20 when left out)."));
  • Operations.Register(ownerGuid, name, description, kind, returns, run, params parameters) returns the Operation, or null when the name is already taken (the log names who has it). A name with capitals or spaces throws.
  • Operations.Parameter(name, type, description, required = false, params choices) makes a parameter. If you give it choices, only those values are accepted (case doesn't matter).
  • Your function gets an OperationArgs, with Has(name), String(name, fallback), Number(name, fallback), Int(name, fallback), Bool(name, fallback).
  • It returns plain values: null, text, numbers, true/false, and lists and text-keyed dictionaries of these. Anything else is written out as its text. To fail with a message, throw.
  • Name your operations after your mod (mymod.…) so they don't collide with anyone else's.

Finding and calling

  • Operations.All has every operation, by name, and Operations.Find(name) gives you one, or null.
  • Operations.CallNow(name, args, caller) calls it right away, on the main thread only, and returns an OperationResult (Ok, Value, Error, ToJson()).
  • Operations.Call(name, args, caller, done) works from any thread. The operation runs on the main thread at the next frame, and done gets the result there.
  • caller names who asked ("console", "mcp:<client>"), for the log.
  • Arguments are checked against the parameters before the operation runs. A missing required one, an unknown name or a value of the wrong type is an error, and text is turned into numbers and true/false where the parameter says so.
  • Operations.ToJson(value, indented) writes a result as JSON.

Rules every call follows

  • Unity objects may only be touched on the main thread, so every operation runs there, whoever called it.
  • A result longer than 200,000 characters of JSON (Operations.MaxResultChars) is an error that asks you to narrow the call down.
  • Every call is logged with who made it, its arguments and whether it worked. Write operations log at Info, read operations at Debug. An operation can see who asked in OperationArgs.Caller.
  • A write says how to undo itself with OperationArgs.TakeBack(label, undo, before, after), and the registry raises Operations.Written with it. That's how the Inspector's History can list a change another mod made. If you write undo as a Func<bool>, it says whether it really put the value back. It returns false when the object is gone or somebody else has written the value since, so a caller counting what it undid only counts the changes that really went back.
  • When a mod is reloaded or unloaded, its operations go with it.
  • Operation.Audience, set right after Register, says at which doors an operation is offered: Console (the F1 window), Page (the Bridge's page on this computer), Mcp (an AI client) and Graphs (a data mod's graph, see Graphs). The default is Anyone, which means all four. Anything that shows the game's own code is Console | Page (the Code graph), and the editor's own operations are Console | Page too, writes included.
  • The Bridge only offers AI clients read operations, and only the ones whose audience has Mcp. It never offers a write, whoever asks.

The console's op

You'll find it in the Console, which is part of the Tool window library:

Command Does
op lists every operation; write ones are marked [write]
op help <name> describes one: kind, owner, each parameter with its type, and what it returns
op <name> key=value ... runs it and prints the result as JSON (a list gets one item per line)

Tab completes names and parameters.

op inspector.objects.find text=Light max=10
op saves.flags.list slot=1 filter=intro

The operations the framework registers

They're all reads, except bridge.page.open.

Library Operation Parameters Returns
Core mods.list the mods on the Mods screen: guid, name, version, loaded, on next launch, library, authors, description
Core mods.network where mods connected this session, and whether each host is declared
Core game.info framework, Unity and graphics versions, Direct3D 12 or not, OS, screen, developer tools
Core scene.list the active scene, the scenes loaded, every scene in the game's build
Tool window log.read max, source, level the last console lines: time, level, source, text
Inspector inspector.objects.find text (required), max objects whose name contains the text: path, scene, active
Inspector inspector.objects.children path an object's children, or the root objects when no path is given
Inspector inspector.components.list path (required) an object's components in order, with each one's index among its type
Inspector inspector.member.get path, component (both required), index, member, private a component's members as the Inspector shows them, or one member
Inspector inspector.selection.get what is selected in the Inspector
Inspector code.graph method (required), stub a method of the game as blocks and branches (page only)
Inspector code.type type (required) a type's methods in groups and the calls between them (page only)
Inspector code.callers method (required) the methods that call a method (page only)
Inspector code.search text (required), max types and methods whose name contains the text (page only)
Inspector code.stats how big the code index is (page only)
Assets assets.textures.list filter, max textures loaded in memory, with their size
Assets assets.materials.list filter, max materials loaded, with their shader and textures
Assets assets.meshes.list filter, max meshes loaded, with vertex and sub-mesh counts
Assets assets.replacements.list filter the texture replacements mods ship: texture, mod, language, file
Assets assets.fonts.language the language the fonts are prepared for
Dialogue dialogue.current the node running, whether lines or options show, the last line
Dialogue dialogue.recent text, max the last lines and options shown this session (up to 100), with the speaker
Text text.rewriters the mods that rewrite the game's text, in order
Text text.shown text (required), max text on screen: what the game set and what is shown
Flags and saves saves.list save slots, with their level and history copies
Flags and saves saves.flags.list slot (required), filter the event flags in a slot, with what the flag catalog says
Flags and saves saves.flags.get slot, id (both required) one event flag
Bridge bridge.page.open (write) focus opens the Bridge's page on this computer, signed in
Overrides objects.writes what the Overrides library has changed this session, who asked, and the mods that changed the same thing

1.4.1 added the Overrides library's three writes for Graphs (objects.member.set, objects.material.set, objects.active.set), plus the Graphs library's own graphs.*, which the page's editor uses and nobody else sees.

For each parameter's description and limits, type op help <name> in the console.

Clone this wiki locally