GlobalPulse - Live Configuration
GlobalPulse is Globio's live configuration service. Update game settings, feature flags, and content without releasing app updates.
🚀 Quick Start
import { GlobalPulse } from '@stanlink/globio'
const config = new GlobalPulse({
apiKey: 'your-api-key',
projectId: 'your-project-id'
})
// Get configuration value
const eventActive = await config.getValue('christmas_event', false)
if (eventActive) {
showChristmasContent()
}⚙️ Configuration Management
Basic Values
// Get string value
const welcomeMessage = await config.getValue('welcome_message', 'Welcome to the game!')
// Get number value
const maxLevel = await config.getValue('max_level', 100)
// Get boolean value
const newFeatureEnabled = await config.getValue('new_feature_enabled', false)
// Get object value
const gameSettings = await config.getValue('game_settings', {
difficulty: 'normal',
soundEnabled: true,
musicVolume: 0.8
})Real-time Updates
// Listen for configuration changes
const unsubscribe = config.onConfigChange((key, value) => {
console.log(`Config updated: ${key} = ${value}`)
switch (key) {
case 'maintenance_mode':
if (value) {
showMaintenanceMessage()
} else {
hideMaintenanceMessage()
}
break
case 'daily_bonus':
updateDailyBonusUI(value)
break
}
})
// Stop listening
unsubscribe()🎮 Gaming Use Cases
Feature Flags
// Enable/disable features remotely
const features = {
newGameMode: await config.getValue('new_game_mode_enabled', false),
socialFeatures: await config.getValue('social_features_enabled', true),
inAppPurchases: await config.getValue('iap_enabled', true),
leaderboards: await config.getValue('leaderboards_enabled', true)
}
// Conditionally show UI elements
if (features.newGameMode) {
showNewGameModeButton()
}
if (features.socialFeatures) {
enableFriendSystem()
}Live Events
// Manage live events
const currentEvent = await config.getValue('current_event', null)
if (currentEvent) {
const eventConfig = await config.getValue(`events.${currentEvent}`, {})
// Apply event settings
applyEventSettings({
name: eventConfig.name,
startTime: new Date(eventConfig.startTime),
endTime: new Date(eventConfig.endTime),
rewards: eventConfig.rewards,
specialRules: eventConfig.specialRules
})
}
// Listen for event changes
config.onConfigChange('current_event', (eventName) => {
if (eventName) {
startEvent(eventName)
} else {
endCurrentEvent()
}
})Game Balance
// Adjust game balance without updates
const gameBalance = {
playerHealth: await config.getValue('player_health', 100),
enemyDamage: await config.getValue('enemy_damage', 25),
coinDropRate: await config.getValue('coin_drop_rate', 0.3),
experienceMultiplier: await config.getValue('xp_multiplier', 1.0)
}
// Apply balance changes
player.maxHealth = gameBalance.playerHealth
enemies.forEach(enemy => {
enemy.damage = gameBalance.enemyDamage
})A/B Testing
// A/B test different game mechanics
const playerGroup = await config.getValue(`ab_test_group_${playerId}`, 'A')
const testConfig = await config.getValue(`ab_test_${playerGroup}`, {})
switch (playerGroup) {
case 'A':
// Original game mechanics
setupOriginalMechanics()
break
case 'B':
// New game mechanics
setupNewMechanics(testConfig)
break
}
// Track A/B test results
trackEvent('ab_test_interaction', {
group: playerGroup,
action: 'game_completed',
result: gameResult
})🔧 Advanced Features
Conditional Configuration
// Configuration based on user properties
const userTier = getCurrentUserTier() // 'free', 'premium', 'vip'
const adFrequency = await config.getValue(`ad_frequency_${userTier}`, {
free: 30, // Every 30 seconds
premium: 120, // Every 2 minutes
vip: 0 // No ads
})
// Configuration based on platform
const platform = getPlatform() // 'ios', 'android', 'web'
const storeConfig = await config.getValue(`store_config_${platform}`, {})Scheduled Changes
// Check for scheduled configuration changes
const scheduledConfigs = await config.getValue('scheduled_configs', [])
scheduledConfigs.forEach(scheduledConfig => {
const { key, value, activateAt } = scheduledConfig
const activationTime = new Date(activateAt)
if (Date.now() >= activationTime.getTime()) {
// Apply scheduled configuration
applyConfigValue(key, value)
}
})Configuration Validation
// Validate configuration values
function validateConfig(key, value, expectedType) {
if (typeof value !== expectedType) {
console.warn(`Invalid config type for ${key}: expected ${expectedType}, got ${typeof value}`)
return false
}
return true
}
// Safe configuration getter
async function getSafeConfig(key, defaultValue, validator) {
try {
const value = await config.getValue(key, defaultValue)
if (validator && !validator(value)) {
console.warn(`Config validation failed for ${key}, using default`)
return defaultValue
}
return value
} catch (error) {
console.error(`Failed to get config ${key}:`, error)
return defaultValue
}
}
// Usage
const maxPlayers = await getSafeConfig('max_players', 4, (value) => {
return typeof value === 'number' && value > 0 && value <= 100
})📱 Platform Examples
Unity C#
// Unity configuration
public class GameConfig : MonoBehaviour {
void Start() {
LoadGameConfig();
}
async void LoadGameConfig() {
// Get configuration values
bool eventActive = await GlobalPulse.GetBool("summer_event", false);
int maxLevel = await GlobalPulse.GetInt("max_level", 50);
float difficultyMultiplier = await GlobalPulse.GetFloat("difficulty_multiplier", 1.0f);
// Apply configuration
if (eventActive) {
EnableSummerEvent();
}
GameManager.MaxLevel = maxLevel;
GameManager.DifficultyMultiplier = difficultyMultiplier;
}
void OnEnable() {
// Listen for config changes
GlobalPulse.OnConfigChanged += OnConfigChanged;
}
void OnConfigChanged(string key, object value) {
switch (key) {
case "maintenance_mode":
if ((bool)value) {
ShowMaintenanceScreen();
}
break;
}
}
}Flutter/Dart
// Flutter configuration
class GameConfigService {
static Future<void> loadConfig() async {
// Load game configuration
final eventActive = await GlobalPulse.getBool('weekend_bonus', false);
final bonusMultiplier = await GlobalPulse.getDouble('bonus_multiplier', 1.0);
// Apply configuration
if (eventActive) {
GameState.bonusMultiplier = bonusMultiplier;
}
}
static void listenForChanges() {
GlobalPulse.onConfigChange.listen((ConfigChange change) {
switch (change.key) {
case 'new_feature_enabled':
if (change.value as bool) {
_enableNewFeature();
}
break;
}
});
}
}💡 Best Practices
Configuration Structure
// ✅ Good: Organized configuration
const config = {
// Game balance
'game.player_health': 100,
'game.enemy_damage': 25,
'game.coin_drop_rate': 0.3,
// Features
'features.new_game_mode': false,
'features.social_system': true,
'features.leaderboards': true,
// Events
'events.current': 'halloween_2024',
'events.halloween_2024.active': true,
'events.halloween_2024.bonus_xp': 2.0,
// A/B Tests
'ab_test.new_ui.enabled': true,
'ab_test.new_ui.percentage': 50
}
// ❌ Avoid: Flat, unclear structure
const config = {
'health': 100,
'damage': 25,
'event': true,
'test': 50
}Caching Strategy
// Cache configuration with TTL
class ConfigCache {
constructor(ttl = 300000) { // 5 minutes
this.cache = new Map()
this.ttl = ttl
}
async get(key, defaultValue) {
const cached = this.cache.get(key)
if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.value
}
const value = await config.getValue(key, defaultValue)
this.cache.set(key, {
value,
timestamp: Date.now()
})
return value
}
invalidate(key) {
this.cache.delete(key)
}
}Next: Learn about GlobalSync Multiplayer →