tecs.application
The host-neutral application lifecycle.
The Rust host owns polling and passes one sealed event batch and elapsed delta to iterate. This module owns only game lifecycle: plugin installation, startup, world updates, crash containment, suspension, quit requests, and shutdown. Windowing, rendering, audio, and platform event conversion are Rust service boundaries rather than application fields.
Each application owns an asset loader. Config.mcpPort opts into one loopback MCP listener, opened before plugin installation so startup failures remain inspectable. Only one application per runtime may own that listener, because the tool registry names one world. Nil opens no listener; zero chooses a port.
A host calls poll outside iterate, once per host turn, even while gameplay is suspended or a lifecycle operation is parked. tecs.host does this and parks asynchronous startup as well as updates. A custom host must follow the same ordering. Diagnostics remain available during a parked operation; tools that could touch its in-progress world report a retryable refusal.
Shutdown first unwinds a parked host operation, then attempts world shutdown, stops the loader, and closes the debug listener. Later application cleanup still runs if world shutdown raises. Resident asset handles retain their existing release contract: game shutdown systems release the holds they own. Repeated application shutdown does nothing.
Module contents
Constructors
| Constructor | Description |
|---|---|
newApplication | Builds an inert application without opening platform services. |
Types
| Type | Kind | Description |
|---|---|---|
Application | record | A host-driven application and its world. |
Config | type | Settings copied by newApplication. |
HostEvent | type | A platform event already translated by the Rust host. |
Plugin | type | Installs a game's entities, resources, observers, and systems before startup. |
State | type | The lifecycle state visible to host diagnostics. |
Constructors#
newApplicationconstructor#
function newApplication(config: Config?): ApplicationBuilds an inert application without opening platform services.
Arguments
| Name | Type | Description |
|---|---|---|
config | Config? | the copied world and lifecycle settings |
Returns
| Type | Description |
|---|---|
Application | an application waiting for |
Raises
when the debug frame limit or MCP port is invalid
Types#
Applicationrecord#
record Application is mcpbindings.Application
world: ecs.World
assets: assets.Assets
debugServer: mcp.Server?
input: input.Input
window: platformwindow.Window
quitRequested: boolean
suspended: boolean
elapsed: number
frame: integer
poll: function(exclusive self: Application, parked: boolean?): boolean
init: function(exclusive self: Application): boolean
iterate: function(exclusive self: Application, dt: number, events: {platformevents.Event}?): boolean
requestQuit: function(exclusive self: Application): nil
setSuspended: function(exclusive self: Application, suspended: boolean): nil
crashed: function(borrows self: Application): string?
clearCrash: function(exclusive self: Application): (boolean, string?)
shutdown: function(exclusive self: Application): boolean
getState: function(borrows self: Application): State
endA host-driven application and its world.
Methods
poll#
poll: function(exclusive self: Application, parked: boolean?): booleanPolls optional debugging once per host turn, outside the world update scope.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application | the application to serve. |
parked | boolean? | whether its lifecycle coroutine remains suspended. |
Returns
| Type | Description |
|---|---|
boolean | whether one debug request was answered. |
init#
init: function(exclusive self: Application): booleanInstalls the game plugin and runs startup phases once.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application |
Returns
| Type | Description |
|---|---|
boolean |
Raises
when the host initializes an application more than once
iterate#
iterate: function(exclusive self: Application, dt: number, events: {platformevents.Event}?): booleanRuns one host iteration and returns whether another is wanted.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application | |
dt | number | |
events | {platformevents.Event}? |
Returns
| Type | Description |
|---|---|
boolean |
Raises
for an invalid delta or when called outside the running lifecycle
requestQuit#
requestQuit: function(exclusive self: Application): nilRequests that the host stop after the current callback returns.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application |
Returns
| Type | Description |
|---|---|
nil |
setSuspended#
setSuspended: function(exclusive self: Application, suspended: boolean): nilChanges whether iterations advance simulation.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application | |
suspended | boolean |
Returns
| Type | Description |
|---|---|
nil |
crashed#
crashed: function(borrows self: Application): string?Returns the first guarded game failure.
Arguments
| Name | Type | Description |
|---|---|---|
borrows self | Application |
Returns
| Type | Description |
|---|---|
string? |
clearCrash#
clearCrash: function(exclusive self: Application): (boolean, string?)Clears a guarded game failure in a debug application.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application |
Returns
| Type | Description |
|---|---|
boolean | |
string? |
shutdown#
shutdown: function(exclusive self: Application): booleanRuns world shutdown once, including after a guarded startup failure.
Arguments
| Name | Type | Description |
|---|---|---|
exclusive self | Application |
Returns
| Type | Description |
|---|---|
boolean |
getState#
getState: function(borrows self: Application): StateReturns the current host lifecycle state.
Arguments
| Name | Type | Description |
|---|---|---|
borrows self | Application |
Returns
| Type | Description |
|---|---|
State |
Fields
assets#
assets: assets.AssetsRead-only. Holds this application's loader, which shuts down with the application.
debugServer#
debugServer: mcp.Server?Read-only. Holds the optional loopback debug listener after initialization.
quitRequested#
quitRequested: booleansuspended#
suspended: booleanelapsed#
elapsed: numberframe#
frame: integerConfigtype#
type Config = {
world: ecs.WorldConfig?,
window: platformwindow.Options?,
plugin: Plugin?,
onEvent: (function(event: platformevents.Event, exclusive app: Application): nil)?,
--- Caller-writable. Enables loopback debugging on this port; nil disables it and
--- zero chooses a free port.
mcpPort: integer?,
debug: boolean?,
debugMaxFrames: integer?
}Settings copied by newApplication.
HostEventtype#
type HostEvent = Quit
| WindowCloseRequested
| WindowResized
| WindowScaleChanged
| WindowFocusGained
| WindowFocusLost
| KeyDown
| KeyUp
| MouseMotion
| MouseDown
| MouseUp
| MouseWheel
| TextInput
| FingerDown
| FingerUp
| FingerMotion
| FingerCanceled
| GamepadAdded
| GamepadRemoved
| GamepadButtonDown
| GamepadButtonUp
| GamepadAxisA platform event already translated by the Rust host.
Plugintype#
type Plugin = function(exclusive app: Application): nilInstalls a game's entities, resources, observers, and systems before startup.
Statetype#
type State = "created" | "running" | "stopped"The lifecycle state visible to host diagnostics.