Prerequisites
- Godot 4.x (GDScript)
- A LightLeaderboard account, game, and API key
- No plugins needed —
HTTPRequestis built into Godot
TLS: Godot 4 ships with TLS support enabled by default. HTTPS requests
to the API work out of the box — no extra configuration needed.
Submit a Score
Attach this script to any Node (e.g. your GameManager autoload or game scene root).
Call submit_score() when the player's run ends.
# Attach this script to any Node in your scene
extends Node
const API_URL = "https://yourapp.com/api/v1/games/my_game"
const API_KEY = "YOUR_API_KEY"
func submit_score(score: int, player_id: String, player_name: String) -> void:
var http := HTTPRequest.new()
add_child(http)
http.request_completed.connect(_on_score_submitted.bind(http))
var headers := [
"Authorization: Bearer " + API_KEY,
"Content-Type: application/json",
]
var body := JSON.stringify({
"score": score,
"playerRefId": player_id,
"playerName": player_name,
"submissionId": str(Time.get_ticks_msec()),
})
http.request(API_URL + "/scores", headers, HTTPClient.METHOD_POST, body)
func _on_score_submitted(result, code, _headers, body, http: HTTPRequest) -> void:
http.queue_free()
if code == 200:
var data = JSON.parse_string(body.get_string_from_utf8())
print("Rank: ", data["rank"]) # show in UIFetch the Leaderboard
Add this to the same script. Call fetch_leaderboard() in your leaderboard
scene's _ready() and populate your UI nodes in the callback.
func fetch_leaderboard(limit: int = 10) -> void:
var http := HTTPRequest.new()
add_child(http)
http.request_completed.connect(_on_leaderboard_received.bind(http))
var headers := ["Authorization: Bearer " + API_KEY]
http.request(
API_URL + "/leaderboard?limit=" + str(limit),
headers, HTTPClient.METHOD_GET
)
func _on_leaderboard_received(result, code, _headers, body, http: HTTPRequest) -> void:
http.queue_free()
if code != 200:
return
var data = JSON.parse_string(body.get_string_from_utf8())
for entry in data["entries"]:
print("#%d %s %d" % [entry["rank"], entry["playerName"], entry["score"]])
# populate your Label or RichTextLabel nodes hereTips
- Always call
http.queue_free()in the completed callback to avoid memory leaks — everyadd_child(http)needs a matching cleanup. - Store the API key in a
constat the top of an Autoload script so it's accessible everywhere without duplication. - Use
Time.get_ticks_msec()as a quicksubmissionId. For stricter deduplication, generate a UUID usingstr(randi()) + str(randi())or a plugin. - Use Godot's
Labelnodes inside aVBoxContainerto display leaderboard rows — set each Label'stextin the_on_leaderboard_receivedcallback.