Fullscreen game launcher built for arcade cabinets and kiosk installations. Features automatic crash recovery, idle monitoring, and a DVD-style attract mode with starfield and floating screenshots.
Current Version: 1.1.0
Grab the latest STLGameLauncher-Setup-v<version>.exe from GitHub Releases and run it. The installer will walk you through configuration and drop everything in C:\Program Files\STLGameLauncher by default.
The launcher runs in one of two modes, configured in settings.cfg:
Normal Mode β Standard desktop application behavior:
- Runs like a regular program
- Uses keyboard/gamepad controls defined in config
- NO auto-restart on crash
- NO auto-start on login
- You manually launch it when you want to use it
Kiosk Mode β Locked-down unattended operation for arcade cabinets:
- Auto-starts on Windows login via scheduled task (
STLGameLauncherKiosk) - Auto-restarts on crash (up to 3 times per minute via the scheduled task)
- Hard-coded arcade controls (ignores config file control settings)
- Enforces idle timeouts for games
- Designed to run 24/7 without human intervention
Settings live in settings.cfg in the install directory. You can edit this manually if needed.
[General]
mode = kiosk
subscription = arcade-jam-2018
idle_seconds_menu = 180
idle_seconds_game = 300modeβnormalorkiosksubscriptionβ Content pack nameidle_seconds_menuβ Inactivity timeout before attract mode kicks inidle_seconds_gameβ Inactivity timeout before killing an idle game
[Paths]
content_root = C:\ProgramData\STLGameLauncher\external
logs_root = C:\ProgramData\STLGameLauncher\logscontent_rootβ Where games, themes, and assets livelogs_rootβ Where logs are written (auto-cleaned after 30 days)
[Update]
update_on_launch = true
server_base = https://sgd.axolstudio.com/update_on_launchβ Check for updates on startupserver_baseβ Update server URL
[Controls.Keys]
select = enter,space
prev = left,a
next = right,d
back = escape
admin_exit = shift+f12
[Controls.Pads]
select = pad_a,pad_start
prev = pad_left
next = pad_right
back = pad_selectNote: Kiosk mode overrides these settings with hard-coded arcade controls and ignores the config file.
Admin hotkey: Shift+F12 force-kills the current game and returns to the menu from anywhere. This works in both Normal and Kiosk mode.
After sitting idle for idle_seconds_menu (configured in settings), the launcher switches to attract mode β a screensaver showing game screenshots and prompting visitors to press Start.
Press any key or button to return to the menu.
A subscription is a content pack that includes games, a theme, and all associated assets. The launcher loads whatever subscription is specified in the subscription field in settings.cfg.
If update_on_launch = true in your config, the launcher checks for new content on startup by connecting to the update server specified in server_base.
The server organizes content by subscription name:
https://sgd.axolstudio.com/
βββ arcade-jam-2018/
βββ games/
β βββ mygame-v1.zip
β βββ mygame-v2.zip
β βββ anothergame-v1.zip
βββ theme/
βββ default-theme-v1.zip
The launcher compares the version numbers in the zip filenames against local .version files for each game and theme. If the server has a newer version, it downloads and extracts it automatically.
For offline installations: Set update_on_launch = false and manually copy game/theme folders to the appropriate directories. No network required.
Each game lives in its own folder under <content_root>/games/<game-id>/ with these required files:
external/games/mygame2025/
βββ game.json (metadata)
βββ game.exe (executable)
βββ box.png (box art for menu)
βββ .version (version number, auto-created)
This file tells the launcher everything about your game:
{
"id": "mygame2025",
"title": "My Game Title",
"developers": ["Studio Name", "Another Dev"],
"description": "Short description that appears in the menu.",
"year": 2025,
"genres": ["action", "puzzle"],
"exe": "game.exe",
"players": "1,2"
}Field Breakdown:
idβ Unique identifier. MUST match the folder name exactly.titleβ Display name shown in the menudevelopersβ Array of developer/studio names (can be multiple)descriptionβ Brief description (shown in menu if theme supports it)yearβ Release yeargenresβ Array of genre tags (e.g.,["action", "rpg", "platformer"])exeβ Name of the executable file (relative to game folder)playersβ Player count:"1"= 1 player only"2"= 2 players only"1,2"= 1 or 2 players"1-2"= 1 to 2 players (displayed differently by some themes)
The menu displays this image for each game. Recommended size is 512x512 or larger. The launcher will scale it to fit the theme layout.
When packaging games for server distribution, create a zip file named <game-id>-v<version>.zip:
mygame2025-v3.zip
βββ mygame2025/
βββ game.json
βββ game.exe
βββ box.png
βββ (any other game files)
Important: The top-level folder inside the zip MUST match the id in game.json.
Update Process:
- Launcher checks server for
<game-id>-v*.zipfiles - Compares version number to local
.versionfile - If server version is newer, downloads and extracts to
<content_root>/games/<game-id>/ - Writes new version number to
.version - Deletes the downloaded zip file
Themes control the visual layout and live in external/theme/<theme-id>/.
external/theme/vortex-theme/
βββ theme.json
βββ ...assets...
{
"id": "vortex-theme",
"name": "Vortex Theme",
"elements": [
{
"name": "titleText",
"type": "text",
"pos": "w/2,40",
"size": "600,80",
"color": "#FFFFFF",
"pointSize": 48,
"content": "%TITLE%"
}
]
}Use these in text content fields:
%TITLE%β Game title%YEAR%β Release year%DEVS%β Developers (comma-separated)%GENRES%β Genres (bullet-separated)%DESC%β Description%PLAYERS%β "1 Player", "2 Players", or "1-2 Players"%BOX%β Box art path%CART%β Cart image path%GENRE1%,%GENRE2%, etc. β Individual genres by 1-based index
Check source/themes/Theme.hx for full element documentation.
The launcher has multiple layers of crash protection:
If the launcher crashes, it catches the exception, logs the error with a full stack trace, and attempts to restart itself. This works in both Normal and Kiosk mode.
In Kiosk mode, the installer creates a Windows scheduled task called STLGameLauncherKiosk that:
- Runs on user login
- Monitors the launcher process
- Automatically restarts it if it exits for any reason
- Limits restarts to 3 attempts per minute (prevents infinite crash loops)
This scheduled task is NOT created in Normal mode β crashes in Normal mode will attempt one self-restart, then exit if that fails.
If you get stuck in a crash loop in Kiosk mode and need to stop the auto-restart behavior:
- Open Task Scheduler (
Win+Rβtaskschd.msc) - Find
STLGameLauncherKioskin the task list - Right-click β Disable
Or via command line:
schtasks /Change /TN "STLGameLauncherKiosk" /DISABLEThis stops the scheduled task from restarting the launcher. You can then investigate the logs to see what's causing the crashes.
Logs go to <logs_root>/gl-YYYYMMDD.log and include:
- Startup/shutdown
- Game launches and session times
- Update checks
- Errors and stack traces
- Idle timeouts
Logs older than 30 days are auto-deleted on startup.
View recent log:
scripts\tail_latest_log.cmdUsage stats are tracked locally in <content_root>/analytics/usage.json:
{
"mygame2025": {
"count": 42,
"lastPlayed": 1699564823000,
"totalSeconds": 12847.5
}
}countβ Launch countlastPlayedβ UTC timestamp (ms)totalSecondsβ Total playtime
This data never leaves the machine.
- Update the version number in
Project.xml - Commit your changes
- Run
scripts\create_release_tag.cmd - GitHub Actions automatically builds the installer and publishes the release
If a release build fails and you need to retry, use scripts\retry_release_tag.cmd to delete and recreate the tag.
- Check
logs/gl-<date>.logfor errors - Verify
settings.cfgis valid - Make sure
content_rootexists and is accessible
- Verify
game.jsonis valid andexefield is correct - Check game executable permissions
- Review logs
- Check
server_baseURL - Verify network connectivity
- Review logs for HTTP errors
See "Emergency Stop" in Crash Recovery section above.
See LICENSE file.