Skip to main content

Environment Variables Reference

Comprehensive reference for all environment variables used across Hyperscape packages.

Server (packages/server/.env)

Required (Production)

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@host:5432/hyperscape
JWT_SECRETJWT signing secret (required in prod/staging)openssl rand -base64 32
PRIVY_APP_IDPrivy authentication app IDclabcd1234...
PRIVY_APP_SECRETPrivy authentication secretabc123...
ADMIN_CODEAdmin API access codeRandom secure string

Database

VariableDefaultDescription
USE_LOCAL_POSTGREStrueUse local Docker PostgreSQL
POSTGRES_URL-Alternative to DATABASE_URL
DATABASE_POOL_MAX10Max database connections

Server Configuration

VariableDefaultDescription
PORT5555HTTP server port
NODE_ENVdevelopmentEnvironment (development/production/staging)
DISABLE_RATE_LIMITfalseDisable rate limiting
ALLOW_DESTRUCTIVE_CHANGESfalseAllow destructive database operations

Streaming & GPU Rendering

VariableDefaultDescription
STREAMING_DUEL_ENABLEDfalseEnable duel streaming
STREAM_CAPTURE_MODEcdpCapture mode (cdp/webcodecs)
STREAM_CAPTURE_WIDTH1280Video width
STREAM_CAPTURE_HEIGHT720Video height
STREAM_FPS30Frame rate
STREAM_VIDEO_BITRATE_KBPS4500Video bitrate
STREAM_AUDIO_BITRATE_KBPS128Audio bitrate
STREAM_LOW_LATENCYfalseUse zerolatency tune (disables B-frames)
STREAM_CAPTURE_CHANNELchrome-devChrome channel (chrome-dev = google-chrome-unstable)
STREAM_CAPTURE_HEADLESSfalseRun headless (false = use Xvfb/Xorg)
STREAM_CAPTURE_ANGLEvulkanANGLE backend (vulkan/swiftshader)
STREAM_CAPTURE_DISABLE_WEBGPUfalseDisable WebGPU rendering
DUEL_CAPTURE_USE_XVFBtrueUse Xvfb instead of Xorg (set dynamically by deploy-vast.sh)
DISPLAY:99X server display number
VK_ICD_FILENAMES/usr/share/vulkan/icd.d/nvidia_icd.jsonForce NVIDIA Vulkan ICD
FFMPEG_PATH/usr/bin/ffmpegFFmpeg binary path
FFMPEG_HWACCELautoHardware acceleration (auto/nvidia/mac)

Audio Capture

VariableDefaultDescription
STREAM_AUDIO_ENABLEDtrueEnable audio capture
PULSE_AUDIO_DEVICEchrome_audio.monitorPulseAudio monitor device
PULSE_SERVERunix:/tmp/pulse-runtime/pulse/nativePulseAudio server socket
XDG_RUNTIME_DIR/tmp/pulse-runtimeRuntime directory for PulseAudio

RTMP Streaming

VariableDefaultDescription
TWITCH_STREAM_KEY-Twitch stream key
TWITCH_RTMP_URLrtmp://live.twitch.tv/appTwitch RTMP server
KICK_STREAM_KEY-Kick stream key
KICK_RTMP_URLrtmps://fa723fc1b171.global-contribute.live-video.net/appKick RTMP server
X_STREAM_KEY-X/Twitter stream key
X_RTMP_URLrtmp://sg.pscp.tv:80/xX/Twitter RTMP server
YOUTUBE_STREAM_KEY""YouTube stream key (empty = disabled)
YOUTUBE_RTMP_URL-YouTube RTMP server
STREAMING_CANONICAL_PLATFORMtwitchPlatform for anti-cheat timing
STREAMING_PUBLIC_DELAY_MS0Public data delay (0 = live betting)

Stream Recovery

VariableDefaultDescription
STREAM_CAPTURE_RECOVERY_TIMEOUT_MS30000Recovery timeout
STREAM_CAPTURE_RECOVERY_MAX_FAILURES6Max recovery failures

Solana

VariableDefaultDescription
SOLANA_DEPLOYER_PRIVATE_KEY-Solana keypair (base58 or JSON array)
SOLANA_RPC_URLhttps://api.devnet.solana.comSolana RPC endpoint
SOLANA_WS_URLwss://api.devnet.solana.com/Solana WebSocket endpoint
SOLANA_ARENA_AUTHORITY_SECRET-Arena authority keypair (falls back to DEPLOYER)
SOLANA_ARENA_REPORTER_SECRET-Arena reporter keypair (falls back to DEPLOYER)
SOLANA_ARENA_KEEPER_SECRET-Arena keeper keypair (falls back to DEPLOYER)
SOLANA_MM_PRIVATE_KEY-Market maker keypair
MARKET_MINTWSOLMarket token mint (defaults to native token)
ENABLE_PERPS_ORACLEfalseEnable perps oracle updates

Arena & Betting

VariableDefaultDescription
DUEL_MARKET_MAKER_ENABLEDfalseEnable market maker bot
DUEL_BETTING_ENABLEDfalseEnable betting system
ARENA_SERVICE_ENABLEDfalseEnable arena service
ARENA_EXTERNAL_BET_WRITE_KEY-External betting API key
DUEL_SKIP_CHAIN_SETUPfalseSkip blockchain setup

AI Agents

VariableDefaultDescription
AUTO_START_AGENTSfalseAuto-start agents on server start
AUTO_START_AGENTS_MAX10Max agents to auto-start
STREAMING_DUEL_COMBAT_AI_ENABLEDfalseEnable DuelCombatAI for streaming

CDN & Assets

VariableDefaultDescription
PUBLIC_CDN_URLhttp://localhost:8080Asset CDN URL
DUEL_ALLOW_INHERITED_CDN_URLfalseAllow CDN URL inheritance

Performance

VariableDefaultDescription
SERVER_RUNTIME_MAX_TICKS_PER_FRAME1Max ticks per frame
SERVER_RUNTIME_MIN_DELAY_MS10Min delay between frames
GAME_STATE_POLL_TIMEOUT_MS5000Game state poll timeout
GAME_STATE_POLL_INTERVAL_MS3000Game state poll interval
DUEL_RUNTIME_HEALTH_INTERVAL_MS15000Health check interval
DUEL_RUNTIME_HEALTH_MAX_FAILURES30Max health check failures

Memory Management

VariableDefaultDescription
MALLOC_TRIM_THRESHOLD_-1Disable malloc trimming
MIMALLOC_ALLOW_DECOMMIT0Disable memory decommit
MIMALLOC_ALLOW_RESET0Disable memory reset
MIMALLOC_PAGE_RESET0Disable page reset
MIMALLOC_PURGE_DELAY1000000Delay memory purge

Game URLs

VariableDefaultDescription
GAME_URLhttp://localhost:3333/?page=streamPrimary game URL
GAME_FALLBACK_URLS-Comma-separated fallback URLs

Client (packages/client/.env)

Required

VariableDescriptionExample
PUBLIC_PRIVY_APP_IDPrivy app ID (must match server)clabcd1234...

API Endpoints

VariableDefaultDescription
PUBLIC_API_URLhttp://localhost:5555Game server HTTP URL
PUBLIC_WS_URLws://localhost:5555/wsGame server WebSocket URL
PUBLIC_CDN_URLhttp://localhost:8080Asset CDN URL

Development

VariableDefaultDescription
VITE_PORT3333Vite dev server port

Plugin Hyperscape (packages/plugin-hyperscape/.env)

LLM Providers

At least one required:
VariableDescription
OPENAI_API_KEYOpenAI API key
ANTHROPIC_API_KEYAnthropic API key
OPENROUTER_API_KEYOpenRouter API key

Hyperscape Connection

VariableDefaultDescription
HYPERSCAPE_SERVER_URLws://localhost:5555/wsGame server WebSocket URL
HYPERSCAPE_AUTO_RECONNECTtrueAuto-reconnect on disconnect
HYPERSCAPE_AUTH_TOKEN-Optional Privy auth token
HYPERSCAPE_PRIVY_USER_ID-Optional Privy user ID

Asset Forge (packages/asset-forge/.env)

AI Services

VariableDescription
OPENAI_API_KEYOpenAI API key (for GPT-4 Vision)
MESHY_API_KEYMeshyAI API key (for 3D generation)
ELEVENLABS_API_KEYElevenLabs API key (for voice/music)

Server Configuration

VariableDefaultDescription
ASSET_FORGE_PORT3400UI server port
ASSET_FORGE_API_PORT3401API server port

Ecosystem Config (ecosystem.config.cjs)

PM2 configuration for production deployment. Reads from environment or provides defaults.

Key Variables

All server variables above, plus:
VariableDefaultDescription
DUEL_DISABLE_BRIDGE_CAPTUREfalseDisable RTMP bridge capture
DUEL_FORCE_WEBGL_FALLBACKfalseForce WebGL (removed - WebGPU required)

GitHub Secrets (CI/CD)

Required for automated deployments:

Vast.ai Deployment

SecretDescription
VAST_HOSTVast.ai instance IP
VAST_PORTSSH port
VAST_SSH_KEYSSH private key
VAST_SERVER_URLPublic server URL (for maintenance mode API)

Streaming

SecretDescription
TWITCH_STREAM_KEYTwitch stream key
KICK_STREAM_KEYKick stream key
KICK_RTMP_URLKick RTMP URL
X_STREAM_KEYX/Twitter stream key
X_RTMP_URLX/Twitter RTMP URL

Database & Security

SecretDescription
DATABASE_URLPostgreSQL connection string
JWT_SECRETJWT signing secret
ADMIN_CODEAdmin API access code

Blockchain

SecretDescription
SOLANA_DEPLOYER_PRIVATE_KEYSolana keypair (base58 or JSON array)
ARENA_EXTERNAL_BET_WRITE_KEYExternal betting API key

Cloudflare

SecretDescription
CLOUDFLARE_API_TOKENCloudflare API token (for Pages/R2)
CLOUDFLARE_ACCOUNT_IDCloudflare account ID

Environment-Specific Configurations

Local Development

Minimal configuration for local development:
# packages/client/.env
PUBLIC_PRIVY_APP_ID=your-app-id

# packages/server/.env
PUBLIC_PRIVY_APP_ID=your-app-id
PRIVY_APP_SECRET=your-app-secret
JWT_SECRET=your-random-secret
All other variables use defaults that work with bun run dev.

Production (Railway)

# packages/server/.env (Railway environment variables)
NODE_ENV=production
DATABASE_URL=postgresql://...
JWT_SECRET=...
PRIVY_APP_ID=...
PRIVY_APP_SECRET=...
ADMIN_CODE=...
PUBLIC_CDN_URL=https://assets.hyperscape.club
USE_LOCAL_POSTGRES=false

Production (Vast.ai Streaming)

# Passed via GitHub Secrets → SSH → /tmp/hyperscape-secrets.env → packages/server/.env
DATABASE_URL=postgresql://...
JWT_SECRET=...
TWITCH_STREAM_KEY=...
KICK_STREAM_KEY=...
KICK_RTMP_URL=...
X_STREAM_KEY=...
X_RTMP_URL=...
YOUTUBE_STREAM_KEY=
SOLANA_DEPLOYER_PRIVATE_KEY=...
ARENA_EXTERNAL_BET_WRITE_KEY=...
Plus all ecosystem.config.cjs defaults for streaming configuration.

Variable Precedence

  1. Environment variables (highest priority)
  2. .env file in package directory
  3. Default values in code
Example from ecosystem.config.cjs:
DATABASE_URL: process.env.DATABASE_URL || 
              process.env.POSTGRES_URL || 
              "postgresql://hyperscape:hyperscape_dev_password@localhost:5488/hyperscape"

Security Best Practices

Never Commit Secrets

Add to .gitignore:
.env
.env.local
.env.production
*.env
deployer-keypair.json

Use GitHub Secrets

For CI/CD, store secrets in GitHub repository settings:
  • Settings → Secrets and variables → Actions
  • Add repository secrets (not environment secrets for better compatibility)

Rotate Secrets Regularly

  • JWT_SECRET: Rotate every 90 days
  • API keys: Rotate when team members leave
  • Stream keys: Rotate if exposed in logs

Generate Secure Secrets

# JWT_SECRET
openssl rand -base64 32

# ADMIN_CODE
openssl rand -hex 32

# Random password
openssl rand -base64 24

Troubleshooting

Secrets Not Persisting (Vast.ai)

Problem: Stream keys or DATABASE_URL not working after deployment. Cause: Git reset overwrites .env file, or stale environment variables override .env values. Fix: Secrets are now written to /tmp/hyperscape-secrets.env before git reset, then copied back. Verify:
# Check /tmp secrets file
cat /tmp/hyperscape-secrets.env

# Check .env file
cat /root/hyperscape/packages/server/.env

# Check environment (should show ***configured***)
grep "STREAM_KEY" /root/hyperscape/logs/duel-out.log

JWT_SECRET Missing Error

Problem: Server throws error on startup: “JWT_SECRET is required in production/staging” Cause: JWT_SECRET not set in production environment. Fix:
# Generate secret
openssl rand -base64 32

# Add to .env
echo "JWT_SECRET=your-generated-secret" >> packages/server/.env

# Or set in Railway/Vast.ai environment

Stream Keys Not Working

Problem: Streams not appearing on Twitch/Kick/X. Cause: Stale stream keys in environment override .env file values. Fix: The deploy script now explicitly unsets and re-exports stream keys:
# In deploy-vast.sh
unset TWITCH_STREAM_KEY X_STREAM_KEY X_RTMP_URL KICK_STREAM_KEY KICK_RTMP_URL
unset YOUTUBE_STREAM_KEY
export YOUTUBE_STREAM_KEY=""
source /root/hyperscape/packages/server/.env
Verify keys are configured:
pm2 logs hyperscape-duel | grep "STREAM_KEY"
# Should show: ***configured*** (not NOT SET)

DATABASE_URL Lost After Git Reset

Problem: Database connection fails after deployment. Cause: Git reset overwrites .env file. Fix: Secrets are now written to /tmp before git reset:
# In deploy-vast.yml
cat > /tmp/hyperscape-secrets.env << 'EOF'
DATABASE_URL=${{ secrets.DATABASE_URL }}
# ... other secrets
EOF

# In deploy-vast.sh (after git reset)
cp /tmp/hyperscape-secrets.env /root/hyperscape/packages/server/.env

Solana Keypair Not Found

Problem: Keeper bot or Anchor tools fail with “keypair not found”. Cause: ~/.config/solana/id.json not created from SOLANA_DEPLOYER_PRIVATE_KEY. Fix:
# Run decode-key script
cd /root/hyperscape
bun run scripts/decode-key.ts

# Verify keypair exists
ls -la ~/.config/solana/id.json

# Check public key
solana-keygen pubkey ~/.config/solana/id.json