Skip to content

Scripting

The main types you drive from C#. The full member list is in the Scripting API reference.

To Start from
Connect, resize, focus, or send input TerminalSession
Read the screen, or run emulation with no Unity objects TerminalEmulator
Use the texture, scroll, select, or paint TerminalRenderer
Change how one screen looks or points TerminalScreen3D, TerminalScreenUGUI
Switch a screen off, break up its signal, or crack it TerminalScreenBase, see Screen behaviors
Build an interface TerminalUI
Draw the whole screen yourself ISurfaceProgram

Three namespaces hold them: DarkEffekt.Terminal for the emulator, connections, and input; DarkEffekt.Terminal.UI for the interface framework; and DarkEffekt.Terminal.Unity for the session, renderer, screens, and assets.

The center of a terminal: one emulator, one connection, one renderer, with input routed from whichever screen has focus. It is a MonoBehaviour.

var session = GetComponent<TerminalSession>();
session.SetConnection(new TelnetConnection("host", 23));
session.SetSize(120, 40); // grid dimensions
session.SetFontSize(18); // cell pixel size for this session, rebuilds the target
session.Focus();
session.AcceptsKeyboard = false; // keep focus, stop typing
session.SendText("help\n");
session.Send(bytes); // raw bytes to the connection
session.Emulator; // the core state
session.Renderer; // the RenderTexture and draw controls
session.Theme = theme; // font, colors, and cursor; swaps during play

SetConnection(null) detaches. ConnectionOpened fires when the stream opens, and ConnectionClosed when the far end closes or a connect fails, with a CloseReason that says which.

session.Blur();
session.HasFocus;
TerminalSession.Focused; // the session with the keyboard, or null
TerminalSession.FocusChanged += s => { };
session.SkipKeyboardThisFrame(); // keep this frame's keys from the terminal
session.RunSurface(program); // hand the screen to a surface program
session.ExitSurface();
session.BindTexture("camera", texture); // fill a TextureView's slot
session.RebuildRenderer(); // after changing the theme's font

Emulator is ready before Awake, so another component can set a connection from its own Awake. Renderer is null until the session’s Awake.

The emulation core, with no UnityEngine dependency. Feed it host output, read its state, and receive the bytes it sends back.

var term = new TerminalEmulator(cols: 80, rows: 24, maxScrollback: 2000);
term.Output += bytes => connection.Send(bytes); // query responses
term.Bell += () => PlayBeep();
term.TitleChanged += title => SetLabel(title);
term.Feed(hostBytes);
term.FeedText("plain text");
string line = term.GetText(new CellRange(0, 0, 79, 0));
ReadOnlySpan<Cell> row = term.Screen.GetRow(0);
term.CursorX; term.CursorY; term.Cols; term.Rows;
term.ChangeVersion; // bumped on every visible change

Screen is the current grid (the alternate screen when active), a ScreenBuffer of Cell values with fore and back TermColor and CellAttrs. Row indexes below zero reach into scrollback. Call the emulator from one thread.

The emulator’s assembly, DarkEffekt.Terminal.Core, has no engine references: reference it from a test project or a server and it runs under plain dotnet.

Draws the emulator into Target. Usually the session owns it; reach it through session.Renderer.

session.Renderer.Target; // the RenderTexture
session.Renderer.ScrollOffset = 3; // scroll into history
session.Renderer.Selection; // the selected CellRange, or null
session.Renderer.AddOverlay(tex, new RectInt(2, 1, 10, 4));
session.Renderer.AfterRender += rt => { /* paint into rt */ };
session.Renderer.TargetChanged += rt => { /* a resize replaced the texture */ };
session.Renderer.SetDirty(); // redraw at the next frame
session.Renderer.CellWidth; session.Renderer.CellHeight;

TerminalScreen3D and TerminalScreenUGUI present a session. Each has its own ScreenType, a TerminalScreenType for the filter and the display effect.

screen.Session = session;
screen.ScreenType = TerminalScreenTypePresets.GreenCrt();

DisplayTexture is the styled image a screen shows, for a material or script of your own. A resize replaces it, so read it each frame you use it.

screen.PointerIndicatorStyle = PointerIndicator.Outline;
screen.UvToCell(uv, out int col, out int row); // a UV on the picture to a cell
screen3D.Resolution = 1024; // pixels across; sets the session's font size
screen3D.FitRows = true; // rows follow the columns
screen3D.PreserveAspect = true;
screenUI.ScaleMode = FlatScaleMode.NativePixels;
screenUI.SnapToNativeSize();

Each screen can also be switched off and on, lose its vertical hold, pick up interference, and take damage. See Screen behaviors.

screen.PowerOff();
screen.PowerOn();
screen.PowerChanged += on => { };
screen.LoseVerticalHold(0.6f);
screen.RecoverVerticalHold(0.5f);
screen.RollOnce();
screen.Signal = SignalCondition.Noisy(0.1f);
screen.Glitch(0.3f, 0.8f);
ScreenImpact impact = screen.Damage(uv, 0.6f);
screen.Repair();

TerminalViewportFitter reflows a session to fill a uGUI screen. Set CellPointSize, DpiScaling, and DpiOverride; read Columns, Rows, and CellPixelHeight.

TerminalTheme and TerminalScreenType are ScriptableObjects with public fields. Create one with ScriptableObject.CreateInstance or take a preset, then assign it:

var theme = TerminalThemePresets.GreenPhosphor();
theme.fontSize = 20;
session.Theme = theme;
var type = TerminalScreenTypePresets.ColorCrt();
type.curvature = 0.04f;
screen.ScreenType = type;

See Themes and screen types.

ITerminalInput is input as events: keys, typed characters, paste, the pointer, and focus. The session sends them to the surface program while one runs, and otherwise to an AnsiInputEncoder, which writes the bytes a host expects. InputEncoder holds the encodings themselves; call it directly to drive a session from your own input source. AnsiInputDecoder reads those bytes back into events. See Input and selection.

session.RunSurface(program) hands the screen to an ISurfaceProgram, which draws into a CellSurface with no escape parsing. TerminalUI and its elements build an interface on top. See Interfaces.

FigletFont parses a .flf font, FigletText renders rows of characters with it, and FigletFontAsset is the imported asset. See Big text.

string[] rows = fontAsset.Render("READY");
foreach (string row in rows) session.Emulator.FeedText(row + "\r\n");

ITerminalConnection is the byte-stream contract; TelnetConnection, TcpConnection, WebSocketConnection, TtydConnection, and LocalProgramConnection implement it. ITerminalProgram and IProgramHost host an in-process program. See Connections.