Construct 3 plugin documentation

G4S Leaderboard Addon

Self-hosted leaderboards for Construct 3 games, with per-game boards, optional all-games ranking, PHP/MySQL backend, API key option, example project, and buyer-ready docs.

Version
1.0.3.0
Internal Addon ID
NANDAX_G4SLeaderboard
clean buyer build
Backend
PHP 7.4+ / PHP 8+, MySQL or MariaDB

Overview

What it does

G4S Leaderboard Addon connects one or many Construct 3 games to a leaderboard hosted on the buyer's own website. It is meant for arcade sites, educational games, casual competitions, classroom activities, and client websites that need a simple scoreboard without a heavy account system.

Per-game boardsEach game can keep its own score table using a unique game key.
All-games boardShows each game's top player and highest score for a quick site-wide champions view.
Self-hosted backendBuyer uploads the PHP backend to their own website and controls the data.
Construct-friendlyUses actions, triggers, and expressions that are easy to wire in event sheets.

Package contents

What buyers receive

  • G4SLeaderboard.c3addon for Construct 3.
  • g4s-leaderboard-example.c3p with a basic working example.
  • website-backend/ PHP/MySQL backend folder.
  • website-backend.zip for easier upload.
  • README, help, API, install, troubleshooting, ACE, and version documentation.

Installation

Website backend setup

  1. Upload `website-backend` to the buyer website, for example `public_html/g4s-leaderboard/`.
  2. Copy `config.php.example` to `config.php`.
  3. Set database host, database name, database user, and password.
  4. For the first test, keep `require_api_key` set to `false`.
  5. Open `install.php` in a browser and confirm the database table is created.
  6. Open `/g4s-leaderboard/api/ping.php` and confirm the response is JSON.
  7. Delete or protect `install.php` after setup.
https://games4studies.com/g4s-leaderboard/api/ping.php

Construct 3 plugin setup

  1. Install `G4SLeaderboard.c3addon` in Construct 3.
  2. Add one G4S Leaderboard Addon object to the project.
  3. Set API base to the uploaded API folder.
  4. Set a short unique game key, for example `snake`, `math-quiz`, or `word-match`.
  5. Set the readable game title shown in all-games leaderboard rows.
  6. Set the player name through object property or runtime action.
API base:
https://games4studies.com/g4s-leaderboard/api

Construct 3 setup

Basic event flow

On start of layoutCall `Ping API` to verify the backend is reachable.
Player name entryCall `Set player name` from a textbox or default profile value.
Level completeCall `Submit score` with score, normalized score, and optional JSON metadata.
Show leaderboardCall `Load leaderboard`, then read rows with expressions.

Recommended event sheet pattern

On start of layout
  G4SLeaderboard: Ping API

On level complete
  G4SLeaderboard: Set player name TextInput.Text
  G4SLeaderboard: Submit score Score, -1, "{}"

On score submitted
  StatusText: Set text G4SLeaderboard.Status
  BestText: Set text G4SLeaderboard.PersonalBest
  BoardText: Set text G4SLeaderboard.LeaderboardRowText(0)

Game vs all-games scope

Use `game` scope for the current game only. Use `all` scope for a website-wide champions view: game name, top player, and highest score. Normalized score is useful when different games have different scoring scales.

ACE reference

Actions, conditions, and expressions

Conditions

ConditionUse
On Ping CompletedBackend ping has returned.
On Score SubmittedScore submit request finished successfully.
On Leaderboard LoadedLeaderboard rows are ready to read.
On My Best LoadedPersonal best request has returned.
On ErrorLast request failed.
Last Request SucceededTrue when the last request completed without error.
Is LoadingTrue while a request is currently active.

Actions

ActionUse
ConfigureSet API base, game key, game title, and player name together.
Set API BaseChange the uploaded API folder URL.
Set Game KeySet the short identifier for the current game.
Set Game TitleSet the readable game title.
Set Player NameSet the active player name.
Set API KeySet optional key when backend API key mode is enabled.
Ping APICheck backend, database, and table readiness.
Submit ScoreSend score, normalized score, and optional metadata JSON.
Load LeaderboardLoad `game` or `all` leaderboard rows.
Load My BestLoad personal best score for the current player/game.
Clear Last ResultClear stored status, error, JSON, and rows.

Key expressions

ExpressionReturns
StatusLast success/status message.
LastErrorLast error text.
LastJSONRaw JSON or response text from last request.
LeaderboardCountNumber of loaded rows.
LeaderboardRowText(index)Formatted row text for quick UI display.
LeaderboardPlayerName(index)Player name from a loaded row.
LeaderboardScore(index)Score from a loaded row.
LeaderboardNormalizedScore(index)Normalized score for all-games ranking.
LeaderboardRank(index)Rank number.
PersonalBestPlayer's best score for the game.
AttemptsSubmission count for that player/game.
RankHintEstimated current rank after submit.

Backend API

Endpoint reference

All responses return JSON with `ok` set to true or false. When API key mode is enabled, send `X-Leaderboard-Key` header or `api_key` value.

Ping

GET /api/ping.php

Returns backend version, database connection status, table readiness, and whether all-games leaderboard is enabled.

Submit score

POST /api/submit-score.php

{
  "game_key": "snake",
  "game_title": "Snake",
  "player_name": "Alex",
  "score": 1200,
  "normalized_score": 82,
  "meta": {"level": 3}
}

Load leaderboard

GET /api/leaderboard.php?scope=game&game_key=snake&game_slug=snake&amount=10&sort=score
GET /api/leaderboard.php?scope=all&amount=10&sort=normalized

All-games display is reduced to the highest row per game.

Load my best

GET /api/my-best.php?game_key=snake&player_name=Alex

Backend config

Important settings

SettingRecommended starting value
require_api_keyfalse for first test, true only after basic setup works.
allow_all_games_leaderboardtrue if the site wants a global arcade board.
cors_allowed_origins`['*']` for quick preview, exact domains for production.
rate_limit_per_minute60 by default. Increase if many users share one network.
table_name`ul_scores` unless the buyer needs a custom table name.

Workflow

Recommended setup checklist

  1. Install backend and verify `ping.php` in the browser.
  2. Install the plugin and open the included Construct 3 example project.
  3. Set API base and game key in Construct.
  4. Submit a test score.
  5. Load `game` leaderboard and confirm rows display.
  6. Enable all-games leaderboard only if the website needs it.
  7. Turn on optional API key only after basic scoring works.
  8. Delete or protect installer files before going live.

Security

Important limits

Browser score submission is not tournament-grade anti-cheat.

This kit is designed for casual games, classrooms, arcade sites, and client websites. Advanced users can inspect browser requests, so high-stakes competitions need server-side verification or a custom secure scoring design.

  • Use HTTPS on production websites.
  • Use exact CORS origins instead of `*` when the final domains are known.
  • Keep database credentials private in `config.php`.
  • Use rate limiting to reduce accidental spam.
  • Remember that browser-visible API keys are a light barrier, not full protection.

Troubleshooting

First checks

  1. Open `/api/ping.php` directly in a browser.
  2. Confirm `ok`, `db_connected`, and `table_ready` are true.
  3. In Construct 3, call `Ping API` and display `Status` or `LastError`.
  4. If a request fails, inspect `LastJSON` to see whether the server returned JSON or an HTML error page.

VPN, firewall, CDN, or hosting blocks

It is common for some hosting providers, CDNs, or firewalls to block shared VPN IP addresses. If the leaderboard works without VPN but fails with VPN, the usual cause is a network/server rule rather than a plugin bug.

Test without VPNCompare the same game and API URL with VPN disabled.
Check response typeHTML block pages cause invalid JSON errors in Construct.
Review firewall logsCheck hosting firewall, ModSecurity, Cloudflare, CDN, or security plugin logs.
Whitelist API pathAllow the uploaded `/g4s-leaderboard/api/` folder where needed.

Common errors

ProblemLikely fix
Invalid JSON responseWrong URL, PHP error page, missing config, firewall block, or HTML response.
CORS failureSet allowed origins correctly in backend config.
API key rejectedMake backend key and Construct key exactly match.
No rows shownCheck game key, scope, amount, and whether scores were submitted.

Version history

1.0.3.0 - 2026-05-27

  • Construct 3 example rebuilt at 1920x1080.
  • Output area enlarged and JSON output formatted across new lines.
  • All-games output now shows each game's top player and highest score.

1.0.0.0 - 2026-05-20

  • Initial saleable universal release.
  • Construct 3 plugin with per-game and all-games leaderboard support.
  • PHP/MySQL backend with installer and SQL files.
  • Optional API key, CORS settings, and rate limiting.
  • Simple Construct 3 example project.
  • Release bundle with backend and documentation.