Skip to content

title: GX Engine Reference description: The lookup page for GX, d/BASIC's 2D game library: how to import it, the exact array layouts, every core function and its rules, who owns what, and what has been tested so far.


GX engine reference

This is the lookup page for GX, d/BASIC's library for 2D games: scenes, sprites, tilemaps, cameras and collision. It covers how to import GX, the exact layout of the arrays it works on, every function in the current core with its rules, who owns which part of a game, and what has and has not been tested yet. If GX is new to you, read What GX Is first; this page assumes you know why the library exists.

GX supplies the portable ideas of a game: scenes, entities, tile worlds, cameras, collision, animation, input, resources, text and sound. The runtime, the program that runs your compiled code, supplies the physical route that shows and plays them.

Alpha reference

d/BASIC and GX are in alpha. Some of the engine families in this reference are not yet available in every compiler, runtime or machine.

Import and delivery

gx is a protected module name, matched without regard to ASCII case. A gx.bas file in your own project cannot replace it.

IMPORT gx

The default is BAKED: the compiler copies the reviewed GX source into your compiled program file, .dbc.

IMPORT gx BAKED

The explicit SHARED form compiles against an installed shared library file, .dbl, and records exactly which one:

IMPORT gx SHARED

A shared dependency records the library's identity, version, export signature and byte digest. If the installed library is missing or its bytes differ, the game declines to start and says why. Baked and shared mean the same thing in BASIC; they differ only in packaging and reuse.

The browser playground currently shows the baked form. The packaged runtime on d/OS (the operating system that brings modern software to 8-bit home computers such as the Atari 800, the Commodore 64 and the Apple II) and the developer-kit runtimes are the natural home for the installed .dbl form.

Capability map

The families below describe what a game author gets from GX and how the runtime usually carries each family out. Many routes are intents: an intent is a named request such as "fill this rectangle" or "play this tone" that the machine carries out however it can.

Family What game authors get How the runtime carries it out
scenes world bounds, lifecycle, ticks, the active scene, scaling policy window lifecycle and frame scheduling
backgrounds layered imagery, wrapping and parallax factors images kept and composed by the runtime
entities and sprites identity, position, size, kind, velocity, z-order, visibility GFX surfaces and sprite routes kept by the runtime
tilemaps and tilesets row, column and layer data, tile lookup, animated tiles, viewport projection tilemap and resource GFX operations
collision and physics rectangle queries, layers, gravity and velocity integration, collision results local maths, or batched compute where the machine offers it
cameras follow, clamp, scroll, world-to-screen projection moving the scene viewport and surfaces
animation tick-based frame selection and playback state choosing a region of an image and showing it
input and devices actions mapped from keyboard, pointer, controller, joystick or paddle normalized events and per-frame input snapshots
fonts and text logical font roles, metrics, game text and overlays GFX.DRAW_TEXT, with each runtime substituting a richer or simpler font
sound and music tones, effects, music and bounded streams described by meaning the AUDIO capability and PCM stream lifecycles
resources images, maps, fonts and sounds by package name checked, load-once resource providers (the part of the host that supplies files and media)
tools and diagnostics map and tileset inspection, debug overlays, capability reports developer tools over the same public formats

GX never gives a game raw file access, a native pointer, a video register, or an unmetered callback. Every crossing goes through d/BASIC's Service and intent rules.

Array layouts in the current core

GX calls the arrays it works on carriers; GXCarrierWords uses the word. All current carriers are one-dimensional INTEGER arrays owned by your program.

Scene array

Allocate at least eight words. Any lower bound is accepted; offsets are relative to LBOUND(Scene, 1).

Offset constant Offset Meaning
GX_SCENE_MAGIC_AT 0 GX array marker
GX_SCENE_VERSION_AT 1 layout version
GX_SCENE_WIDTH_AT 2 world width
GX_SCENE_HEIGHT_AT 3 world height
GX_SCENE_TICK_AT 4 current tick
GX_SCENE_ACTIVE_AT 5 active flag
reserved 6–7 kept for future compatible state; do not reuse

Constants: GX_SCENE_WORDS = 8, GX_SCENE_MAGIC = 18248, and GX_SCENE_VERSION = 1.

Entity array

Each entity occupies ten consecutive words. Capacity is the number of complete words divided by ten; leftover words at the end are ignored.

Offset constant Offset Meaning
GX_ENTITY_ALIVE_AT 0 alive flag
GX_ENTITY_X_AT, GX_ENTITY_Y_AT 1, 2 world position
GX_ENTITY_WIDTH_AT, GX_ENTITY_HEIGHT_AT 3, 4 collision size
GX_ENTITY_VX_AT, GX_ENTITY_VY_AT 5, 6 velocity per step
GX_ENTITY_FRAME_AT 7 remembered frame value
GX_ENTITY_FRAME_TICK_AT 8 remembered animation tick
GX_ENTITY_KIND_AT 9 a kind number your game defines

Constant: GX_ENTITY_WORDS = 10.

Tile array

Tiles are one word per cell, stored row by row. The current layout requires LBOUND(Tiles, 1) = 0, so that -1 always unambiguously means "invalid index".

index = Y * Columns + X

The declared Columns × Rows product must fit in the array and within the range an integer tile index can address.

Camera array

Allocate at least two words. GX_CAMERA_X_AT = 0 and GX_CAMERA_Y_AT = 1; offsets are relative to the array's lower bound.

Current core procedures and functions

Arrays and scene

Words = GXCarrierWords(Carrier())
Ready = GXSceneReady(Scene())
CALL GXSceneOpen(Scene(), Width, Height)
CALL GXSceneAdvance(Scene())
  • GXCarrierWords returns the number of elements between the array's bounds.
  • GXSceneReady returns -1 only when the marker and version are valid.
  • GXSceneOpen needs eight words and positive dimensions; otherwise it leaves the array unchanged.
  • GXSceneAdvance needs a ready scene and wraps its tick from 32767 to 0.

Entities

Capacity = GXEntityCapacity(Entities())
Valid = GXEntityValid(Entities(), Slot)
At = GXEntityBase(Entities(), Slot)

CALL GXEntitySpawn(Entities(), Slot, X, Y, Width, Height, Kind)
CALL GXEntityVelocity(Entities(), Slot, VX, VY)
CALL GXEntityStep(Entities(), Slot)

X = GXEntityX(Entities(), Slot)
Y = GXEntityY(Entities(), Slot)
  • slots count from zero even when the array itself has another lower bound;
  • spawn needs a complete slot and a positive size;
  • velocity and step only touch a valid, living entity;
  • getters return zero for an invalid slot; and
  • GXEntityBase is a low-level layout helper and does not check the slot itself.

Collision

Hit = GXRectOverlap(AX, AY, AW, AH, BX, BY, BW, BH)
Hit = GXEntitiesOverlap(Entities(), LeftSlot, RightSlot)

Both functions return -1 for an overlap and 0 otherwise. Widths and heights must be positive. Touching at an edge without shared area is not a hit. The far edges are computed in LONG, so wrapping at the edge of the integer range cannot become a false collision.

Tiles

At = GXTileIndex(Tiles(), Columns, Rows, X, Y)
CALL GXTileSet(Tiles(), Columns, Rows, X, Y, Tile)
Tile = GXTileAt(Tiles(), Columns, Rows, X, Y)

GXTileIndex returns -1 for an invalid map or coordinate. In that case GXTileSet leaves the array unchanged and GXTileAt returns 0. If zero is a meaningful tile in your game, check the index first whenever you need to tell "tile zero" from "invalid request".

Camera

CALL GXCameraFollow(Camera(), FocusX, FocusY, WorldWidth, WorldHeight, ViewWidth, ViewHeight)
X = GXCameraX(Camera())
Y = GXCameraY(Camera())

Follow centres the view on the focus point and keeps each axis inside the world. A view larger than the world on one axis clamps that axis to zero. Invalid dimensions leave the camera unchanged; the getters return zero if the array is too small.

Animation

Frame = GXAnimationFrame(FirstFrame, FrameCount, Tick, TicksPerFrame)

The result is:

FirstFrame + ((Tick \ TicksPerFrame) MOD FrameCount)

An invalid count, an invalid duration, or a negative tick returns FirstFrame. The function never waits or draws.

Ownership rules

Thing Owner
game rules, scores, quests and save decisions your program
GX arrays and the object model around them your program
checked changes to those arrays GX
decoded images, audio and fonts the runtime's resource provider, the part of the host that supplies media
turning hardware input into events the runtime
showing frames and playing audio the part of the runtime that carries out intents
the installed .dbl bytes and the record of which library was bound the package and the runtime

This split stops any one machine's adaptation from becoming a private edition of the game.

Return values and errors

  • BASIC truth is -1; false is 0.
  • an operation that changes state leaves everything unchanged when its preconditions fail.
  • queries return a documented neutral value such as 0 or -1 for invalid input.
  • when the host lacks a capability, the program is told which family and operation are missing, by stable names.
  • work that takes a ticket may pause and resume in a later bounded turn of the runtime.
  • a failed resource, data or audio operation never reports partial success.

When a neutral value could also be real game data, check first, or keep an explicit status in the game object that owns the data.

What has been tested

The full engine is larger than the core that works today:

  • the engine source is about 121 KB of declarations and code;
  • 17 official sample programs cover collision, devices, fonts, maps, tilesets, physics, overworlds and complete game demos; and
  • beneath it all sit the 96 classic listings we counted for the d/BASIC language itself.

The tests keep those steps separate. Passing the core proves the core API documented on this page. It does not quietly promise the whole engine. See What GX Is for the three-ring test story.


Next: GX on 6502 & Intent Acceleration →