Aego Script
Aego Script is the gameplay language of the Aego engine. It is statically typed, uses Go-like syntax, compiles to a register bytecode and runs inside the engine's VM. Scripts attach to scene nodes, expose fields to the Inspector, read and write engine components, call functions exposed by the engine or by a project's native Go code, and talk to each other through signals and script references.
This document is the normative reference for language version 2 (Stages 5–6). Language version 1 modules are no longer loaded; projects are recompiled on open.
- OverviewAttach
PlayerControllerto a node in the editor, setSpeedandTargetin the Inspector, press Play. - Files and packagesSource files use the
.aesextension and live underscripts/in the project. Any directory underscripts/is a package; files in one directory belong to one package. - Lexical structureIdentifiers are ASCII only:
[A-Za-z_][A-Za-z0-9_]*. A non-ASCII letter where an identifier could start isAES1001. Non-ASCII text is fully supported inside string literals. - GrammarPrecedence, high to low: unary
-!;* / %;+ -;== != < <= > >=;&&;||. Type arguments in a call (Get<T>()) are accepted by the parser anywhere, but only intrinsics may use them (§9). - TypesRules:
- Declarations and statements
var x T,var x T = e— explicit type;x := e— inferred frome(untyped constants default toint/float);nilcannot initialise:=. - Scripts and lifecycleA
scriptis a stateful type that attaches to a node. A node holds at most one instance of each script type; different script types may share a node. - AttributesExportable field types:
bool int float string Vec2 Vec3 Color Quat Rect, enums,NodeRef,AssetRef<T>,ComponentRef<T>. Slices, structs,ScriptRef,CoroutineandConnectioncannot be exported (AES3001). An exportedComponentRef<T>is stored as a node reference; the Inspector only offers nodes that haveT, and a node withoutTstarts the field asnil. - Nodes, components and referencesTransforms are read and written by value:
t := node.Transform2D(); t.Position.X += 1; node.SetTransform2D(t). A 2D method on a 3D node (and the reverse) faults.Destroytakes effect at the end of the phase;IsAliveis false immediately.Get<T>()andGetScript<T>()on a destroyed node returnnil; on anilreference they fault withAES6004. - Standard library
aego/math—Pi Tau;Floor Ceil Round Trunc Sqrt Sin Cos Tan Asin Acos Exp Log Abs Sign Min Max Clamp Lerp Atan2 Pow Deg2Rad Rad2Deg;AbsInt MinInt MaxInt ClampInt; Vec2:Length Normalize Dot Cross Dist Rotate Angle LerpVec2; Vec3:Length3 Normalize3 Dot3 Cross3 Dist3 LerpVec3; Quat:QuatEuler QuatAxisAngle QuatMul QuatRotate QuatSlerp QuatLookDir. There is no overloading: Vec3 variants carry a3suffix, int variants anIntsuffix. - Native bindingsProject Go code in
native/exposes functions, constants and component members through the SDK. - Runtime behaviourA fault stops only the instance that caused it (its methods, coroutines and handlers are no longer called); the rest of the scene keeps running. The Console shows the script stack; double-click opens the file.
- Limits255 registers per function · 32 767 instructions per function · 32 value slots per slice element · 255 script-visible fields per component (checked when the component is registered) · call depth 256 · 100 000 instructions per callback (configurable).
- DiagnosticsCompiler diagnostics have a code, file, line and column, and often a note:
- CLIAll of them use the same workspace as the editor and hot reload.
checkanddumpuse the bindings manifest. For a project withnative/, a small helper that only calls the module'sRegisterwrites it to.aego/cache/script-bindings; it is rebuilt whennative/*.go,go.mod/go.sumor the engine change. A native compile error or a failingRegisteris exit code 2.teston a project withnative/builds the game binary and runs the tests inside it, because tests call the real native functions. - CoroutinesA coroutine is a script method that can pause and continue on a later frame.
- SignalsDeclaration.
signal Name(params)inside a script. Signals have no result. An uppercase name is visible from other packages. - ScriptRef
node.GetScript<T>()returns theScriptRef<T>of scriptTon that node, ornilwhen the node has none. On anilor destroyed node it faults withAES6004. Usepkg.Namewhen the short name is ambiguous (AES2058). - Hot reloadSaving a script while the game runs (
aego run, Play in the editor) swaps the code without restarting. The workspace builds a new generation from the saved files. At the start of the next frame (script.swap,PhaseFrameBegin, the VM stack is empty), every module of that generation is loaded into the same VM. Every live instance is then moved into the new layout, and the dynamic schema is replaced in the same transaction. If anything fails, nothing changes and the previous generation keeps running. A save that does not compile never produces a generation. - EditorThe editor's code editor, navigation, completion, hover, library stubs, Problems panel and Profiler sections for scripts are described in
docs/editor.md(§ Scripts). Unsaved edits are analysed but never run; autosave writes them one second after the last keystroke, on focus loss and before Play. - Keywords and builtinsEvery keyword, builtin type and builtin function of Aego Script. Hover in the script editor shows the same text.