Hyve Phaser Plugin
The Hyve Phaser Plugin is a powerful integration tool that seamlessly connects Phaser 3 games with the Hyve platform, providing automatic authentication and telemetry tracking capabilities.
Installation
NPM Package
npm install @hyve-sdk/phaser
# or
pnpm add @hyve-sdk/phaser
# or
yarn add @hyve-sdk/phaser
Using the Game Template
The easiest way to get started is using the create-hyve-game template:
pnpm create hyve-game my-game
cd my-game
pnpm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local and add your Hyve API key
pnpm dev
Game Setup
Adding the Plugin to Your Phaser Game
Here's how to integrate the Hyve Phaser Plugin into your game configuration:
import { AUTO, Game } from "phaser";
import HyvePhaserPlugin from "@hyve-sdk/phaser";
import { MainScene } from "./scenes/MainScene";
// Game configuration
const config: Phaser.Types.Core.GameConfig = {
type: AUTO,
width: 800,
height: 600,
parent: "game-container",
backgroundColor: "#1a1a2e",
physics: {
default: "arcade",
arcade: {
gravity: { x: 0, y: 0 },
debug: false
}
},
plugins: {
global: [{
key: "HyvePhaserPlugin",
plugin: HyvePhaserPlugin,
start: true,
data: {
apiKey: process.env.NEXT_PUBLIC_HYVE_API_KEY || "",
isDev: true,
debug: true
}
}]
},
scene: [MainScene]
};
const StartGame = (parent: string) => {
return new Game({ ...config, parent });
};
export default StartGame;
JavaScript Version
import { AUTO, Game } from "phaser";
import HyvePhaserPlugin from "@hyve-sdk/phaser";
import { MainScene } from "./scenes/MainScene";
// Game configuration
const config = {
type: AUTO,
width: 800,
height: 600,
parent: "game-container",
backgroundColor: "#1a1a2e",
physics: {
default: "arcade",
arcade: {
gravity: { x: 0, y: 0 },
debug: false
}
},
plugins: {
global: [{
key: "HyvePhaserPlugin",
plugin: HyvePhaserPlugin,
start: true,
data: {
apiKey: process.env.NEXT_PUBLIC_HYVE_API_KEY || "",
isDev: true,
debug: false
}
}]
},
scene: [MainScene]
};
const StartGame = (parent) => {
return new Game({ ...config, parent });
};
export default StartGame;
Configuration
Plugin Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | '' | Your Hyve API key for telemetry (required for sending events) |
isDev | boolean | true | Use development environment (dev.hyve.gg vs prod.hyve.gg) |
debug | boolean | false | Enable debug logging to console |
Environment Variables
Create a .env.local file from the provided template:
# Copy the example file
cp .env.example .env.local
# Edit .env.local and add your API key
NEXT_PUBLIC_HYVE_API_KEY=your-actual-api-key
The .env.example file is included in the template as a reference for required environment variables.
// Use in configuration
data: {
apiKey: process.env.NEXT_PUBLIC_HYVE_API_KEY,
isDev: process.env.NODE_ENV !== 'production'
}
Authentication
How It Works
The plugin automatically authenticates users from URL parameters on initialization. No manual handling required!
Supported URL Formats
Modern Token Format (Recommended)
https://yourgame.com?hyve-token=signature.address.randomBase64.timestamp
Legacy Format
https://yourgame.com?signature=0x...&message=encoded_message
Manual Authentication
If you need to trigger authentication manually:
const hyve = this.plugins.get('HyvePhaserPlugin');
// Authenticate from current URL
await hyve.authenticateFromUrl();
Checking Authentication Status
const hyve = this.plugins.get('HyvePhaserPlugin');
if (hyve.isAuthenticated()) {
const userId = hyve.getUserId();
const sessionId = hyve.getSessionId();
console.log(`User ${userId} is authenticated`);
}
Telemetry Tracking
Using sendTelemetry
The plugin provides a single, flexible sendTelemetry method for all tracking needs. All optional parameters accept null to indicate no value:
const hyve = this.plugins.get('HyvePhaserPlugin');
// Basic telemetry
await hyve.sendTelemetry(
'game', // event_location (required)
'player', // event_category (required)
'jump', // event_action (required)
null, // event_sub_category (pass null if not needed)
null, // event_sub_action (pass null if not needed)
null, // event_details (pass null if not needed)
null // additionalData (pass null if not needed)
);
// With all parameters
await hyve.sendTelemetry(
'game', // event_location
'player', // event_category
'jump', // event_action
'double_jump', // event_sub_category
'successful', // event_sub_action
null, // event_details (will be JSON stringified additionalData)
{ // additionalData - becomes JSON in event_details
height: 200,
duration: 1.5,
description: 'Player performed double jump at level 3'
}
);
Common Telemetry Patterns
// Game start
await hyve.sendTelemetry(
'game', 'gameplay', 'start', 'level_1', null, null,
{ mode: 'campaign' }
);
// Game end
await hyve.sendTelemetry(
'game', 'gameplay', 'end', null, null, null,
{ score, duration: gameTime, description: `Score: ${score}` }
);
// Level complete
await hyve.sendTelemetry(
'game', 'level', 'complete', `level_${levelNum}`, null, null,
{ score, stars: 3, description: `Level ${levelNum} completed` }
);
// Achievement unlock
await hyve.sendTelemetry(
'game', 'achievement', 'unlock', achievementId, null, null,
{ timestamp: Date.now(), description: achievementName }
);
// Player action
await hyve.sendTelemetry(
'game', 'player', 'action', 'power_up', powerUpType, null,
{ location: { x, y }, description: `Collected ${powerUpType}` }
);
API Reference
Authentication Methods
| Method | Returns | Description |
|---|---|---|
authenticateFromUrl() | Promise<boolean> | Authenticate from URL parameters |
isAuthenticated() | boolean | Check if user is authenticated |
getUserId() | string | null | Get authenticated user's ID |
getSessionId() | string | Get current session ID |
Telemetry Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
sendTelemetry(location, category, action, subCategory?, subAction?, details?, additionalData?) | string, string, string, string|null, string|null, string|null, object|null | Promise<boolean> | Send telemetry event with full control |
Telemetry Fields
When sent to the backend, the telemetry event includes these fields (all are always present):
| Field | Type | Description |
|---|---|---|
session_id | string | Unique session identifier (auto-generated) |
hyve_user_id | string | User's wallet address or 'anonymous' |
event_location | string | Where the event occurred (required) |
event_category | string | Main category of event (required) |
event_action | string | Action taken (required) |
event_sub_category | string | null | Sub-category for granular classification |
event_sub_action | string | null | Sub-action for detailed tracking |
event_details | string | null | JSON stringified additional data or description |
Additional Data Structure
interface TelemetryAdditionalData {
[key: string]: any; // Additional data (will be JSON stringified into event_details)
}
Utility Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
getClient() | None | HyveClient | Get underlying SDK client instance |
configure(config) | HyvePhaserPluginConfig | void | Update plugin configuration |
Events
The plugin emits Phaser events that you can listen to:
import { HyveEvents } from '@hyve-sdk/phaser';
// Listen for authentication completion
this.game.events.on(HyveEvents.AUTHENTICATED, (event) => {
if (event.success) {
console.log('Authentication successful!');
console.log('User ID:', event.userId);
} else {
console.error('Authentication failed:', event.error);
}
});
// Listen for successful telemetry
this.game.events.on(HyveEvents.TELEMETRY_SENT, (event) => {
console.log('Event tracked:', event.eventName);
});
// Listen for telemetry errors
this.game.events.on(HyveEvents.TELEMETRY_ERROR, (event) => {
console.error('Telemetry error:', event.eventName, event.error);
});
// Plugin ready event
this.game.events.on(HyveEvents.PLUGIN_READY, (plugin) => {
console.log('Plugin is ready to use!');
});
Complete Example
Boot Scene with Plugin Integration
import { Scene } from 'phaser';
import HyvePhaserPlugin, { HyveEvents } from '@hyve-sdk/phaser';
export class BootScene extends Scene {
private hyve!: HyvePhaserPlugin;
constructor() {
super('Boot');
}
init() {
// Get plugin reference
this.hyve = this.plugins.get('HyvePhaserPlugin') as HyvePhaserPlugin;
// Listen for authentication
this.game.events.once(HyveEvents.AUTHENTICATED, (event) => {
if (event.success) {
// Store user info for other scenes
this.registry.set('userId', event.userId);
this.registry.set('authenticated', true);
// Track successful login
this.hyve.sendTelemetry(
'app',
'auth',
'login',
null,
null,
null,
{ method: 'url_params', description: 'User authenticated via URL params' }
);
}
});
}
preload() {
// Load game assets
this.load.image('logo', 'assets/logo.png');
}
create() {
// Check authentication status
if (this.hyve.isAuthenticated()) {
console.log('Welcome back,', this.hyve.getUserId());
}
// Track game start
this.hyve.sendTelemetry(
'game',
'gameplay',
'start',
'my-awesome-game',
null,
null,
{
version: '1.0.0',
platform: 'web'
}
);
// Proceed to menu
this.scene.start('MainMenu');
}
}
Best Practices
1. Environment-Based Configuration
// Use environment variables for sensitive data
const config = {
plugins: {
global: [{
key: 'HyvePhaserPlugin',
plugin: HyvePhaserPlugin,
start: true,
data: {
apiKey: process.env.NEXT_PUBLIC_HYVE_API_KEY,
isDev: process.env.NODE_ENV !== 'production',
debug: process.env.NODE_ENV !== 'production'
}
}]
}
};
2. Error Handling
// Always handle telemetry failures gracefully
try {
const success = await hyve.trackGameEnd('my-game', score);
if (!success) {
console.warn('Telemetry failed to send');
// Game continues normally
}
} catch (error) {
console.error('Telemetry error:', error);
// Don't let telemetry errors break the game
}
3. Batching High-Frequency Events
// For high-frequency events, consider batching
class GameScene extends Scene {
private pendingEvents: any[] = [];
private eventTimer?: Phaser.Time.TimerEvent;
create() {
// Send batched events every 5 seconds
this.eventTimer = this.time.addEvent({
delay: 5000,
callback: this.sendBatchedEvents,
callbackScope: this,
loop: true
});
}
trackAction(action: string, data: any) {
this.pendingEvents.push({ action, data, timestamp: Date.now() });
}
sendBatchedEvents() {
if (this.pendingEvents.length > 0) {
const hyve = this.plugins.get('HyvePhaserPlugin');
hyve.sendTelemetry(
'game',
'batch',
'events',
null,
null,
null,
{
events: this.pendingEvents,
description: `Batch of ${this.pendingEvents.length} events`
}
);
this.pendingEvents = [];
}
}
}
Troubleshooting
Plugin Not Loading
Problem: Plugin is undefined when trying to access it.
Solution:
// Ensure plugin is loaded before accessing
create() {
// Wait for next frame if needed
this.time.delayedCall(0, () => {
const hyve = this.plugins.get('HyvePhaserPlugin');
if (hyve) {
// Use plugin
}
});
}
Authentication Not Working
Problem: User is not being authenticated from URL parameters.
Checklist:
- Verify URL parameters are correct format
- Listen for AUTHENTICATED event for debugging
- Check browser console for errors
- Ensure the plugin is initialized before trying to authenticate
// Debug authentication
this.game.events.on(HyveEvents.AUTHENTICATED, (event) => {
console.log('Auth event:', event);
if (!event.success) {
console.error('Auth failed:', event.error);
}
});
Telemetry Not Sending
Problem: Telemetry events are not being sent.
Checklist:
- Verify API key is set correctly (check
.env.local) - Check network tab for failed requests to hyve.gg endpoints
- User authentication is optional - telemetry works with 'anonymous' user
- Listen for TELEMETRY_ERROR events
- Verify all required fields (location, category, action) are provided
// Debug telemetry
this.game.events.on(HyveEvents.TELEMETRY_ERROR, (event) => {
console.error('Telemetry failed:', event);
});
TypeScript Types Not Found
Problem: TypeScript cannot find plugin types.
Solution:
// Import types explicitly
import HyvePhaserPlugin, {
HyveEvents,
HyvePhaserPluginConfig
} from '@hyve-sdk/phaser';
// Type your plugin reference
const hyve = this.plugins.get('HyvePhaserPlugin') as HyvePhaserPlugin;
Migration Guide
From Manual SDK Integration
If you're migrating from manual SDK integration to the plugin:
Before (Manual SDK):
import { HyveClient } from '@hyve-sdk/js';
class GameScene extends Scene {
private client: HyveClient;
create() {
this.client = new HyveClient({ apiKey: 'key', isDev: true });
this.client.authenticateFromUrl();
// Manual telemetry
this.client.sendTelemetry(
'game', 'gameplay', 'start', null, null, null, null
);
}
}
After (Plugin):
class GameScene extends Scene {
create() {
const hyve = this.plugins.get('HyvePhaserPlugin');
// Authentication is automatic
// Same telemetry API
hyve.sendTelemetry(
'game', 'gameplay', 'start', null, null, null, null
);
}
}