Skip to content

Players & Segments

Identify players with custom properties and organize them into segments using tags. Segments drive Remote Config overrides — different player groups can get different settings.

QuestData.set_user_property(key: String, value: Variant)
ParameterTypeDescription
keyStringProperty name (e.g. "level", "platform")
valueVariantProperty value (String, int, float, bool)

Sets a single property for the current player. Sent to the server immediately.

QuestData.set_user_properties(props: Dictionary)

Sets multiple properties at once. More efficient than calling set_user_property() multiple times.

# Set properties on game start
func _ready():
QuestData.set_user_properties({
"platform": OS.get_name(),
"language": TranslationServer.get_locale(),
"game_version": ProjectSettings.get_setting("application/config/version"),
"first_launch": true
})
# Update as the player progresses
func _on_level_completed(level: int):
QuestData.set_user_property("highest_level", level)
# Track spending tier
func _on_purchase(amount: float):
total_spent += amount
if total_spent > 100:
QuestData.set_user_property("spending_tier", "whale")
elif total_spent > 10:
QuestData.set_user_property("spending_tier", "dolphin")

Tags are lightweight labels used for player segmentation. Unlike properties, tags don’t have values — a player either has a tag or doesn’t.

QuestData.set_user_tag(tag: String)
ParameterTypeDescription
tagStringTag name (auto-lowercased, e.g. "vip", "beta_tester")
QuestData.remove_user_tag(tag: String)

Removes a tag from the current player.

# Tag VIP players
func _on_purchase_completed():
QuestData.set_user_tag("paying_user")
if total_purchases >= 5:
QuestData.set_user_tag("vip")
# Tag by play style
func _on_game_completed(playtime_hours: float):
if playtime_hours > 100:
QuestData.set_user_tag("hardcore")
elif playtime_hours < 2:
QuestData.set_user_tag("casual")
# Remove tag when no longer applicable
func _on_subscription_expired():
QuestData.remove_user_tag("subscriber")

Tags are the building blocks for segments. In the dashboard, create segments by combining tags, then attach config overrides:

  1. Define segments in Players > Segments (e.g. “VIP Players” = tag vip)
  2. Add config overrides in Configuration > Remote Config (e.g. “VIP Players” get max_lives = 10)
  3. SDK fetches automatically — When fetch_remote_config() is called, the server checks the player’s tags and returns the correct overrides
# In your game code — no segment logic needed
QuestData.set_user_tag("vip")
QuestData.fetch_remote_config()
# Later, this returns 10 for VIP players, 3 for everyone else
var lives = QuestData.get_config("max_lives", 3)

The SDK automatically generates a persistent player_id on first launch, stored in user://quest_player_id.save. This ID survives game restarts and reinstalls (if the user data directory is preserved).

# Read the current player ID
var pid = QuestData.get_player_id()
# Override with your own ID (e.g. from your auth system)
QuestData.player_id = "steam_76561198012345"
  • Players > Player Explorer — Search players by ID, view properties, event timeline, session history
  • Players > Segments — Create tag-based segments, view player counts per segment
  • Configuration > Remote Config — Attach config overrides to segments
  1. set_user_property() buffers the property locally
  2. Properties are sent to POST /v1/identify with the player’s ID
  3. The server stores them as JSONB — queryable in the Player Explorer
  1. set_user_tag() sends a fire-and-forget POST to /v1/players/:id/tags
  2. Tags are stored server-side and used for segment matching
  3. remove_user_tag() sends a DELETE request
  4. Tags are always lowercased for consistency
  1. Set properties early — Platform, language, and version on game start
  2. Update properties as they change — Level, spending tier, play style
  3. Use tags for segments — Tags are boolean (has/doesn’t have), properties are key-value
  4. Keep tag names simple"vip", "beta", "churned" — not "user_who_paid_more_than_100"
  5. Don’t over-segment — Start with 2-3 meaningful segments, add more as needed