GAMENIGHT / DOCUMENTATION
LÖVE / Lua
Use the shared runner in the separate ontola/gamenight-games repository. It handles the GameNight connection, hidden preparation, pause/resume, window switching and host controller input. The bundled games use this path.
Run the reference game
Install LÖVE 11.5, clone the repository and run from its root:
python scripts/fetch-game-sources.py
love ../gamenight-games/love-party
The fetch command checks out the revision in game-sources.json beside the host repository. For local edits, set GAMENIGHT_GAMES_DIR to your game checkout before testing or packaging.
This starts the standalone menu. The host supplies GAMENIGHT=1, its address, game ID and launch token when launching a managed build. Do not set a made-up token yourself.
Add your game module
Keep simulation in a game module and leave lifecycle handling in the runner. A module defines new(players, rng) and update(state, dt, inputs). This is the beginning of the real Neon Trails module:
function M.new(players, rng)
local s = { players = players, rng = rng }
reset(s)
return s
end
function M.update(s, dt, inputs)
if s.intermission then
s.intermission = s.intermission - dt
if s.intermission <= 0 then
reset(s)
end
return
end
for i, p in ipairs(s.players) do
local c = inputs[i]
local dx, dy = 0, 0
if math.abs(c.x) > math.abs(c.y) and math.abs(c.x) > 0.3 then
dx = c.x > 0 and 1 or -1
elseif math.abs(c.y) > 0.3 then
dy = c.y > 0 and 1 or -1
end
if dx ~= 0 or dy ~= 0 then
if dx ~= -p.dx or dy ~= -p.dy then
p.nextX, p.nextY = dx, dy
end
end
end
Source: games/love-party/games/trails.lua
The input entries belong to the supplied player slots. Do not replace them with love.joystick.getJoysticks() in managed mode. The shared input adapter neutralises disconnected devices and frames older than 250 ms.
Register a new module in modes in main.lua, add its renderer and add its ID to GAMES in the packaging script. These are explicit registries, not automatic plugin discovery. Use an existing game as the full worked example.
Draw a player face
local Face = require("shared.face")
Face.drawFace(player, x, y, 24, { facing = -1 })
x and y are the centre of the head. The helper draws the skin circle before the transparent artwork, retains space for hats and handles live artwork changes. See Faces & colours.
Keep the shared window path
Use shared.window and shared.back_gate. Prepare before showing the window. Back needs a fresh press after release, and a focus event must never resume a paused game. Keep borderless fullscreen and the helper’s Windows presentation workaround.
Package and test
python scripts/test-love-simulation.py
python scripts/package-love-party.py --output dist/my-party-build
The output directory must be new. Packaging builds the registered titles; it does not automatically publish them. Run the integration suite against the resulting packages, then check real controllers and window switching on each target OS.
Optional performance diagnostics
The bundled launcher samples application frame intervals while running and reports them every ten active seconds. It includes GPU, OS and pixel dimensions; CPU and RAM are unavailable. Standalone games send nothing. See the protocol reference for counters, limits and missing-data semantics. These diagnostics contain no accounts, behavioral history or recommendation logic.
Game settings
Use the settings helper and game reference to expose choices, toggles and bounded numbers to the lobby and phone. Validate each change and snapshot round rules when creating a round.