Game ideas & features

Your next feature

Shared objects

Share opaque game data through explicit access policies, indexed queries and original revisions.

SDK developRequires a player session
Godot
Illustration of Shared objects
Your visible result

Read the owner usage before creating. Creation uses its revision; update and deletion use the original object revision. Owner, group and creation expiry stay unchanged.

Video coming later

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

Shared objects

Prepare the same project

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

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

    Key
    bases
    Read policy
    all
    Write policy
    owner
    Grid position
    true
    Maximum object bytes
    1024
    Maximum objects per owner
    1

    Keys stay reserved. After first use, policies, search schema, TTL and position are immutable. Archive blocks new writes; reads and deletion remain available.

    This first example reads data. It creates no group, match or object. An empty list is a valid first response.

  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.

This SDK example uses develop. Check whether the required APIs exist in your installed SDK.

Complete the Quickstart connection with the intended player. Call read_world_map() from an explicit button or scene action. Opening the file alone sends no request.

GDScript
res://scripts/shared_objects.gd
horizOn call
1extends Node
2​
3# Verified SDK Develop API. Call explicitly after restoring the existing player.
4func read_world_map() -> void:
5 var user = Horizon.auth.getCurrentUser()
6 if user == null:
7 return
8 var result = await Horizon.sharedObjects.queryObjects(user.userId, "bases", {
9 "mode": "rectangle", "minX": -10, "maxX": 10,
10 "minY": -10, "maxY": 10, "limit": 20
11 })
12 if not result.success:
13 push_warning(result.errorCode)
14 return
15 for object in result.data.objects:
16 var bytes: PackedByteArray = object.data
17 print(object.id, " bytes=", bytes.size())
18 # Respect result.data.pollAfterSeconds; no automatic poll or page loop.
19 # Keep dataBase64 and lossless search-string wrappers unchanged on metadata edits.
20 # Mutations need durable original bytes, IDs and If-Match revision before one send.
21 # An unknown create is reconciled through getRecoveryUsage/queryRecoveryObjects.
22 # No new identity, replacement revision or automatic create retry.
Open the complete SDK sample ↗

World map

Store owner bases as opaque bytes. Query a configured integer grid rectangle explicitly; update with the original object revision. Position is a query index, not a game-rule validator.

Asynchronous PvP

Choose an opponent through a bounded nonuniform integer query. Load their defense bytes and validate play with a server-owned Validated Actions run. Only a trusted backend decides the outcome and sends an immutable Inbox notice.

Use matching player sessions, a durable original write intent and explicit bounded reads. Trusted outcome validation and Inbox delivery belong on your game backend; Account Keys never belong in game builds.

Test your new feature.

Read the owner usage before creating. Creation uses its revision; update and deletion use the original object revision. Owner, group and creation expiry stay unchanged.

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

Endpoints
  • GET/shared-objects/collections
  • GET/shared-objects/{collection}/usage
  • GET/shared-objects/{collection}/objects/{objectId}
  • POST/shared-objects/{collection}/query
  • POST/shared-objects/{collection}/objects
  • PUT/shared-objects/{collection}/objects/{objectId}
  • DELETE/shared-objects/{collection}/objects/{objectId}
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.