Developer Console Sample
Samples~/Console/ is a drop-in runtime developer console: import the sample, hit the toggle key, and you have a live log viewer + command line in any scene without writing any code.
What You Get (Zero Setup)
- Captures
Debug.Log/LogWarning/LogError/ exceptions automatically - Auto-bootstrapped before the first scene loads (no GameObject to drag in)
- Toggle with
`(backtick) by default - 30+ built-in commands — app/time/scene control, PlayerPrefs, and a Linux-shell-style hierarchy browser (
cd,ls,tree,cat,rm,mv,cp, …). Full reference: Built-in Commands - Quote-aware Tab autocompletion: commands at the start of the line, GameObject paths after a space (relative to the current
cd'd node) - Command history (Up/Down arrows), scrollback, log timestamps
- Window mode (default): draggable macOS-style frame with title-bar zoom (
+/−, ~10% per click) and resize (drag the blue◥handle) — inherited fromRatatuiRenderer; see Resolution & Readability → OnGUI Window Mode
Boot Flow
The console is a Terminal App discovered via [RatatuiTerminalApp(Id = "console")]. Services and renderer bootstrap separately:
sequenceDiagram
participant U as Unity
participant TA as RatatuiTerminalApps
participant RC as RatatuiConsole
participant LC as ConsoleLogCapture
participant R as RatatuiConsoleRenderer
U->>TA: BeforeSceneLoad
TA->>TA: Discover [RatatuiTerminalApp] types
TA->>U: GameObject + AddComponent RatatuiConsoleRenderer
U->>RC: BeforeSceneLoad
RC->>RC: EnsureServicesBooted()
RC->>LC: Install() (subscribes to logMessageReceivedThreaded)
RC->>RC: BuiltinCommands.Register()
R->>RC: Awake → EnsureServicesBooted()
Note over R: Idle until toggle key pressed
No GameObject to add manually — import the sample and press Play.
Pieces
| File | Role |
|---|---|
RatatuiConsole.cs |
Public facade: Open/Close/Toggle, TerminalApps, RegisterCommand, Log, ClearLogs, accessors |
RatatuiConsoleConfig.cs |
ScriptableObject for dimensions, font size, toggle key, buffer sizes, colors |
RatatuiConsoleRenderer.cs |
[RatatuiTerminalApp] renderer that paints the log + prompt; uses TerminalCommandInput for the command line (see Input Handling) |
ConsoleLogCapture.cs |
Hooks Application.logMessageReceivedThreaded, owns the log ring buffer |
ConsoleCommandRegistry.cs |
Dictionary of registered commands, plus parser (Parse(raw, out name, out args)) |
ConsoleHistory.cs |
Command-line history (up/down recall) |
BuiltinCommands.cs |
Registration of the built-in commands listed above |
Resources/RatatuiConsoleConfig.asset |
Default config asset loaded at boot |
Usage from Game Code
Toggle / state
using RatatuiUnity.Samples.Console;
RatatuiConsole.Toggle(); // open or close
RatatuiConsole.Open(); // takes scene keyboard focus (RatatuiFocusManager)
RatatuiConsole.Close();
bool open = RatatuiConsole.IsOpen;
Register a custom command
RatatuiConsole.RegisterCommand("spawn", "Spawn N enemies. Usage: spawn 10",
args =>
{
if (args.Length == 0 || !int.TryParse(args[0], out int n))
{
Debug.LogWarning("Usage: spawn <count>");
return;
}
for (int i = 0; i < n; i++) EnemySpawner.Spawn();
});
Anything sent to Debug.Log from inside a command shows up in the console output.
Push a message directly
RatatuiConsole.Log("Player connected: " + playerId);
Execute a command programmatically
RatatuiConsole.ExecuteCommand("time_scale 0.5");
Built-in Commands
All commands below are registered automatically by BuiltinCommands.Register() at boot. They are listed by category. Argument syntax: <required> [optional] a|b (alternatives).
Use help at runtime to print the live list.
Console & application lifecycle
| Command | Description |
|---|---|
help |
Print every registered command with its description. |
clear |
Empty the log ring buffer. |
quit |
Exit the app (Application.Quit); in the Editor, leaves play mode. |
echo <text…> |
Print the joined argument string back to the console. |
version |
Unity version, product name + Application.version, platform, editor/player flag. |
sysinfo |
OS, device, CPU/GPU, memory totals, screen resolution + refresh rate, platform, internet reachability. |
gc |
Force GC.Collect() and print managed-memory delta. |
Terminal apps
For every app registered in RatatuiTerminalApps, BuiltinCommands.Register() adds a matching pair of commands at boot. The console sample registers as id console, so you get open_console and close_console. A custom app with id debug gets open_debug and close_debug.
| Command | Description |
|---|---|
open_<id> |
Open the terminal app with the given id (RatatuiTerminalApps.Open). |
close_<id> |
Close the terminal app with the given id (RatatuiTerminalApps.Close). |
Use help at runtime for the full list — it reflects every registered app. From code, RatatuiConsole.TerminalApps exposes the same registry as RatatuiTerminalApps.Apps.
Emitting log entries (for testing capture)
| Command | Description |
|---|---|
log_warning <text…> |
Emit a Debug.LogWarning. |
log_error <text…> |
Emit a Debug.LogError. |
log_exception <text…> |
Emit a Debug.LogException(new Exception(text)). |
Time & framerate
| Command | Description |
|---|---|
fps |
Current FPS, deltaTime, unscaledDeltaTime, timeScale, targetFrameRate. |
time_scale [value] |
No arg: print current Time.timeScale. With value: set it (clamped ≥ 0). |
target_fps [value] |
No arg: print current Application.targetFrameRate. With value: set it (-1 = unlimited). |
pause |
Set timeScale to 0; remembers the prior value. |
resume |
Restore the timeScale captured by the most recent pause. |
Scene control
| Command | Description |
|---|---|
scene |
Active scene name + build index, and every loaded scene (Single/additive). |
scene_load <name\|index> [additive] |
Load by scene name or build index. Append additive for LoadSceneMode.Additive; default is Single. Validates against build settings. |
scene_reload |
Reload the currently active scene via its build index, Single mode. |
PlayerPrefs
prefs <subcommand> [args…] — flat namespace with five subcommands:
| Form | Description |
|---|---|
prefs get <key> |
Print the stored value. Probes string → float → int (PlayerPrefs is untagged). Reports (not set) if missing. |
prefs set <key> <value> |
Infer the type from <value>: parses int first, then float, otherwise stores as string. Auto-saves. |
prefs del <key> |
Delete one key (alias: prefs delete). Auto-saves. |
prefs clear |
PlayerPrefs.DeleteAll() + save. No confirmation. |
prefs save |
Force PlayerPrefs.Save() (set/del/clear already save). |
Hierarchy navigation
These behave like a Linux shell where each GameObject is a directory containing its child GameObjects. The current path lives in a static _cwd, defaults to / (virtual scene root). Inactive GameObjects are visible — they live in the hierarchy regardless of SetActive state.
| Command | Description |
|---|---|
pwd |
Print the current path. |
cd [path] |
Change current path. No arg → /. Accepts absolute (/Player/Body), relative (Body), .., .. Fails with "Path not found" if the resolved path is missing. |
ls [path] |
List immediate children of path (or _cwd). Each row: Name (Comp1, Comp2, …). Inactive children have a trailing *. |
tree [path] [depth] |
Tree view with box-drawing connectors. No arg → use _cwd. Depth defaults to 3. tree 5 is shorthand for "current node, depth 5". Truncates at 500 nodes; dirs cut off by depth show …(N) with the unshown child count. |
Path syntax recap:
/A/B— absolute, from scene root.A/B— relative to_cwd...pops one segment,.is a no-op./alone refers to the virtual scene root (the container of all scene-root GameObjects).- A name with spaces must be quoted:
cd "Main Camera".
Hierarchy inspection
| Command | Description |
|---|---|
cat [path] |
Multi-line dump of one GameObject: name + active state, absolute path, scene/layer/tag/static, activeSelf vs activeInHierarchy, local pos/rot/scale, parent path, child names, component types. Refuses the virtual root. |
Hierarchy mutation
These run in both edit-mode and play-mode (Destroy vs DestroyImmediate is chosen automatically). No confirmation prompts — pair with discipline.
| Command | Description |
|---|---|
rm <path> |
Destroy the GameObject (and its subtree). Refuses to destroy the virtual root. |
mv <src> <dest> |
POSIX semantics. If dest is an existing GameObject → move src into it under its original name. If dest doesn't exist → split into parent + new name; parent must exist, src is reparented and renamed. Detects parent-into-descendant cycles. |
cp <src> <dest> |
Same destination rules as mv, but instantiates a clone (Object.Instantiate) instead of moving. The clone takes the resolved name — no (Clone) suffix. |
enable <path> |
SetActive(true). |
disable <path> |
SetActive(false). |
toggle <path> |
Flip activeSelf. |
mv / cp destination semantics in one table:
| Form | dest state |
Result |
|---|---|---|
cp A B |
B missing, parent (/) exists |
clone at /B |
cp A B |
B exists |
clone is added under B, named A |
cp A / |
always | clone at /A (scene root) |
cp A /X/Y |
/X/Y missing, /X exists |
clone at /X/Y |
cp A /X/Y |
/X/Y exists |
clone under /X/Y, named A |
cp A /X/Y |
/X missing |
error (destination parent not found) |
Tab autocompletion
Tab completes whichever token the cursor is in:
- Before the first space → command-name completion against the registry.
- After the first space → path completion of the last whitespace-delimited token, resolved against
_cwd.
Behaviour details:
- The popup shows up to 6 suggestions;
↑/↓cycle through them,Tabapplies the highlighted one. Suggestions for directories (nodes with children) show a trailing/and do not insert a trailing space, so you can immediately keep typing the next segment. - Quote-aware: if a candidate name contains a space, the inserted text wraps the affected segment in quotes (e.g.
cd "Main Camera",cd "Main Camera"/Body). Tokens you start with an unmatched"are recognised — typingcd "Main Ca<Tab>completes the quoted segment correctly. - Detail column shows the first three components of the candidate (
Transform, Camera, AudioListener, …).
Programmatic access
Built-in commands are just registrations against RatatuiConsole.RegisterCommand. Anything you register at runtime appears in help, in autocomplete, and via ExecuteCommand. Override a built-in by registering the same name — the registry stores by key, so the later registration wins.
Configuration
Either edit Samples~/Console/Resources/RatatuiConsoleConfig.asset after import, or create your own via Assets → Create → Ratatui → Console Config and drop it under any Resources/ folder named exactly RatatuiConsoleConfig.
Knobs:
| Field | Default | Purpose |
|---|---|---|
cols, rows |
120 × 32 | Fallback terminal grid. The console enables Fit Cols And Rows, so the grid is derived from the available pixel area at startup (these values are only used if that area is unavailable). |
fontSize |
1.6 | Glyph size. Interpreted per sizingMode: absolute pixels in Pixel, or percent of the viewport in Vh / Vw / Vmin / Vmax |
sizingMode |
Vmin |
How fontSize is interpreted. Vmin = percent of the smaller viewport dimension, so glyphs stay readable in both portrait and landscape |
displayMode |
Window |
Full stretches to screen, Partial uses native pixel size, Window is a draggable frame whose title bar shows the host GameObject name |
windowStartMaximized |
true |
When displayMode is Window, maximize on first open |
horizontalAlign / verticalAlign |
Center / Top | Placement in Partial mode |
backgroundColor |
#121221 |
Terminal background |
toggleKey |
` (BackQuote) |
Open/close key |
maxLogEntries |
2000 | Log ring buffer size |
maxHistoryEntries |
64 | Command history size |
showTimestamp |
true | Prefix each line with [HH:mm:ss] |
RatatuiConsoleRenderer applies the config in ApplyConfigToBase and always enables Fit Cols And Rows, so zoom and resize both keep the log grid filled to the current window content area.
Adjusting readability at runtime
With the default displayMode of Window:
- Open the console (
`by default). - Use the blue + / − buttons on the title bar to zoom glyph size in or out (~10% per click, clamped to 1–200 in the active sizing units).
- Drag the blue ◥ resize handle (far right) to change how much screen area the window occupies without changing glyph scale; the column/row count adapts on release.
Zoom works even when the window is maximized (green traffic-light). Resize is disabled while maximized. Initial fontSize and sizingMode from the config asset set the starting scale; zoom adjusts from there for the session (not persisted back to the asset).
For viewport-relative sizing (Vmin, etc.), see Resolution & Readability.
Caveat: Input System
Terminal apps (including the console) use UnityEngine.Input (legacy). If your project has Player Settings → Active Input Handling = "Input System Package (New)", RatatuiTerminalApps logs a warning at boot and does not instantiate apps. Set it to "Both" or "Input Manager (Old)" to use this sample as-is. See Terminal Apps.
Extending
To replace just the renderer (custom layout, different keybinds) while keeping the log capture + command registry: implement your own MonoBehaviour : RatatuiRenderer and use RatatuiConsole.Logs, RatatuiConsole.Registry, RatatuiConsole.History as data sources. The facade stays — only the visual layer changes.