# `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. ## Constructors ### `newApplication` _constructor_ ```nupp function newApplication(config: Config?): Application ``` Builds 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 `init` | #### Raises - when the debug frame limit or MCP port is invalid ## Types ### `Application` _record_ ```nupp 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 end ``` A host-driven application and its world. #### Methods ##### `poll` ```nupp poll: function(exclusive self: Application, parked: boolean?): boolean ``` Polls 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` ```nupp init: function(exclusive self: Application): boolean ``` Installs 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` ```nupp iterate: function(exclusive self: Application, dt: number, events: {platformevents.Event}?): boolean ``` Runs 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` ```nupp requestQuit: function(exclusive self: Application): nil ``` Requests that the host stop after the current callback returns. ###### Arguments | Name | Type | Description | | --- | --- | --- | | `exclusive self` | `Application` | | ###### Returns | Type | Description | | --- | --- | | `nil` | | ##### `setSuspended` ```nupp setSuspended: function(exclusive self: Application, suspended: boolean): nil ``` Changes whether iterations advance simulation. ###### Arguments | Name | Type | Description | | --- | --- | --- | | `exclusive self` | `Application` | | | `suspended` | `boolean` | | ###### Returns | Type | Description | | --- | --- | | `nil` | | ##### `crashed` ```nupp crashed: function(borrows self: Application): string? ``` Returns the first guarded game failure. ###### Arguments | Name | Type | Description | | --- | --- | --- | | `borrows self` | `Application` | | ###### Returns | Type | Description | | --- | --- | | `string?` | | ##### `clearCrash` ```nupp 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` ```nupp shutdown: function(exclusive self: Application): boolean ``` Runs world shutdown once, including after a guarded startup failure. ###### Arguments | Name | Type | Description | | --- | --- | --- | | `exclusive self` | `Application` | | ###### Returns | Type | Description | | --- | --- | | `boolean` | | ##### `getState` ```nupp getState: function(borrows self: Application): State ``` Returns the current host lifecycle state. ###### Arguments | Name | Type | Description | | --- | --- | --- | | `borrows self` | `Application` | | ###### Returns | Type | Description | | --- | --- | | `State` | | #### Fields ##### `world` ```nupp world: ecs.World ``` ##### `assets` ```nupp assets: assets.Assets ``` Read-only. Holds this application's loader, which shuts down with the application. ##### `debugServer` ```nupp debugServer: mcp.Server? ``` Read-only. Holds the optional loopback debug listener after initialization. ##### `input` ```nupp input: input.Input ``` ##### `window` ```nupp window: platformwindow.Window ``` ##### `quitRequested` ```nupp quitRequested: boolean ``` ##### `suspended` ```nupp suspended: boolean ``` ##### `elapsed` ```nupp elapsed: number ``` ##### `frame` ```nupp frame: integer ``` ### `Config` _type_ ```nupp 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`. ### `HostEvent` _type_ ```nupp type HostEvent = Quit | WindowCloseRequested | WindowResized | WindowScaleChanged | WindowFocusGained | WindowFocusLost | KeyDown | KeyUp | MouseMotion | MouseDown | MouseUp | MouseWheel | TextInput | FingerDown | FingerUp | FingerMotion | FingerCanceled | GamepadAdded | GamepadRemoved | GamepadButtonDown | GamepadButtonUp | GamepadAxis ``` A platform event already translated by the Rust host. ### `Plugin` _type_ ```nupp type Plugin = function(exclusive app: Application): nil ``` Installs a game's entities, resources, observers, and systems before startup. ### `State` _type_ ```nupp type State = "created" | "running" | "stopped" ``` The lifecycle state visible to host diagnostics.