# ============================================================================= # Wownerogue Server Configuration # ============================================================================= # Copy this file to .env and customize for your environment. # The server validates these settings at startup. Production fails closed on missing secrets, # ambiguous payout flags, simulated blocks, or missing wallet/daemon RPC endpoints. # # This is a generic MIT self-hosting template. The named operator is solely responsible for the # deployment and its legal/financial obligations; Such Software does not operate or endorse it. # Do not set OPERATED_PRODUCT_PROFILE. That opt-in identifier is reserved for the two exact # Such Software operated templates in .env.mainnet.example and .env.stagenet.example. # # QUICK START CONFIGURATIONS: # --------------------------- # 1. FREE MODE (no payments, just play): # PAYMENTS_ENABLED=false # # 2. PAID MODE (1 WOW per game, 2x payout on win): # PAYMENTS_ENABLED=true # PAYMENT_MODES=direct # + Configure wallet RPC and database # # 3. CREDITS MODE (buy bundles, play multiple games): # PAYMENTS_ENABLED=true # PAYMENT_MODES=credits # + Configure wallet RPC and database # # 4. BOTH MODES (let users choose): # PAYMENTS_ENABLED=true # PAYMENT_MODES=direct,credits # ============================================================================= # UNDERSTANDING ATOMIC UNITS # ============================================================================= # Wownero (like Monero) uses "atomic units" - the smallest indivisible unit. # # 1 WOW = 100,000,000,000 atomic units (10^11, or 100 billion) # # Examples: # 1 WOW = 100000000000 # 0.5 WOW = 50000000000 # 0.1 WOW = 10000000000 # 5 WOW = 500000000000 # 10 WOW = 1000000000000 # # Why? Floating point math is imprecise. Atomic units ensure exact calculations. # ============================================================================= # SECTION 1: BASIC SERVER SETTINGS # ============================================================================= # Server port (default: 3000) PORT=3000 # Environment: production | development | debug # - production: minimal logging, real blockchain # - development: verbose logging, can use simulated blocks # - debug: maximum logging, debug hotkeys enabled NODE_ENV=production # External renderer downloads are disabled by default. When true, pinned Pixi/Three # bundles may be loaded from jsDelivr; vendored, self-hosted assets are preferred. RENDERER_CDN_ENABLED=false # Network selection (only matters for Monero - Wownero only has mainnet) MONERO_NETWORK=mainnet # Optional: Display "Hosted by" link in footer (leave empty to hide) # Example: https://yoursite.com or https://github.com/yourname # HOSTED_BY=https://example.com # HOSTED_BY_NAME=Example Host # ============================================================================= # SECTION 2: DATABASE (PostgreSQL) - REQUIRED # ============================================================================= # The game stores user sessions, payment history, and credits in PostgreSQL. # You must create the database and user first (see README). DB_HOST=localhost DB_PORT=5432 DB_NAME=wownerogue DB_USER=wownerogue DB_PASSWORD=your_secure_password_here # ============================================================================= # SECTION 3: GAME DIFFICULTY # ============================================================================= # Controls dungeon size, monster behavior, and effective house edge. # # Preset | Dungeon | Monster Speed | Player Win Rate | Best For # ------------|----------|---------------|-----------------|------------------ # easy | 30x15 | Slow | ~70% | Free play, demos # normal | 45x22 | Medium | ~45% | Balanced gameplay # hard | 55x28 | Fast | ~35% | Challenge mode # casino | 70x35 | Fast | ~30% | Paid modes (default) # # If unset, defaults to 'casino' for paid modes, 'normal' for free mode. # DIFFICULTY_PRESET=casino # Fine-tune individual difficulty parameters (override preset defaults). # Only set these if you want to deviate from the chosen preset. # # Dungeon layout: # DUNGEON_WIDTH=70 # Map width in tiles # DUNGEON_HEIGHT=35 # Map height in tiles # DUNGEON_DUG_PERCENTAGE=0.10 # % of map that's open space (lower = tighter) # DUNGEON_ROOM_WIDTH_MIN=3 # Room width range (min) # DUNGEON_ROOM_WIDTH_MAX=4 # Room width range (max) # DUNGEON_ROOM_HEIGHT_MIN=3 # Room height range (min) # DUNGEON_ROOM_HEIGHT_MAX=4 # Room height range (max) # DUNGEON_CORRIDOR_MIN=6 # Corridor length range (min) # DUNGEON_CORRIDOR_MAX=15 # Corridor length range (max) # # Monster behavior: # MONSTER_SPEED=1.0 # Moves per player move (1.0 = same speed, 0.5 = half) # MONSTER_CHASE=0.97 # Chase probability 0.0-1.0 (rest is random wander) # MONSTER_VISION=22 # Vision range in tiles # MONSTER_DISTANCE=0.30 # Starting distance ratio 0.0-1.0 (lower = closer) # # Treasure placement: # TREASURE_ROOM_POSITION=0.20 # Room position ratio 0.0-1.0 (lower = earlier room) # TREASURE_EXIT_DISTANCE=0.85 # Distance from exit ratio 0.0-1.0 (higher = farther) # ============================================================================= # SECTION 4: PAYMENT SYSTEM OVERVIEW # ============================================================================= # # PAYMENTS_ENABLED is the master switch: # false = FREE mode, anyone can play, no crypto involved # true = Paid mode, requires wallet RPC configuration # # PAYMENT_MODES determines HOW users pay (when payments enabled): # # ┌─────────────────────────────────────────────────────────────────────────┐ # │ MODE: direct │ # ├─────────────────────────────────────────────────────────────────────────┤ # │ • User pays X WOW per game │ # │ • If they WIN (escape dungeon): get PAYOUT_ESCAPE × X back (e.g., 2x) │ # │ • If they WIN with treasure: get PAYOUT_TREASURE × X back (e.g., 3x) │ # │ • If they LOSE (die): house keeps the payment │ # │ │ # │ Example: Pay 1 WOW, win = get 2 WOW. Die = lose 1 WOW. │ # └─────────────────────────────────────────────────────────────────────────┘ # # ┌─────────────────────────────────────────────────────────────────────────┐ # │ MODE: credits │ # ├─────────────────────────────────────────────────────────────────────────┤ # │ • User buys a PACKAGE of credits upfront (e.g., 10 credits for 5 WOW) │ # │ • Each game costs 1 credit (or CREDITS_PER_GAME) │ # │ • Packages can include bonus credits (bulk discount) │ # │ • Payouts are optional - credits are usually just for playing │ # │ │ # │ Example: Buy 10 credits for 5 WOW = 0.5 WOW/game (50% discount!) │ # └─────────────────────────────────────────────────────────────────────────┘ # # ┌─────────────────────────────────────────────────────────────────────────┐ # │ MODE: direct,credits (both enabled) │ # ├─────────────────────────────────────────────────────────────────────────┤ # │ • Users can choose which mode to use │ # │ • If PREFER_CREDITS_FIRST=true, credits are auto-used when available │ # │ • Good for giving users flexibility │ # └─────────────────────────────────────────────────────────────────────────┘ # Master switch: Set to false for completely free play (no wallet needed) PAYMENTS_ENABLED=true # FREE_PLAY_ENABLED: offer FREE play as a CHOICE even when payments are on. Free games # are recorded as game_mode=FREE and appear on the Pleb leaderboard (NOT the Hall of # Champions, which is for paid games). Always effectively on when PAYMENTS_ENABLED=false. # # DEPLOYMENT PATTERNS # • Mainnet prestige: free-to-play + sell service credits/entry, with NO PAYOUTS. # No-payout design is not a legal conclusion; an independent operator needs its own review. # PAYMENTS_ENABLED=true FREE_PLAY_ENABLED=true PAYOUTS_ENABLED=false # DIRECT_PAYOUTS_ENABLED=false CREDITS_PAYOUTS_ENABLED=false # DIRECT_REQUIRES_ADDRESS=false CREDITS_REQUIRES_ADDRESS=false (no payout = no address) # • Test/stagenet: test mechanics can exercise payouts only with conspicuous no-real-value copy. # Never accept or represent mainnet funds under a test-only profile. # PAYMENTS_ENABLED=true PAYOUTS_ENABLED=true *_PAYOUTS_ENABLED=true FREE_PLAY_ENABLED=true # Which payment modes to enable (comma-separated) PAYMENT_MODES=direct,credits # ============================================================================= # SECTION 5: DIRECT MODE CONFIGURATION # ============================================================================= # Only relevant if PAYMENT_MODES includes "direct" # Enable/disable direct payments DIRECT_PAYMENT_ENABLED=true # Price per game in atomic units (100000000000 = 1 WOW) DIRECT_GAME_PRICE=100000000000 # Must user provide a payout address before playing? # true = User must set address first (ensures they can receive winnings) # false = User can play without address (but can't receive payouts!) DIRECT_REQUIRES_ADDRESS=false # Allow guest play without any address? (Usually false for paid modes) DIRECT_ALLOW_GUEST_PLAY=false # Payout multipliers for direct mode wins: # If user pays 1 WOW and ESCAPE multiplier is 2.0, they get 2 WOW on escape. DIRECT_PAYOUTS_ENABLED=false DIRECT_PAYOUT_ESCAPE=2.0 # Escape dungeon = 2x payment DIRECT_PAYOUT_TREASURE=3.0 # Escape WITH treasure = 3x payment # ============================================================================= # SECTION 6: CREDITS MODE CONFIGURATION # ============================================================================= # Only relevant if PAYMENT_MODES includes "credits" # Enable/disable credits system CREDITS_ENABLED=true # How many credits does one game cost? CREDITS_PER_GAME=1 # Must user provide address for credits mode? CREDITS_REQUIRES_ADDRESS=false # When both modes enabled: ALLOW_MIXED_MODE=true # Show both options to user PREFER_CREDITS_FIRST=true # Auto-deduct credits if user has them # Credits payouts (usually DISABLED so purchases grant service play, not prize eligibility) CREDITS_PAYOUTS_ENABLED=false CREDITS_PAYOUT_BASE=50000000000 # Base amount for credit wins CREDITS_PAYOUT_ESCAPE=2.0 # Same as direct mode CREDITS_PAYOUT_TREASURE=3.0 # Same as direct mode # Optional credit-payout bounds. The global PAYOUT_MAX_PER_GAME below is always # the outer safety cap, even when this mode-specific maximum is larger. # CREDITS_PAYOUT_MIN=10000000000 # CREDITS_PAYOUT_MAX=10000000000000 # Credit packages - JSON array of available bundles # Fields: # id - Unique identifier (shown in UI) # credits - Number of game credits included # price - Cost in atomic units (as STRING to avoid JS number precision issues) # bonus - Extra free credits (0 for no bonus) # # Default packages (small discounts to encourage bulk purchase): # small: 10 credits for 9 WOW (~10% discount vs 1 WOW/game direct) # medium: 20 credits for 17 WOW (~15% discount) # large: 50 credits for 40 WOW (~20% discount) # # Tip: Format JSON with newlines for readability, then minify for .env: # [ # {"id":"small", "credits":10, "price":"900000000000", "bonus":0}, # {"id":"medium", "credits":20, "price":"1700000000000", "bonus":0}, # {"id":"large", "credits":50, "price":"4000000000000", "bonus":0} # ] # CREDITS_PACKAGES='[{"id":"small","credits":10,"price":"900000000000","bonus":0},{"id":"medium","credits":20,"price":"1700000000000","bonus":0},{"id":"large","credits":50,"price":"4000000000000","bonus":0}]' # Credit packages can bundle cosmetic/render pack grants and a premium tier via # a "grants" field. Example: # CREDITS_PACKAGES='[{"id":"supporter_25","credits":20,"bonus":5,"price":"1000000000000","grants":{"packs":["generated-skins","kenney-3d-characters"],"premiumLevel":"supporter"}}]' # Standalone products (no game entry or credits required). Each product may grant packs, # a premium tier, and/or funded race tickets. Crypto-match tickets must declare an atomic # value exactly equal to MATCH_ENTRY_FEE_ATOMIC, and the product price must cover every ticket. # COSMETIC_PRODUCTS='[{"id":"pack_3d","label":"3D Character Pack","price":"250000000000","grants":{"packs":["kenney-3d-characters"]}}]' # COSMETIC_PRODUCTS='[{"id":"race_2","label":"Two race entries","price":"10000000000","grants":{"race_entries":2,"race_entry_value_atomic":"5000000000"}}]' # ============================================================================= # SECTION 6b: EARLY ENTRY # ============================================================================= # Early entry lets players start a game immediately without waiting for the # next block. Risk: if a new block arrives before they escape, the game ends. # # Disabled by default for direct (paid-per-game) mode since players paid for # a full block window. Useful for free and credits modes. # Master toggle EARLY_ENTRY_ENABLED=true # Allow early entry in free mode? EARLY_ENTRY_FREE_MODE=true # Allow early entry in credits mode? EARLY_ENTRY_CREDITS_MODE=true # ============================================================================= # SECTION 7: PAYOUT SETTINGS # ============================================================================= # Controls how winnings are sent back to players. # Payouts are batched for efficiency and to reduce transaction fees. # Master payout switch. The Such-operated mainnet product sells credits for leaderboard prestige # without crypto winnings. Its separate XMR stagenet test product uses 2x/3x test-coin payouts. # This switch suppresses payout creation, block/batch dispatch, and retry workers. PAYOUTS_ENABLED=false # Production mainnet payouts are additionally fail-closed. Only set this true after legal review, # bankroll/risk review, and a real wallet-RPC integration test. It is not needed on stagenet. ALLOW_MAINNET_PAYOUTS=false # Minimum payout amount (atomic units). Prevents dust transactions. # 10000000000 = 0.1 WOW PAYOUT_MIN_AMOUNT=10000000000 # Maximum payout per single game (safety limit) # 10000000000000 = 100 WOW PAYOUT_MAX_PER_GAME=10000000000000 # How often to process payout queue (seconds). 300 = every 5 minutes. PAYOUT_BATCH_INTERVAL=300 # Confirmed incoming outputs must reach at least this many chain confirmations before granting # a game, credits, cosmetics, or race tickets. PAYMENT_CONFIRMATIONS=1 # Retry failed payouts this many times before marking as permanently failed. # Failed payouts are logged with error details. Check logs or query: # SELECT * FROM payouts WHERE status = 'failed'; # To retry a permanently failed payout, reset it with: # UPDATE payouts SET status = 'pending', retry_count = 0 WHERE id = ; PAYOUT_MAX_RETRIES=3 # Max payouts to send in one batch (wallet RPC can timeout on large batches) MAX_PAYOUT_BATCH_SIZE=50 # How often to retry failed/stuck payouts (milliseconds). Default: 300000 (5 min) # PAYOUT_RETRY_INTERVAL_MS=300000 # ============================================================================= # SECTION 8: ANTI-ABUSE LIMITS # ============================================================================= # Protect against bots and abuse MAX_GAMES_PER_HOUR=60 # Max games one user can play per hour MAX_PAYOUTS_PER_DAY=100 # Max payout transactions per user per day MAX_CREDIT_PURCHASE_PER_DAY=100000000000000 # Max credit purchase (1000 WOW) GAME_COOLDOWN_SECONDS=5 # Minimum seconds between games # ============================================================================= # SECTION 9: WALLET RPC - REQUIRED FOR PAID MODES # ============================================================================= # The wallet RPC handles: # 1. Generating unique payment addresses for each user # 2. Checking for incoming payments # 3. Sending payouts to winners # # You must run wownero-wallet-rpc (or monero-wallet-rpc) separately: # # wownero-wallet-rpc \ # --wallet-file /path/to/wallet \ # --password-file /path/to/root-readable-wallet-password \ # --rpc-bind-ip 127.0.0.1 \ # --rpc-bind-port 34570 \ # --rpc-login user:strong-random-rpc-password # # Production requires rpc-login even on loopback. The application deliberately proves that an # unauthenticated request receives a Digest challenge; configured credentials do not make an # unauthenticated wallet daemon safe. Never combine rpc-login with --disable-rpc-login, and never # expose wallet RPC beyond the local host. # # The wallet must be synced with a daemon to see incoming transactions. PRIMARY_WALLET_ENDPOINT=http://127.0.0.1:34570 # Required together in production: # WALLET_RPC_USER=wownerogue # WALLET_RPC_PASSWORD=replace-with-a-distinct-strong-rpc-password # ============================================================================= # SECTION 10: BLOCKCHAIN DAEMON RPC # ============================================================================= # Used to get current block height for game synchronization. # This is the daemon (wownerod/monerod), NOT the wallet. # # The game syncs to block timing - each block triggers game state checks. PRIMARY_RPC_ENDPOINT=http://127.0.0.1:34568 FALLBACK_RPC_ENDPOINT=http://127.0.0.1:34568 # OPTIONAL: additional daemons, comma or whitespace separated, in PREFERENCE ORDER. # PRIMARY/FALLBACK above are appended to this list and the whole thing is deduplicated: # note that the two defaults are the SAME host, so out of the box there is exactly one node # and no redundancy at all. # # A fallback only helps if it can fail independently. A second daemon in the same rack (or the # same office) shares the outage that takes the first one down, so it buys nothing. What actually # adds availability is a node reachable over a separate path: a home node across the mesh, or a # public/community node. # # Every endpoint must still pass the chain-identity check before it may answer, so listing a # remote node cannot silently serve a different chain's data. For FREE / CREDITS instances the # daemon is only supplying block height, so a remote node is a reasonable fallback. For instances # taking PAYMENTS, prefer daemons you control: block height feeds match fairness and entropy, and # an untrusted node is an untrusted input to those. # # RPC_ENDPOINTS=http://127.0.0.1:34568,http://192.0.2.40:34568 # # How long to stay on a backup before re-testing the preferred node (ms, minimum 1000). # RPC_PREFERRED_RETRY_MS=60000 # # When NO endpoint answers, the server does not guess: entries are refused with a clear message # and nothing is charged. There is intentionally no wallet failover: two wallet-rpc processes # over one wallet file can spend the same outputs. So a wallet outage declines paid intake while # credits and free play keep working. # How often to poll for new blocks (milliseconds) RPC_POLL_INTERVAL=2000 # ============================================================================= # SECTION 11: ADMIN API # ============================================================================= # Secure endpoints for refunds, credit adjustments, and user management. # Generate a strong random key and keep it secret! # Required in production. Generate with: openssl rand -hex 32 # ADMIN_API_KEY=your-64-character-hex-key-here # Public operator and paid-play disclosure controls. Production paid instances fail startup # until these are explicitly set to truthful, non-placeholder values. # Independent deployments must identify their own operator. Such Software operates only # play.wowne.ro and monerogue.app; it does not endorse or accept responsibility for self-hosts. # OPERATOR_NAME=Responsible operator name # OPERATOR_CONTACT_URL=mailto:support@example.com # OPERATOR_CONTACT_LABEL=Support # LEGAL_POLICY_VERSION=2026-07-22-v1 # TERMS_EFFECTIVE_DATE=2026-07-22 # MINIMUM_AGE=18 # PAID_ACKNOWLEDGEMENT_REQUIRED=true # Leave unset for third-party/self-hosted deployments. Official templates set one reviewed value: # OPERATED_PRODUCT_PROFILE=such-play-wow-prestige | such-monerogue-stagenet # Optional plain-language location restriction notice supplied after legal review: # RESTRICTED_LOCATIONS_NOTICE= # Use in requests: # curl -H "X-Admin-Key: your-key" http://localhost:3000/api/admin/... # Allowed origins for admin API CORS (comma-separated, only needed for cross-origin) # Same-origin requests are always allowed. Leave unset if admin panel is on same host. # ALLOWED_ORIGINS=https://admin.example.com # Set to 'true' ONLY when running behind a trusted reverse proxy (Nginx/Caddy). When # true, the real client IP is read from the X-Forwarded-For header for rate limiting and # req.ip. Leave unset/false for direct exposure, otherwise clients could spoof their IP. # TRUST_PROXY=true # TRUST_PROXY_HOPS=1 # NPM directly in front of Node # Anti-instant-death grace (ms) before a block-timeout can end a game. This is NOT a # fairness floor: random block timing is the core mechanic. It only prevents the # degenerate case where a block lands the instant a game starts (before the dungeon # renders / before the first move is possible). Default 2000 (2s); set 0 to disable. # GAME_START_GRACE_MS=2000 # ============================================================================= # SECTION 13: ADMIN ALERTS (Resend) # ============================================================================= # Email alerts for low wallet balance and critical issues. # Sign up at https://resend.com to get an API key. # Resend API key # RESEND_API_KEY=re_xxxxxxxxxxxxx # Admin email to receive alerts # ADMIN_EMAIL=admin@example.com # From address for alert emails (must be verified in Resend) # Default: alerts@monerogue.app # ALERT_FROM_EMAIL=noreply@yourdomain.com # ------------------------- # BALANCE THRESHOLDS # ------------------------- # Two-tier alert system for wallet balance monitoring: # # BALANCE_WARN: Sends email alert when balance drops below this level # You should top up the wallet soon. # # BALANCE_CRITICAL: Sends email AND HALTS NEW GAMES when balance drops below # Users will see a modal: "Sorry, the house balance is too low..." # Games resume automatically when balance is restored above this threshold. # # All values in atomic units: # WOW: 1 WOW = 100000000000 (10^11) # XMR: 1 XMR = 1000000000000 (10^12) # Warning threshold - sends email alert (default: 0.1 WOW/XMR) BALANCE_WARN=100000000000 # Critical threshold - halts new games (default: 0.01 WOW/XMR) BALANCE_CRITICAL=10000000000 # Scan recently expired invoices for transfers that mined after the 30-minute watcher stopped. # Valid receipts create manual-review records only; they never auto-grant stale entries/products. LATE_PAYMENT_RECONCILE_HOURS=72 LATE_PAYMENT_RECONCILE_BATCH=100 # Legacy alias (superseded by BALANCE_WARN, kept for backwards compatibility) # LOW_BALANCE_THRESHOLD=100000000000 # ------------------------- # OTHER ALERT SETTINGS # ------------------------- # Alert when pending/failed payouts exceed this count HIGH_PENDING_THRESHOLD=10 # Alert when payout processing or refund requested/processing remains nonterminal this long. # These alerts never retry a transfer. Default: 900000 (15 minutes). FINANCIAL_REVIEW_STALE_MS=900000 # Alert cooldown in milliseconds (avoid spam) # Default: 3600000 (1 hour) ALERT_COOLDOWN_MS=3600000 # ============================================================================= # SECTION 13b: OPTIONAL MAINNET FINANCIAL-EVENT EXPORT # ============================================================================= # Confirmed payments and final refunds are snapshotted to a durable outbox. Configure both values # only for a reviewed MAINNET accounting sink that honors Idempotency-Key. Test-network rows are # suppressed locally and must never be exported. Keep the bearer token in the protected runtime # environment; never commit it. # FINANCIAL_EVENT_SINK_URL=https://ledger.operator.example/v1/events # FINANCIAL_EVENT_SINK_TOKEN=CHANGE_ME_STRONG_ACCOUNTING_SINK_TOKEN FINANCIAL_EVENT_ACCOUNT_REF=wowngeon:receipts # FINANCIAL_EVENT_POLL_MS=60000 # FINANCIAL_EVENT_BATCH_SIZE=20 # FINANCIAL_EVENT_MAX_ATTEMPTS=8 # ============================================================================= # SECTION 14: SMIRK WALLET INTEGRATION # ============================================================================= # Smirk is a browser extension wallet for Wownero/Monero. # https://smirk.network # # Enable this for Wownero mainnet. Disable for Monero stagenet # (Smirk doesn't support stagenet addresses). # Enable Smirk wallet connection button (default: true) # Set to false for Monero stagenet deployments SMIRK_ENABLED=true # ============================================================================= # SECTION 14b: BLOCK EXPLORER # ============================================================================= # URL prefix for linking transaction hashes to a block explorer. # Include the trailing slash. TX hash will be appended directly. # Leave unset to disable clickable TX links in transaction history. # # Wownero: https://explore.wowne.ro/tx/ # Monero: https://xmrchain.net/tx/ EXPLORER_TX_URL=https://explore.wowne.ro/tx/ # ============================================================================= # SECTION 15: DEVELOPMENT/DEBUG OPTIONS # ============================================================================= # These are for testing only. Don't use in production with real money! # Block source: daemon (real blockchain) | simulated (fake blocks for testing) # Paid modes always use daemon unless FORCE_SIMULATED_BLOCKS=true BLOCK_SOURCE=daemon # Force simulated blocks even in paid mode (DANGEROUS - for testing only!) # FORCE_SIMULATED_BLOCKS=false # ============================================================================= # LEGACY OPTIONS (deprecated - use PAYMENT_MODES instead) # ============================================================================= # GAME_MODE: FREE | PAID_SINGLE | PAID_CREDITS # Kept for backward compatibility. New setups should use PAYMENT_MODES. # GAME_MODE= CRYPTO_TYPE=WOW # ============================================================================= # Tavern & Multiplayer modes (optional) # ============================================================================= # Tavern: a walkable social room (chat, avatars, spectator camera). TAVERN_ENABLED=true # Server-tick / snapshot broadcast cadence in ms (default 100 = 10 Hz) # TAVERN_TICK_MS=100 # ============================================================================= # Match mode (multiplayer races) # ============================================================================= # Enable real-time multiplayer races. Solo/Tavern are unaffected. MATCH_ENABLED=true # Max players per match, also bounded by the selected ruleset (built-ins max at 8). MATCH_MAX_PLAYERS=4 # Server tick interval in ms (default 250 = 4 Hz). # MATCH_TICK_MS=250 # Server-selected match ruleset. Clients cannot choose this value. # Built-ins: race, last-alive, score-attack, coop-escape. Default: race. MATCH_RULESET_ID=race # Paid matches freeze entrants at H, target H+2, and activate at target+1 by default. # Production requires explicit safe integers from 2 through 100 for both settings. MATCH_PAID_ENTROPY_DELAY_BLOCKS=2 MATCH_PAID_ENTROPY_CONFIRMATIONS=2 # Minimum race duration in ms before the next block can end it (default 20s). # MATCH_MIN_DURATION_MS=20000 # Hard ceiling in ms after which a race is force-ended (default 4m). # MATCH_HARD_CEILING_MS=240000 # Credits cost for prestige-only races (default 1). # MATCH_CREDITS_COST=1 # Crypto race house fee percent. Production crypto matches require an explicit value from # 0 (inclusive) through 100 (exclusive). MATCH_HOUSE_FEE_PERCENT=5 # Required crypto-race per-player entry fee in atomic units when payout matches are enabled. MATCH_ENTRY_FEE_ATOMIC=5000000000 # Crypto admission requires all three explicit gates plus a worst-case winner cap. Co-op has no # winner-takes-pot split contract and is therefore rejected for crypto matches. MATCH_CRYPTO_RACE_ENABLED=false MATCH_PAYOUTS_ENABLED=false MATCH_PAYOUT_MAX=50000000000