Custom Events
Track custom gameplay events to understand how players interact with your game. This guide covers the Analytics SDK API and best practices for event tracking.
Basic Usage
The Analytics SDK is available globally as Hyperstone in all your GDScript files (after exporting with analytics enabled).
Simple Events
Track an event without additional data:
Hyperstone.track("level_complete")Events with Data
Track an event with custom data:
Hyperstone.track("player_death", {
"level": 3,
"cause": "enemy",
"time_survived": 120.5
})API Reference
track(event_name: String, event_data: Dictionary = {})
Tracks a custom event with optional data.
Parameters:
event_name(String): Name of the event (automatically normalized to lowercase)event_data(Dictionary, optional): Custom data to attach to the event
Returns: None
Example:
Hyperstone.track("achievement_unlocked", {
"achievement_id": "speedrunner",
"time_to_unlock": 3600
})Event Naming
Normalization
All event names are automatically normalized to lowercase:
Hyperstone.track("LevelComplete") # Stored as "levelcomplete"
Hyperstone.track("PLAYER_DEATH") # Stored as "player_death"
Hyperstone.track("Item_Purchased") # Stored as "item_purchased"Best Practices
Use snake_case:
# Good
Hyperstone.track("level_complete")
Hyperstone.track("player_death")
Hyperstone.track("item_purchased")
# Avoid
Hyperstone.track("LevelComplete")
Hyperstone.track("playerDeath")
Hyperstone.track("Item-Purchased")Be descriptive:
# Good
Hyperstone.track("boss_defeated")
Hyperstone.track("tutorial_completed")
# Too vague
Hyperstone.track("event1")
Hyperstone.track("action")Use consistent naming:
# Good - consistent pattern
Hyperstone.track("level_started")
Hyperstone.track("level_completed")
Hyperstone.track("level_failed")
# Inconsistent
Hyperstone.track("level_start")
Hyperstone.track("complete_level")
Hyperstone.track("failed")Event Data
Supported Types
Event data can include:
- Numbers:
int,float - Strings:
String - Booleans:
bool - Arrays:
Array - Dictionaries:
Dictionary(nested)
Example:
Hyperstone.track("level_complete", {
"level": 5, # int
"time_taken": 123.45, # float
"perfect_score": true, # bool
"collectibles": [1, 2, 3], # Array
"stats": { # Dictionary
"deaths": 2,
"secrets_found": 3
}
})Data Limits
- Event name: Max 255 characters
- Event data: Max 10 KB per event
- Nested depth: Max 5 levels deep
Common Event Patterns
Level Progression
Track player progress through levels:
# Level started
func _on_level_start():
Hyperstone.track("level_started", {
"level": current_level,
"difficulty": difficulty_setting
})
# Level completed
func _on_level_complete():
Hyperstone.track("level_completed", {
"level": current_level,
"time_taken": level_timer.time,
"score": player_score,
"deaths": death_count,
"collectibles": collectibles_found
})
# Level failed
func _on_level_failed():
Hyperstone.track("level_failed", {
"level": current_level,
"reason": failure_reason,
"progress_percent": calculate_progress()
})Player Actions
Track important player actions:
# Player death
func _on_player_death():
Hyperstone.track("player_death", {
"level": current_level,
"cause": death_cause,
"position_x": player.position.x,
"position_y": player.position.y,
"health_remaining": player.health
})
# Ability used
func _on_ability_used(ability_name: String):
Hyperstone.track("ability_used", {
"ability": ability_name,
"level": current_level,
"cooldown_remaining": get_cooldown(ability_name)
})
# Item collected
func _on_item_collected(item: Item):
Hyperstone.track("item_collected", {
"item_id": item.id,
"item_type": item.type,
"level": current_level,
"total_collected": inventory.count(item.type)
})Achievements
Track achievement unlocks:
func unlock_achievement(achievement_id: String):
Hyperstone.track("achievement_unlocked", {
"achievement_id": achievement_id,
"play_time": get_total_play_time(),
"level_reached": max_level_reached
})In-Game Economy
Track purchases and currency:
# Item purchased
func purchase_item(item_id: String, price: int):
Hyperstone.track("item_purchased", {
"item_id": item_id,
"price": price,
"currency": "gold",
"balance_before": player.gold,
"balance_after": player.gold - price
})
# Currency earned
func earn_currency(amount: int, source: String):
Hyperstone.track("currency_earned", {
"amount": amount,
"source": source,
"balance_after": player.gold
})Tutorial & Onboarding
Track tutorial completion:
# Tutorial step completed
func _on_tutorial_step_complete(step: int):
Hyperstone.track("tutorial_step_completed", {
"step": step,
"time_taken": step_timer.time
})
# Tutorial completed
func _on_tutorial_complete():
Hyperstone.track("tutorial_completed", {
"total_time": tutorial_timer.time,
"steps_completed": tutorial_steps.size(),
"skipped": false
})
# Tutorial skipped
func _on_tutorial_skipped():
Hyperstone.track("tutorial_skipped", {
"step_reached": current_tutorial_step
})Settings & Preferences
Track settings changes:
func _on_setting_changed(setting_name: String, new_value):
Hyperstone.track("setting_changed", {
"setting": setting_name,
"value": str(new_value)
})Boss Battles
Track boss encounters:
# Boss encountered
func _on_boss_encounter(boss_id: String):
Hyperstone.track("boss_encountered", {
"boss_id": boss_id,
"player_level": player.level,
"attempt_number": get_boss_attempts(boss_id)
})
# Boss defeated
func _on_boss_defeated(boss_id: String):
Hyperstone.track("boss_defeated", {
"boss_id": boss_id,
"time_taken": boss_timer.time,
"health_remaining": player.health,
"attempts": get_boss_attempts(boss_id)
})Best Practices
Track Meaningful Events
Do track:
- Level progression
- Player deaths and failures
- Achievement unlocks
- In-game purchases
- Tutorial completion
- Boss battles
- Settings changes
Don't track:
- Every frame update
- Mouse movements
- Continuous position updates
- Rapid-fire events (button mashing)
Include Context
Always include relevant context with events:
# Good - includes context
Hyperstone.track("player_death", {
"level": current_level,
"cause": "enemy",
"enemy_type": "goblin",
"player_health": 0,
"time_in_level": 45.2
})
# Bad - no context
Hyperstone.track("death")Use Consistent Units
Be consistent with units across events:
# Good - consistent time units (seconds)
Hyperstone.track("level_complete", {
"time_taken": 123.45 # seconds
})
# Bad - inconsistent units
Hyperstone.track("level_complete", {
"time_taken": 2.05 # minutes? seconds?
})Avoid PII
Never track personally identifiable information:
# Bad - contains PII
Hyperstone.track("player_registered", {
"email": player_email,
"name": player_name,
"ip_address": player_ip
})
# Good - no PII
Hyperstone.track("player_registered", {
"platform": OS.get_name(),
"version": game_version
})Batch Related Events
Group related data in a single event rather than multiple events:
# Good - single event with all data
Hyperstone.track("level_complete", {
"level": 5,
"time": 120.5,
"score": 1000,
"deaths": 2,
"collectibles": 8
})
# Bad - multiple events
Hyperstone.track("level_complete")
Hyperstone.track("level_time", {"time": 120.5})
Hyperstone.track("level_score", {"score": 1000})
Hyperstone.track("level_deaths", {"deaths": 2})Performance Considerations
Event Queuing
Events are queued in memory and sent in batches every 15 minutes. This means:
- No immediate network overhead
- Minimal performance impact
- Events are cached if network is unavailable
Memory Usage
Each event uses approximately:
- 100-500 bytes for event name and data
- Events are cleared after successful transmission
- Cached events are stored on disk if network fails
Recommended Limits
- Max events per session: 1,000-5,000
- Max events per minute: 10-50
- Event data size: Keep under 1 KB per event
Testing Custom Events
Local Testing
- Export your game with analytics enabled
- Add custom event tracking to your code
- Run the exported game
- Trigger the events you want to test
- Wait 15-20 minutes for events to be sent
- Check the Analytics tab in Hyperstone
Debugging
Add debug prints to verify events are tracked:
func track_with_debug(event_name: String, event_data: Dictionary = {}):
print("[Analytics] Tracking: ", event_name, " with data: ", event_data)
Hyperstone.track(event_name, event_data)Viewing Events
In Hyperstone's Analytics tab:
- Go to the Recent Events table
- Look for your custom event names
- Verify the event data is correct
- Check timestamps to ensure events are being sent
Related Documentation
- Analytics Overview - Understanding Hyperstone Analytics
- Integration Guide - Enable analytics in your builds
- Viewing Analytics - Use the analytics dashboard
- API Reference - Complete SDK reference