Core8Bit Lua SDK
Core8Bit games are written in Lua 5.3 against the c8b API. This reference describes the API and its behaviour on the console and in the emulator.
Contents
- Getting started
- Game folder layout
- main.lua and the update loop
- How the runtime starts a game
- Running in the emulator
- Running on the console
- Namespaces
- Reference pages
Getting started
-- Games/HelloWorld/main.lua
local gfx = c8b.graphics
local x, y = 240, 136
function c8b.update()
if c8b.buttonIsPressed(c8b.kButtonLeft) then x = x - 2 end
if c8b.buttonIsPressed(c8b.kButtonRight) then x = x + 2 end
gfx.clear(gfx.kColorBlack)
gfx.fillCircle(x, y, 10, 0x07E0) -- RGB565 green
gfx.drawText("Hello Core8Bit", 10, 10)
end
The screen is 480x272 pixels and colors are RGB565 integers (gfx.kColorBlack = 0x0000, gfx.kColorWhite = 0xFFFF, gfx.kColorClear = -1).
Game folder layout
/Games/<Name>/
main.lua required: the launcher only lists folders that contain main.lua
icon.stj optional cover art shown by the launcher (legacy: icons/icon.sti)
icons/splash.sti optional splash image shown while launching
data/ written by c8b.datastore (data/<name>.json)
... your own scripts (import/require) and assets
- The launcher scans
/Gamesand lists every directory that hasmain.lua. Order and "featured" games come from/System/launcher/order.txt(one name per line,*prefix = featured). - No manifest is read for games: a
manifest.jsonin a game folder is ignored by the console and the launcher. The emulator only readsmanifest.jsonunder/System/*to find the auto-start system application ("auto_start": true,"entry"). - The working directory is the game folder on both platforms, so relative paths (
"images/hero",require("enemy"),import "scenes/Title") resolve inside it. Asset paths are usually given without extension (.sti,.sta,.stsare resolved by the loaders).
main.lua and the update loop
- The runtime loads the SDK (the class system, the graphics, sprite, timer and JSON modules, and the native bindings).
- It runs
main.luaonce. Top-level code is your initialisation. - Every frame it calls
c8b.update. After it returns, the runtime services streaming sound players and closes graphics contexts left open bylockFocus/pushContext.
Differences: the emulator passes the frame time in seconds as the only argument (c8b.update(dt)) and calls core8bit.init() once after main.lua if you define it; the console calls c8b.update() with no argument and never calls core8bit.init. Lifecycle callbacks (c8b.gameWillTerminate, gameWillPause, gameDidResume, deviceWillSleep, deviceDidWake) are only called on the console. Sprites and timers are not updated automatically: call gfx.sprite.update() and c8b.timer.updateTimers() from your update function.
How the runtime starts a game
- Console (BIOS): loads the SDK once at boot, then starts the launcher. Choosing a game calls
c8b.system.loadGame("/Games/<Name>/main.lua"); the console callsgameWillTerminateon the old game, cleans up, changes into the game folder, creates a fresh sandboxed environment for the game and runs it.MENU+Bheld for one second forces a return to the launcher. - Emulator: creates a fresh Lua state, registers the same native API plus the emulator modules (network, UDP, P2P, STV, time, plugins), loads the SDK (or the
System/sdkfolder of a mounted SD-card folder), then changes into the game folder and runs the script.
Running in the emulator
core8bit_emulator Games/MyGame/main.lua
core8bit_emulator --game MyGame # same as Games/MyGame/main.lua
core8bit_emulator --sdcard /path/to/sdcard # console boot: runs the System app with "auto_start": true
core8bit_emulator --dev ... # developer mode (protected calls with stack traces)
With no script argument the emulator boots like the console from an SD-card folder (a directory containing System/). In that mode c8b.launchGame/c8b.system.loadGame switch games.
Running on the console
Copy the game folder to /Games/<Name>/ on the SD card (or over the USB developer bridge) and start it from the launcher. Use c8b.system.loadGame(path) to switch games and c8b.returnToLauncher() to exit; c8b.launchGame has no effect on the console.
Namespaces
| Name | What it is |
|---|---|
c8b |
The API table. C8B is the same table and also holds the flat native bindings (C8B.Graphics_fillRect, ...). |
gfx |
Global alias of c8b.graphics created by the SDK. |
json |
Global JSON module (= c8b.json). |
Sprite, Image, ImageTable, Tilemap, Font, NineSlice, AnimationLoop, Animator, Timer, RealTimer, Object |
Global classes created by the SDK modules. |
plugin |
Native plugin API. |
core8bit / Core8Bit |
Legacy names (see System page). |
Reference pages
- Graphics — primitives, text, fonts, display
- Sprites
- Images, image tables & tilemaps — also nine-slice, animation loop, animator, Tiled loader
- Input — buttons, analog sticks
- Sound — samples, sample players, file players, synth
- Music — MOD, S3M, XM, MIDI, MP3
- Files & storage — files, datastore, io
- Time — clock, timers, easing
- Network & P2P — HTTP, UDP, peer-to-peer rooms, STV streaming
- System — lifecycle, game control, menu, keyboard, plugins, classes, environment
- JSON
- Math & utilities — geometry, RNG, CRC