💎 Hidden Gems
Public API that NjConsole uses internally and you’re welcome to use too, but that doesn’t get its own page elsewhere. Handy for building your own debug tools on top of the console.
These are public and won’t be removed casually, but expect less hand-holding than the guided flow.
📦 What survives stripping
Stripping the console compiles most of it out of the build. A few entry points keep a do-nothing stub so your code still compiles; everything else disappears and must be wrapped:
#if !NJCONSOLE_DISABLE
ConsoleTextPrompt.Show(data);
#endif
| ✅ Safe to call unguarded | ❗ Must be wrapped in #if !NJCONSOLE_DISABLE |
|---|---|
NjConsole.* — Options, KeyBindings, Overlay, Settings, Modules |
ConsoleTextPrompt |
ConsoleToasts |
ConsoleInspector |
Everything in Ninjadini.Logger — NjLogger, LogChannel, LogsHistory, StrValue |
ConsoleGraphingElement, FpsMonitorElement, MemoryMonitorElement |
ColoredLogChannel |
ConsoleUtilitiesElement — the log export helpers |
ConsoleModules, ConsoleSettings |
ConsoleWindow, ConsoleLogsPanel, ConsoleScreenShortcuts |
ConsoleContext.SetData() / GetData() / Storage |
ConsoleContext.TryGetFocusedContext() / RuntimeOverlay |
ConsoleKeyBindings, including IsUserTyping() |
ConsoleScreenShortcuts, including its IRestorable |
Every IConsole* interface you implement |
StringParser, ConsoleUIUtils |
💡 Rule of thumb: reached through the
NjConsolestatic, it’s stubbed; named as a UI class directly, it isn’t. This bites on naming the type at all — implementing a stripped interface or using it as a generic argument breaks the build just like calling into it, so the guard goes around the whole declaration.
🍞 Toasts
A transient message at the top of whichever console window has focus — good for confirming a debug action ran. Stubbed, so no guard needed.
using Ninjadini.Console;
ConsoleToasts.TryShow("Save wiped");
// ... with a call-to-action button
ConsoleToasts.TryShow("Save wiped", () => NjConsole.Overlay.Hide(), "Close");
TryShow() falls back to the log if no console window exists; Show(context, ...) targets a specific window.
Both return the toast element — RemoveFromHierarchy() to dismiss early.
⌨️ Text prompts
The modal input dialog behind the Options panel’s text and number items (Options Menu). Call it directly when you need input somewhere else.
❗ Needs
#if !NJCONSOLE_DISABLE— this class has no stub.
#if !NJCONSOLE_DISABLE
ConsoleTextPrompt.Show(new ConsoleTextPrompt.Data()
{
Title = "Server URL",
InitialText = MyGame.ServerUrl,
ResultCallback = (txt) =>
{
if (txt == null) return true; // close button - accept and dismiss.
if (!txt.StartsWith("https://")) return false; // reject, prompt stays open and flashes red.
MyGame.ServerUrl = txt;
return true;
}
});
#endif
| Method | Where it draws |
|---|---|
Show(Data) |
Own UIDocument above the game. Play mode only. Returns it, destroyed for you on success. |
ShowInConsoleRoot(visualSrc, Data) |
Inside the console window visualSrc belongs to. Works in editor windows. |
Show(parent, Data) |
A child of parent, to place it yourself. |
Data also carries auto-complete (AutoCompleteResultsCallback), password masking, multiline and mobile
keyboard type. Data.CreateForNumberInput(setter) preconfigures numeric input for float / double /
int / uint / long / ulong.
🔍 Object inspector from your own code
Inspector covers the panel. The programmatic hooks:
// Draw your own type however you like - applies everywhere the inspector shows it.
ConsoleInspector.RegisterCustomDrawer(typeof(MySaveData), (obj, foldOut) =>
{
var data = (MySaveData)obj;
foldOut.Add(ConsoleInspector.CreateInfo("coins", typeof(int),
() => data.Coins, v => data.Coins = (int)v));
});
// Open the inspector on any object, from inside a console panel.
ConsoleInspector.Show(someContainerElement, myObject);
ConsoleInspector.AutoReadProperties and CustomFieldCreator are the other two static hooks.
📌 Pin your own widget to the screen shortcuts
The corner shortcuts — where the FPS and memory graphs live — accept any VisualElement. Implement
ConsoleScreenShortcuts.IRestorable so the console can rebuild your widget after a restart, then add it.
❗
IRestorableis nested inside the strippedConsoleScreenShortcuts, so the whole class needs the guard — a guard around just the method body won’t compile, because the base list still names the interface.
#if !NJCONSOLE_DISABLE
class MyWidget : IConsoleModule, ConsoleScreenShortcuts.IRestorable
{
string ConsoleScreenShortcuts.IRestorable.FeatureName => "myWidget";
VisualElement ConsoleScreenShortcuts.IRestorable.TryRestore(ConsoleContext context, string path)
=> path == "hp" ? new Label("HP") : null;
public void PinIt(ConsoleContext context)
=> context.RuntimeOverlay?.Shortcuts?.AddNewItem(this, "hp");
}
#endif
⚠️
FeatureNameand the path are persisted — renaming them orphans the user’s pinned shortcuts.
📈 Your own graphs
The element behind the built-in FPS and memory monitors. Pair it with the shortcuts above to pin a live graph on screen.
var graph = new ConsoleGraphingElement(width: 120, pixesPerValue: 2f, intervalMs: 100);
graph.Add(new IConsoleGraphDataProvider.Simple("enemies", Color.red, () => MyGame.EnemyCount));
graph.ValueSuffix = " units";
Subclass to override Update(), AddValueLabel() or UpdateLabelValue(). ForcedMinBound / ForcedMaxBound
pin the scale when auto-ranging isn’t what you want.
📜 Reading the log history yourself
NjLogger.LogsHistory is the ring buffer of everything NjLogger captured. Always available — nothing in
Ninjadini.Logger is stripped by NJCONSOLE_DISABLE, which is what makes it usable for crash reports.
See Logging.
using Ninjadini.Logger;
// The LogsHistory type itself lives in Ninjadini.Logger.Internal - only needed if you name it.
NjLogger.LogsHistory.ForEachLogNewestToOldest(line => Report(line.GetLineString()), maxLogs: 200);
var sb = new StringBuilder();
NjLogger.LogsHistory.GenerateHistoryNewestToOldest(sb, maxLogs: 500);
GetLevelCount(level)— a cheap running count, good for an on-screen error badge.StartBackLoggingLock()/StopBackLoggingLock()— stop old lines recycling while the user scrolls back.
🐞 Your own bug-report button
The Utilities panel’s export buttons are public statics, so you can wire the same behaviour to your own UI.
For the format, implement IConsoleLogExportFormatter
(Logging).
#if !NJCONSOLE_DISABLE
var context = ConsoleContext.TryGetFocusedContext();
if (context != null)
{
var text = ConsoleUtilitiesElement.GenerateTextLog(context); // header + logs + footer
ConsoleUtilitiesElement.EmailTextLog(context); // opens a mail draft
ConsoleUtilitiesElement.ExportHtmlLog(context); // shareable HTML file
}
#endif
🧰 Adding a page to the Utilities panel
Your own screens next to Tools / App Info / Device Info. Safe unguarded.
NjConsole.Settings.CustomUtilitiesMenus += (context, addMenu) =>
{
addMenu("My Tools", () => new Label("Hello from my tools"));
};
Use +=, not =, so you don’t wipe out other systems’ menus. It runs once per console window, so the editor
window and runtime overlay each get their own. For a full panel instead of a sub-page, see
Custom Panels.
🎛️ Driving the overlay
These live on the stubbed NjConsole static, so they’re safe unguarded. See Console Window.
NjConsole.Overlay.Toggle(); // show if hidden, hide if showing
NjConsole.Overlay.SetActivePanel("Utilities"); // by side-bar name - always safe
NjConsole.Overlay.Instance.Scale = 1.5f; // user-facing UI scale, persisted
NjConsole.Overlay.Instance.HideErrorDisplayedAtTop();
NjConsole.Overlay.Destroy(); // tear the runtime console down
#if !NJCONSOLE_DISABLE
// The generic overload names a panel type, and the built-in panel classes are stripped.
NjConsole.Overlay.SetActivePanel<ConsoleLogsPanel.Module>();
#endif
🧩 Odds and ends
ConsoleContext.SetData(obj)/GetData<T>()— per-window state keyed by type, for as long as the window lives.context.Storageis the persisted version: PlayerPrefs at runtime, serialised into the editor window.ConsoleKeyBindings.IsUserTyping()— true while a text field has focus. Check it before acting on raw key input, so your shortcuts don’t fire while someone types in the command line.NjConsole.Settings.CustomStackTraceFrameSkip— hide your logging wrapper’s frames so double-clicking a log lands on the real call site.NjConsole.Settings.PlayerPrefKeysProvider— feed your known keys into Utilities > Player Prefs.ConsoleModules.ModuleAdd/ModuleRemoved— react to modules coming and going. Unsubscribe:ConsoleModulesis shared across windows and play sessions, so it leaks fast.StringParser— parsing helpers behind the Command Line.GetRemainingPartialMatch()is the one forIConsoleCommandlineModule.FillAutoCompletableHints(). Needs a guard.ConsoleObjReferenceStorage— the command line’s named object store (_,@,$name). Write to it from your own command line module so users can pass objects between commands. Safe unguarded.