Game ideas & features

Your next feature

Gift Codes

Let players enter and redeem gift codes.

Requires a player session
Godot
Illustration of Gift Codes
Your visible result

A test code is redeemed. Repeat redemption follows your rules.

Create a gift code1:42
Open video separately ↗
Video coming later

This step does not have a video yet. The guide and MCP request are ready to use.

Server player values

Prepare the same project

  1. Choose the same project in the dashboard as in your game configuration.

    Gift Codes →
  2. Create or reuse these test entries in the dashboard form. These are example values, not current project data.

    Code
    WELCOME
    Gift Data (JSON)
    {}
    Max Per User
    1

    Up to eight configured values are credited by the server when redeemed. giftData remains a separate game payload. Display the returned balance; do not add the reward again locally.

    Player values →
  3. Save, reload and verify the entries before running the example. Preserve unrelated definitions.

Build this feature

You can preview the guide. Running it requires an active project key. Prepare project

SDK installed, project configuration imported and player signed in.

Up to eight configured values are credited by the server when redeemed. giftData remains a separate game payload. Display the returned balance; do not add the reward again locally. This SDK example uses develop. Check whether the required APIs exist in your installed SDK.

Save the GDScript, attach it to a node in the main scene and run it. Check Output.

GDScript
res://scripts/gift_codes.gd
horizOn callSetup
1# Attach this script to a node in your main scene.
2extends Node
3​
4​
5func _ready() -> void:
6 # Setup: initialize, connect and sign in a player.
7 var connected = await Horizon.connect_to_server()
8 if not connected:
9 print("Failed to connect to horizOn server")
10 return
11 if not Horizon.auth.isSignedIn():
12 var signed_in: bool
13 if Horizon.auth.hasCachedAnonymousToken():
14 signed_in = await Horizon.auth.restoreAnonymousSession()
15 else:
16 signed_in = await Horizon.auth.signUpAnonymous("StatisticsPlayer")
17 if not signed_in:
18 return
19​
20 # horizOn: validate a gift code and redeem it.
21 # Run from one explicit player action; serialize this handler until it completes.
22 var user_id: String = Horizon.auth.getCurrentUser().userId
23 var project: String = Horizon.getConfig().api_key
24 var scope: String = project + "|" + user_id
25 var path: String = "user://gift_pending_" + scope.sha256_text() + ".bin"
26 var pending: Dictionary
27 if FileAccess.file_exists(path):
28 var file := FileAccess.open(path, FileAccess.READ)
29 if file == null: return
30 var saved: Variant = file.get_var(false)
31 file.close()
32 if not HorizonGiftCodes.validIntent(saved, project, user_id): return
33 pending = saved # Invalid/V1 records stay untouched for reconciliation.
34 else:
35 pending = await Horizon.giftCodes.prepareRedemption("WELCOME")
36 if not HorizonGiftCodes.validIntent(pending, project, user_id) or FileAccess.file_exists(path): return
37 var file := FileAccess.open(path, FileAccess.WRITE)
38 if file == null: return
39 file.store_var(pending, false)
40 file.flush()
41 var saved_ok: bool = file.get_error() == OK
42 file.close()
43 if not saved_ok: return
44 var verify := FileAccess.open(path, FileAccess.READ)
45 if verify == null: return
46 var original: Variant = verify.get_var(false)
47 verify.close()
48 if original != pending: return
49 var result: Dictionary = await Horizon.giftCodes.redeemPrepared(pending)
50 if not result.get("success", false): return # Keep all seven original fields for retry.
51 verify = FileAccess.open(path, FileAccess.READ)
52 if verify == null: return
53 original = verify.get_var(false)
54 verify.close()
55 if original == pending: DirAccess.remove_absolute(ProjectSettings.globalize_path(path))
56 if result.get("playerValues") is Dictionary:
57 print(result.playerValues.values) # Current balances, never add grantedValues locally.
58 # Replay has alreadyApplied=true, giftData=null and empty grantedValues/grantedUnlocks.
Open the complete SDK sample ↗

Test your new feature.

A test code is redeemed. Repeat redemption follows your rules.

Choose the same project in the dashboard as in your game configuration.

Endpoints
  • POST/gift-codes/validate
  • POST/gift-codes/redeem
All endpoints in the API reference
Our suggestion for your next step

Give every round a high score.

Save the score after a round and show who's ahead. Keep using your connection and player session.