On this page
tecs.debug
Debugger commands, and the tools they project to.
A command is declared once. Its argument schema types both a typed command line and a JSON tool call, its action returns one structured result, and the debug server advertises it with an input schema, an output schema and safety hints that were all derived from that single declaration. Nothing about a command is written twice, so the two surfaces cannot disagree.
Getting the commands
tecs.io.mcp does not install them. An application with mcpPort set calls ensure for its own world, so every session that has a debug server has the whole command surface. A headless tool calls ensure itself.
Adding one
local debugapi <const> = require("tecs.debug")
debugapi.ensure(world)
debugapi.register(
world,
{
name = "wave",
section = "Custom",
shortHelp = "report the wave the game is on",
agentHelp = "Reports the current wave number and how many enemies are left in it. "
.. "Call it to check progress before spawning or despawning anything.",
readOnly = true,
outputSchema = {
["type"] = "object",
properties = {
wave = {["type"] = "integer"},
remaining = {["type"] = "integer"},
},
required = {"wave", "remaining"},
},
run = function(_values: {string: any}): debugapi.Result
return {
message = "wave " .. tostring(state.wave),
data = {
wave = state.wave, remaining = state.remaining
},
}
end,
}
)That registers the tool wave. A command with subcommands registers one tool per verb, named <command>_<verb>, and registers <command> as well when it carries a run of its own.
Results and failures
Result.data is the tool call's structured content, and Result.message travels beside it under the key message. A result with ok = false raises its code and message through the tool call, so an agent reads a failure the way it reads any other tool error rather than by inspecting a field.
Declare outputSchema on anything a game ships. It is what lets an agent know the shape of an answer before it makes the call, and it is what the reference renders.
Command names are a compatibility surface
A tool name is generated from a command name and a verb name, so renaming either renames a tool that an agent already calls. Choose both once.
Requiring this module as debug shadows Lua's own debug library. A module that needs both binds this one as debugapi.
Module contents
Types
| Type | Kind | Description |
|---|---|---|
ArgSpec |
record | Declares one argument. |
Command |
type | Declares one command. |
Registry |
type | Holds the commands one world has declared. |
Result |
record | Reports what one command did. |
Schema |
record | Declares a command's arguments. |
Subcommand |
record | Declares one verb under a command. |
Functions
| Function | Kind | Description |
|---|---|---|
bindRenderer |
Static | Tells the commands which renderer draws this world. |
ensure |
Static | Builds the world's command registry, or returns the one it already has. |
of |
Static | Returns the registry installed in world. |
register |
Static | Registers a game's own command and projects it onto the debug server. |
Values
| Value | Type | Description |
|---|---|---|
SECTIONS |
{string} |
Read-only. Groups commands in help and in the generated reference, in the order they are presented. |
Types
tecs.debug.ArgSpec record
Declares one argument.
record tecs.debug.ArgSpec
required: boolean
default: any
help: string
forward: string
synthetic: {string}
kind: string
enum: {string}
min: number
max: number
rest: boolean
endtecs.debug.ArgSpec.required field
Caller-writable. Requires the argument to hold a value once parsing finishes.
tecs.debug.ArgSpec.default field
Caller-writable. Supplies the value used when the argument is absent, and infers the value type when kind is omitted. A forwarding argument never receives its default, which only types it.
tecs.debug.ArgSpec.help field
Caller-writable. Describes the argument in generated help and in the MCP tool schema.
tecs.debug.ArgSpec.forward field
Caller-writable. Names the synthetic argument this argument feeds its value into.
tecs.debug.ArgSpec.synthetic field
Caller-writable. Lists the source argument names this synthetic argument accepts, and its presence marks the argument synthetic, so users neither name it nor see it.
tecs.debug.ArgSpec.kind field
Caller-writable. States the value type explicitly, as "number", "boolean", "string", "list", "table" or "rows". Omitting it infers the type from default, so set it for an optional typed argument that has no default, such as a number that leaves the current value unchanged when absent. A "list" is a comma-separated string on the command line and a JSON string array over MCP. A "table" is a brace-balanced Lua expression on the command line and a JSON object over MCP. A "rows" argument is that same expression on the command line and a JSON array of objects over MCP, so an action receives either a string or a table and handles both.
tecs.debug.ArgSpec.enum field
Caller-writable. Restricts a string argument to these values, and projects to a JSON Schema enum.
tecs.debug.ArgSpec.min field
Caller-writable. Bounds a number argument from below, inclusively.
tecs.debug.ArgSpec.max field
Caller-writable. Bounds a number argument from above, inclusively.
tecs.debug.ArgSpec.rest field
Caller-writable. Makes the slot consume every remaining token as free text, joined with single spaces, where a quoted span keeps its inner spacing. The argument must be the last positional slot and must be string-, table- or rows-typed.
tecs.debug.Command type
Declares one command.
type tecs.debug.Command = debugtypes.Commandtecs.debug.Registry type
Holds the commands one world has declared.
type tecs.debug.Registry = registry.Registrytecs.debug.Result record
Reports what one command did.
tecs.debug.Result.ok field
Caller-writable. Reports whether the command did what it was asked. Omitted counts as success. False raises the command's message through the tool call rather than answering with it.
tecs.debug.Result.code field
Caller-writable. Names the failure in a word an agent can match on, such as no_match or invalid_ref. Required when ok is false and ignored otherwise.
tecs.debug.Result.message field
Caller-writable. Summarizes the outcome for a person in one line. A successful command carries it beside its data under the key message.
tecs.debug.Result.data field
Caller-writable. Carries the structured answer, which is what the tool call returns and what outputSchema describes. Omitted answers with the message alone.
tecs.debug.Schema record
Declares a command's arguments.
record tecs.debug.Schema
args: {string: ArgSpec}
positional: {string}
endtecs.debug.Schema.args field
Caller-writable. Maps each argument name to the spec that types it.
tecs.debug.Schema.positional field
Caller-writable. Lists the argument names bound by position, in order. A slot may name a synthetic argument.
tecs.debug.Schema.positional: {string}tecs.debug.Subcommand record
Declares one verb under a command.
record tecs.debug.Subcommand
name: string
aliases: {string}
shortHelp: string
agentHelp: string
schema: cmdargs.Schema
examples: {string}
outputSchema: {string: any}
readOnly: boolean
destructive: boolean
run: function({string: any}): Result
endtecs.debug.Subcommand.name field
Caller-writable. Names the verb. The projected tool is <command>_<name>, so this string is part of an externally typed surface once it ships. Required.
tecs.debug.Subcommand.name: stringtecs.debug.Subcommand.aliases field
Caller-writable. Names other spellings that dispatch to this verb on a typed command line. Aliases are never projected as tools.
tecs.debug.Subcommand.aliases: {string}tecs.debug.Subcommand.shortHelp field
Caller-writable. Says what the verb does in one line, lowercase and without a trailing period. Required.
tecs.debug.Subcommand.shortHelp: stringtecs.debug.Subcommand.agentHelp field
Caller-writable. Says what an agent needs: when to call this, what it changes, what it answers with, and what to call next. The projected tool description falls back to shortHelp, which is written to fit one line rather than to brief an agent.
tecs.debug.Subcommand.agentHelp: stringtecs.debug.Subcommand.schema field
Caller-writable. Declares the arguments. Omitted means the verb takes none.
tecs.debug.Subcommand.schema: cmdargs.Schematecs.debug.Subcommand.examples field
Caller-writable. Shows complete command lines that work, for the generated reference and the usage output.
tecs.debug.Subcommand.examples: {string}tecs.debug.Subcommand.outputSchema field
Caller-writable. Describes Result.data as a JSON Schema. The projection advertises it as the tool's outputSchema, so an agent knows the shape of the answer before making the call.
tecs.debug.Subcommand.outputSchema: {string: any}tecs.debug.Subcommand.readOnly field
Caller-writable. Declares that the verb only reads. Omitted derives the answer from the verb: list, info, status and get read.
tecs.debug.Subcommand.readOnly: booleantecs.debug.Subcommand.destructive field
Caller-writable. Declares that the verb destroys something a caller cannot get back. Omitted derives the answer from the verb.
tecs.debug.Subcommand.destructive: booleantecs.debug.Subcommand.run Static
Caller-writable. Runs the verb. Required.
function tecs.debug.Subcommand.run({string: any}): ResultArguments
| Name | Type | Description |
|---|---|---|
#1 |
{string : any} |
Returns
| Type | Description |
|---|---|
Result |
Functions
tecs.debug.bindRenderer Static
Tells the commands which renderer draws this world.
Commands that read or draw through the renderer answer with a failure until something calls this, since a world alone does not name one.
Arguments
| Name | Type | Description |
|---|---|---|
world |
types.World |
The caller supplies the world the renderer draws. |
renderer |
Renderer |
The caller supplies the renderer, or nil to unbind. |
Returns
None.
tecs.debug.ensure Static
Builds the world's command registry, or returns the one it already has.
Registering the engine's own commands projects each of them onto the debug server, so a session that calls this once has the whole surface. Calling it again answers with the same registry and registers nothing further.
Arguments
| Name | Type | Description |
|---|---|---|
world |
types.World |
The caller supplies the world the commands read and write. |
Returns
| Type | Description |
|---|---|
registry.Registry |
The world's registry. |
tecs.debug.of Static
Returns the registry installed in world.
Arguments
| Name | Type | Description |
|---|---|---|
world |
types.World |
The caller supplies a world with or without a registry. |
Returns
| Type | Description |
|---|---|
registry.Registry |
The world's registry, or nil before ensure has run. |
tecs.debug.register Static
Registers a game's own command and projects it onto the debug server.
Raises when the world has no registry, and raises on a malformed declaration: a command is written once and called forever, so a mistake in one belongs at the call that made it.
Arguments
| Name | Type | Description |
|---|---|---|
world |
types.World |
The caller supplies a world ensure has already run on. |
command |
debugtypes.Command |
The caller supplies a complete declaration. |
Returns
None.
Values
tecs.debug.SECTIONS variable
Read-only. Groups commands in help and in the generated reference, in the order they are presented. A command that names no section groups as "Custom".
tecs.debug.SECTIONS: {string}