Game

Main Game Engine class which runs everything The main game loop is as follows:

  1. Update - For each GameEntity:
  1. Collisions - For each GameEntity:
  • Run Entity's onPreCollision() function
  • For any collisions, runs Entity's onCollision() function
  • Runs entity's onPostCollision() function (At any time, the Entity in question may Delete() itself. Before every entity interaction, the entity is checked to make sure it is still valid in case it was deleted in the last interaction)
  1. Draw - For each GameEntity, sorted by zIndex
  • Runs the Entity onDrawBegin() function
  • For each drawable in the Entity, run the draw() function
  • Run the Entity onDrawEnd() function
  1. Draw all debug items in game space (e.g. colliders, screen safe zones, etc).

  2. UI - For the tree of widgets in the UI Container

  • Run onUpdate()
  • Run draw()
  1. Debug UI - Draw all debug windows in the tree of the Debug UI

Properties

  • sortedEntities (Array.<GameEntity>)
  • compositor (roCompositor)
  • screen (roScreen)
  • canvas (BGE.Canvas)
  • uiCanvas (BGE.Canvas)
  • dummyScreen (roScreen)
  • renderQuality (BGE.RenderQualityManager) — The game's render quality level and presets - see setQualityLevel(),
  • currentScene (GameScene) — The scene currently in play
  • currentSceneArgs (object) — The args passed to changeScene() for the current scene
  • Entities (object) — All of the GameEntities by name => => GameEntity
  • Statics (object) — All static variables for a given object type
  • Scenes (object) — The scene definitions by name (see defineScene())
  • Interfaces (object) — The interface definitions by name
  • Bitmaps (object) — The loaded bitmaps by name
  • Sounds (object) — The loaded sounds by name
  • Fonts (object) — The loaded fonts by name
  • Models (object) — The loaded Models by name
  • tweenManager (BGE.TweenManager) — Ticks every live tween once per frame and writes interpolated values onto arbitrary
  • screenFade (BGE.ScreenFade) — Full-screen overlay used by changeSceneWithFade() - see BGE.ScreenFade.
  • gameUi (BGE.UI.UiContainer) — Container for all UI
  • debugUi (BGE.UI.UiContainer) — Container for Debug UI
  • focusManager (BGE.UI.FocusManager) — The single, global focused-widget/cursor state shared by gameUi and any
  • defaultTheme (BGE.UI.Theme) — Default theme for all UI widgets, set in new()
  • uiFocusSoundKey (string) — Default Game.loadSound() keys played by every BGE.UI.Button on focus/click (see
  • uiClickSoundKey (string)
  • controls (BGE.Controller.ControlMap) — Unified remote+controller input mapping - see enableControllerInput()

Constructor

new Game( canvasWidth: integer, canvasHeight: integer, uiWidth?: integer, uiHeight?: integer, ): Game

Constructor for GameEngine

Parameters

  • canvasWidth (integer) — Width of the canvas the game is drawn to
  • canvasHeight (integer) — Height of the canvas the game is drawn to
  • uiWidth (integer, optional, default: 0) — Width of the UI canvas - if 0, will be same as screen
  • uiHeight (integer, optional, default: 0) — Height of the UI canvas - if 0, will be same as screen

Instance Methods

setCamera(cam: Camera): void

Parameters

Returns

  • void

setupUi(uiWidth: integer, uiHeight: integer): void

Sets up the Ui layer

Parameters

  • uiWidth (integer)
  • uiHeight (integer)

Returns

  • void

scaleCanvasToFillScreen(): void

Returns

  • void

getNextGameEntityId(): string

Gets the next valid id for a GameEntity

Returns

  • string

Play(): void

Returns

  • void

broadcastControllerConnectionInfo(): void

Sends every currently-connected controller-web client (see controller-web/index.html) a fresh {playerIndex, labels, connectedCount} message - unlike the old single sendMessage() this replaced (still correct for the client that just opened, since it's the only one that needs its own playerIndex/labels), a client already connected also needs to hear about connectedCount changing when a different client opens or closes, so the page can show "2 controllers connected" - it has no other way to find that out. No-op if controller input was never enabled. Left non-private (like processEntityOnControls/ ControllerServer.parseHttpRequest - see their own doc comments) so a future spec has a seam to exercise this without standing up real sockets end to end.

Returns

  • void

clearStaleInputCaptureForTest(): void

Test-only passthrough to the private clearStaleInputCapture(), so specs can exercise the top-of-frame capture reset Game.Play() performs without driving a full Play() loop iteration.

Returns

  • void

processCollisionsForTest(): void

Test-only passthrough to the private processEntitiesCollisions(), so specs can run one frame's collision pass without driving a full Play() loop iteration.

Returns

  • void

processKeyboardCharsForTest( entity: GameEntity, chars: Array.<integer>, ): boolean

Test-only: runs processEntityOnInput() for one entity as if these characters had been typed this frame, with no button events.

Parameters

Returns

  • boolean — true if the entity is still valid

dispatchOnInputForTest( entity: GameEntity, input: GameInput, ): boolean

Test-only passthrough to the private dispatchOnInput(), so specs can exercise the same currentInputEntityId gating Game.Play() relies on without needing a full Play() loop iteration.

Parameters

Returns

  • boolean — true if the entity is still valid

processUiInputForTest(controllerInputs: Array.<GameInput>): void

Test-only passthrough to the private processUiInput() with only controller-originated inputs, so specs can check gameUi dispatch.

Parameters

Returns

  • void

processEntityOnControls(entity: GameEntity): boolean

Dispatches onControls() to one entity, but only if the game has bound at least one action/axis (ControlMap.hasBindings()) - see GameEntity.onControls()'s doc comment for the zero-cost-when-unbound guarantee this preserves. Not private, matching this file's own precedent (BGE.Controller.ControllerServer.parseHttpRequest) of an otherwise-internal method left public purely so a spec can exercise it directly, since Game's real per-frame loop has no other test seam.

Parameters

Returns

  • boolean — true if this entity is still valid

End(): void

Ends the Game

Returns

  • void

Pause(): void

Pauses the game Only entities marked as pausable = false will be processed in game loop For each entity, the onPause() function will be called

Returns

  • void

Resume(): integer

Resumes / unpauses the game For each entity, the onResume() function will be called, and any image in the entity will have its onResume() called

Returns

  • integer

isPaused(): boolean

Is the game paused?

Returns

  • boolean

setBackgroundColor(color: integer): void

Sets the default background color for the game Before any entities are drawn, the screen is cleared to this color

Parameters

  • color (integer)

Returns

  • void

getDeltaTime(): float

What's the time in seconds since last frame?

Returns

  • float

getTotalTime(): float

What's the total time in seconds since ths start

Returns

  • float

getScene(): GameScene

Gets the scene the game is currently in

Returns

getCanvas(): ifDraw2D

Gets the bitmap the game is currently drawing to

Returns

  • ifDraw2D

getScreen(): roScreen

Gets the screen object

Returns

  • roScreen

getScreenSize(): BGE.Math.Vector

Returns

  • BGE.Math.Vector

getScreenCenter(): BGE.Math.Vector

Returns

  • BGE.Math.Vector

resetScreen(): void

Resets the screen Note: Important This function is here because of a bug with the Roku. If you ever try to use a component that displays something on the screen aside from roScreen, such as roKeyboardScreen, roMessageDialog, etc. the screen will flicker after you return to your game You should always call this method after using a screen that's outside of roScreen in order to prevent this bug.

Returns

  • void

getEmptyBitmap(): roBitmap

Gets a 1x1 bitmap image (used for collider compositing)

Returns

  • roBitmap

getUI(): BGE.Ui.UiContainer

Gets the UI Container to add new UI elements (which get drawn on top off Game Entities)

Returns

  • BGE.Ui.UiContainer

getDebugUI(): BGE.UI.UiContainer

Gets the main debug window to add other debug widgets to

Returns

  • BGE.UI.UiContainer

enableControllerInput( port?: integer, shareFirstControllerWithRemote?: boolean, ): void

Starts a local HTTP + WebSocket server so a browser (phone/tablet) can connect as a virtual twin-stick controller - see BGE.Controller.ControlMap (game.controls) to map its input to named actions/axes.

Never calling this creates no socket and drains no messages. The per-entity controller-input dispatch is likewise skipped whenever no controller events were produced this frame, and all ControlMap work is skipped until a game binds an action/axis - so a game using neither pays nothing per frame, and a remote-only game that uses game.controls still works without calling this.

Parameters

  • port (integer, optional, default: 8888) — TCP port to listen on
  • shareFirstControllerWithRemote (boolean, optional, default: true) — share playerIndex 0 between the first browser and first remote/gamepad (whichever connects first), so a default bindAction(playerIndex=0) responds to either. Set false to give every input source its own distinct index instead.

Returns

  • void

setCombineRemoteInputs(combine: boolean): void

Selects how physical remotes/gamepads map to player indices, independent of enableControllerInput()/browser controllers. Default false: each device gets its own stable index. Set true so every device drives playerIndex 0 instead, regardless of connect/input order - for a single-player game where either the remote or a gamepad should work. Only affects a device first seen after this call.

Parameters

  • combine (boolean)

Returns

  • void

getControllerConnectionInfo(): string

The LAN URL to open on a phone/tablet to connect as a controller, or "" if enableControllerInput() hasn't been called.

Returns

  • string

enableStandardDebugUi(args?: roAssociativeArray): void

Adds the standard set of debug panels (fps, input, memory, garbageCollector, log) to the debug UI - the same five widgets nearly every example wires up by hand in main.bs. Pass false for any key in args to opt out of that one panel, e.g. {log: false}.

Parameters

  • args (roAssociativeArray, optional, default: "{}") — set fps/input/memory/garbageCollector/log to false to skip that panel

Returns

  • void

debugDrawColliders(enabled: boolean): void

Set if colliders should be drawn

Parameters

  • enabled (boolean)

Returns

  • void

debugDrawSafeZones(enabled: boolean): void

Set if Safe Zone should be drawn

Parameters

  • enabled (boolean)

Returns

  • void

debugDrawEntityDetails(enabled: boolean): void

Set GameEntity and SceneObject debug view on or off

Parameters

  • enabled (boolean)

Returns

  • void

debugShowUi(enabled: boolean, drawToScreen?: boolean): void

Set if Debug UI/Windows should be drawn

Parameters

  • enabled (boolean)
  • drawToScreen (boolean, optional, default: true) — Draw the debug UI to the screen instead of the canvas

Returns

  • void

isDebugUiEnabled(): boolean

Returns

  • boolean

debugPrintPerfStats( enabled: boolean, intervalSeconds?: float, ): void

Set whether Play() prints per-frame perf stats to the console (entity/collider counts and per-phase timing: UI input, update+collision, entity draw, buffer swap). Off by default - each phase timestamp above is only measured while this is on, so leaving it off costs nothing per frame. Independent of, and typically a much shorter interval than, the periodic garbage-collection print.

Parameters

  • enabled (boolean)
  • intervalSeconds (float, optional, default: "2.0") — How often to print, in seconds (default 2)

Returns

  • void

getDebugValue(debugKey: string): dynamic

Parameters

  • debugKey (string)

Returns

  • dynamic

log(message: string, level?: BGE.Debug.LogLevel): void

Logs a message, printing it and recording it for on-screen debug display (e.g. BGE.Debug.LogDisplay)

Parameters

  • message (string)
  • level (BGE.Debug.LogLevel, optional, default: "BGE.Debug.LogLevel.info")

Returns

  • void

getLogHistory(): Array.<object>

Gets the history of messages logged via log()

Returns

  • Array.<object> — an array of {message: string, level: BGE.Debug.LogLevel}

debugSetColors(colors: DebugColors): void

Sets the colors for the debug items to be drawn colors = {colliders: integer, safe_action_zone: integer, safe_title_zone: integer}

Parameters

Returns

  • void

debugLimitFrameRate(limit_frame_rate: integer): void

Limit the frame rate to the given number of frames per second

Parameters

  • limit_frame_rate (integer)

Returns

  • void

getGarbageCollectionStats(): GarbageCollectionInfo

Gets the latest stats from automatic garbage collection https://developer.roku.com/en-ca/docs/references/brightscript/language/global-utility-functions.md#rungarbagecollector-as-object

Returns

raycast( origin: BGE.Math.Vector, direction: BGE.Math.Vector, maxDistance?: float, collidableFlags?: integer, ): BGE.RaycastHit

Casts a ray from origin in direction and returns the nearest collider it intersects - 2D (CircleCollider/RectangleCollider) and 3D (SphereCollider3d/BoxCollider3d) alike. Useful for line-of-sight checks, hitscan weapons, ground/wall detection, AI vision cones, and mouse/cursor picking.

Parameters

  • origin (BGE.Math.Vector) — world-space point the ray starts from
  • direction (BGE.Math.Vector) — world-space direction of the ray (does not need to be pre-normalized)
  • maxDistance (float, optional, default: "10000.0") — the ray stops testing past this distance
  • collidableFlags (integer, optional, default: "&hFFFFFFFF") — only colliders whose memberFlags overlap this mask are tested (see Collider.memberFlags)

Returns

  • BGE.RaycastHit — the nearest hit, or invalid if the ray hit nothing

raycastAll( origin: BGE.Math.Vector, direction: BGE.Math.Vector, maxDistance?: float, collidableFlags?: integer, ): Array.<BGE.RaycastHit>

Casts a ray from origin in direction and returns every collider it intersects, sorted by ascending distance from origin. See raycast() for the single-nearest-hit variant.

Parameters

  • origin (BGE.Math.Vector) — world-space point the ray starts from
  • direction (BGE.Math.Vector) — world-space direction of the ray (does not need to be pre-normalized)
  • maxDistance (float, optional, default: "10000.0") — the ray stops testing past this distance
  • collidableFlags (integer, optional, default: "&hFFFFFFFF") — only colliders whose memberFlags overlap this mask are tested (see Collider.memberFlags)

Returns

  • Array.<BGE.RaycastHit> — every hit along the ray, nearest first (empty array if none)

defineInterface( interfaceName: string, interfaceCreationFunction: function, ): void

TODO: work on interfaces

Parameters

  • interfaceName (string)
  • interfaceCreationFunction (function)

Returns

  • void

addEntity( entity: GameEntity, args?: roAssociativeArray, ): GameEntity

Adds a game entity to be processed by the game engine Only entities that have been added will be part of the game Calls the entity's onCreate() function with the args provided

Parameters

  • entity (GameEntity) — the entity to be added
  • args (roAssociativeArray, optional, default: "{}") — arguments to the entity's onCreate() method

Returns

getEntityByID(entityId: string | dynamic): GameEntity

Gets an entity by its unique id

Parameters

  • entityId (string | dynamic)

Returns

  • GameEntity — the entity with the given id, if found, otherwise invalid

getEntityByName(objectName: string): GameEntity

Gets the first entity with the given name

Parameters

  • objectName (string)

Returns

  • GameEntity — the entity with the given name, if found, otherwise invalid

getAllEntities(objectName: string): Array.<GameEntity>

Gets all the entities that match the given name

Parameters

  • objectName (string)

Returns

  • Array.<GameEntity> — an array with entities with the given name

getEntitiesByTag(tag: string): Array.<GameEntity>

Gets all entities tagged with the given tag (via GameEntity.tagsList), across every scene

Parameters

  • tag (string) — the tag to look for (case insensitive, see BGE.TagList)

Returns

  • Array.<GameEntity> — an array of entities with the given tag

getAllEntitiesWithInterface(interfaceName: string): dynamic

TODO: work on interfaces

Parameters

  • interfaceName (string)

Returns

  • dynamic

destroyEntity(entity: GameEntity, callOnDestroy?: boolean): void

Destroys an entity and all its colliders Clears its properties, so images, etc. won't get drawn anymore

Parameters

  • entity (GameEntity) — the entity to destroy
  • callOnDestroy (boolean, optional, default: true)

Returns

  • void

destroyAllEntities( objectName: string, callOnDestroy?: boolean, ): void

Destroys all entities with a given name

Parameters

  • objectName (string)
  • callOnDestroy (boolean, optional, default: true)

Returns

  • void

entityCount(objectName: string): integer

Gets the number of entities of a given name

Parameters

  • objectName (string)

Returns

  • integer

defineScene(newScene: GameScene): void

Registers a scene so it can later be switched to by name with changeScene().

Parameters

  • newScene (GameScene) — The scene to register; its name is the key changeScene() uses

Returns

  • void

isSceneChanging(): boolean

Whether a scene change was requested this frame and hasn't been applied yet.

Returns

  • boolean

changeScene(sceneName: string, args?: object): boolean

Changes to the scene registered under the given name, then calls its onCreate(args). While the game is running, the change is applied at the end of the current frame.

Parameters

  • sceneName (string) — The name of a scene registered with defineScene()
  • args (object, optional, default: "{}") — Passed to the scene's onCreate()

Returns

  • boolean — true if a scene with that name exists

changeSceneWithFade( sceneName: string, args?: object, seconds?: float, ): boolean

Fades the screen to black, changes to the scene registered under the given name, then fades back in once its onCreate(args) has run. With no current scene yet (e.g. starting the first scene), the scene changes straight away and just fades in from black. Check isTransitioning() to ignore gameplay input while this runs.

Parameters

  • sceneName (string) — The name of a scene registered with defineScene()
  • args (object, optional, default: "{}") — Passed to the scene's onCreate()
  • seconds (float, optional, default: 0.3) — How long each half of the fade takes

Returns

  • boolean — false if the scene doesn't exist or a transition is already running

isTransitioning(): boolean

Whether a changeSceneWithFade() transition is running (fading out, changing scene, or fading back in).

Returns

  • boolean

updateFadeTransitionForTest(dt: float): void

Test-only: one frame's fade step with a given dt, then any scene change it requested, the way the end of a Play() frame applies it.

Parameters

  • dt (float)

Returns

  • void

resetScene(): void

Restarts the current scene by changing to it again with the same args.

Returns

  • void

getSceneNames(): Array.<string>

The names of every scene registered with defineScene().

Returns

  • Array.<string>

loadBitmap(bitmapName: string, path: dynamic): boolean

Loads an image file to be used as an image in the game.

Supported file types are .png, .jpg/.jpeg, .webp, .bmp and .gif. SVG is not supported by Roku. An animated .gif only loads its first frame - use a sprite sheet with AnimatedImage for animation.

Parameters

  • bitmapName (string) — the name this bitmap will be referenced by later
  • path (dynamic) — The path to the bitmap, or an associative array {width: integer, height: integer, alphaEnable:boolean}

Returns

  • boolean — true if image was loaded

getBitmap(bitmapName: string): roBitmap

Gets a bitmap image (roBitmap) by the name given to it when loadBitmap() was called

Parameters

  • bitmapName (string)

Returns

  • roBitmap

unloadBitmap(bitmapName: string): void

Invalidates a bitmap name, so it can't be loaded again

Parameters

  • bitmapName (string)

Returns

  • void

load3dModel( modelName: string, modelPath: string, options?: BGE.Model3dLoadOptions, ): boolean

Loads a 3d model file (.stl or .obj) to be used in the game. For an .obj file, also resolves and loads its texture (if any) - either from options.texturePath (always takes priority) or from the .obj's own mtllib/map_Kd reference. A missing or unreadable texture file logs a warning and leaves the model untextured (flat-shaded) rather than failing the whole load - see BGE.Model3dOps.applyTexture.

Parameters

  • modelName (string) — the name this model will be referenced by later
  • modelPath (string) — the path to the model file
  • options (BGE.Model3dLoadOptions, optional, default: "{}") — optional load options (currently just texturePath, an .obj-only explicit texture override)

Returns

  • boolean — true if the model was loaded

get3dModel(modelName: string): Model3d

Gets a 3d Model (Model3d) by the name given to it when load3dModel() was called

Parameters

  • modelName (string)

Returns

unload3dModel(modelName: string): void

Invalidates a 3d Model name, so it can't be loaded again

Parameters

  • modelName (string)

Returns

  • void

registerFont(path: string): boolean

Registers a font by its path

Parameters

  • path (string)

Returns

  • boolean — true if font was registered

loadFont( fontName: string, font: string, size: integer, italic: boolean, bold: boolean, ): void

Loads a font from the registry, and assigns it the given name

Parameters

  • fontName (string) — the lookup name to assign to this font
  • font (string) — the font to load
  • size (integer)
  • italic (boolean)
  • bold (boolean)

Returns

  • void

unloadFont(fontName: string): void

Unloads a font so it can't be used again

Parameters

  • fontName (string)

Returns

  • void

getFont(fontName: string): roFont

Gets a font object, to be used for writing text to the screen For example, in BGE.DrawText()

Parameters

  • fontName (string)

Returns

  • roFont

fitCanvasToScreen(): void

Scales and positions the current canvas to fit the screen

Returns

  • void

centerCanvasToScreen(): void

Centers the canvas on the screen

Returns

  • void

musicPlay(path: string, loop?: boolean): boolean

Plays an audio file at the given path This is designed for music, where only one file can play at a time.

Parameters

  • path (string) — the path of the music file
  • loop (boolean, optional, default: false)

Returns

  • boolean

musicStop(): void

Stops the currently playing music file

Returns

  • void

musicPause(): void

Pauses the currently playing music

Returns

  • void

musicResume(): void

Resumes / unpauses the current music

Returns

  • void

loadSound(soundName: string, path: string): void

Loads a sound file from the given path to be played later

Parameters

  • soundName (string) — the name to assign this sound to, to be referenced later
  • path (string) — the path to load

Returns

  • void

playSound(soundName: string, volume?: integer): boolean

Plays the given sound

Parameters

  • soundName (string) — the name of the sound to play
  • volume (integer, optional, default: 100) — volume (0-100) to play the sound at

Returns

  • boolean

newAsyncUrlTransfer(): roUrlTransfer

Creates a new URL Async Transfer object, which is handled by the game loop Events from this URL transfer will be set to entities via the onUrlEvent() method

Returns

  • roUrlTransfer

setInputEntity(entity: GameEntity): void

Set only one entity to receive onInput() calls Useful for when a menu/pause screen should handle all input Takes effect immediately (this frame's remaining dispatch), not just next frame.

Parameters

Returns

  • void

unsetInputEntity(): void

Unset that only one entity will receive onInputCalls() Takes effect immediately (this frame's remaining dispatch), not just next frame.

Returns

  • void

postGameEvent( eventName: string, data?: roAssociativeArray, ): void

General purpose event dispatch method Game entities can listen for events via the onGameEvent() method

Parameters

  • eventName (string) — identifier for the event, eg. "hit", "win", etc.
  • data (roAssociativeArray, optional, default: "{}") — any data that needs to be be passed with the event

Returns

  • void

setQualityLevel(level: integer): void

Pins the render quality level and turns off adaptive tuning.

Parameters

  • level (integer) — a BGE.RenderQualityLevel value

Returns

  • void

enableAdaptiveQuality( options?: BGE.AdaptiveQualityOptions, ): void

Adjusts the render quality level automatically to hold a target frame rate, starting from the current level (moved into minLevel..maxLevel first if needed).

Parameters

Returns

  • void

disableAdaptiveQuality(): void

Stops adaptive tuning, keeping the current level.

Returns

  • void