Wownerogue

A browser-based roguelike synchronized with crypto block timing. A run is a race
against the next block: reach the exit before the block lands, or the house wins.
The same codebase runs the solo dungeon, the social Tavern, and operator-selected
PvP and race rulesets, with separate free and paid leaderboards.

Self-hostable under the MIT License. See README.md to run it, docs/ARCHITECTURE.md
for the design, and docs/DEPLOY.md to operate an instance.
This commit is contained in:
jwinterm
2026-07-27 08:23:01 -04:00
commit fad2a695bd
578 changed files with 102281 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
# Such Software operated product: play.wowne.ro.
# Wownero mainnet free play + pay-for-credits leaderboard/prestige only.
# No payouts, prizes, cash-out, or crypto racing; not offered/marketed as gambling.
# Legal classification still depends on applicable law.
# Copy to .env, replace every CHANGE_ME value, then run `npm run preflight`.
NODE_ENV=production
RENDERER_CDN_ENABLED=false
HOST=0.0.0.0
PORT=3000
TRUST_PROXY=true
TRUST_PROXY_HOPS=1
BLOCK_SOURCE=daemon
CRYPTO_TYPE=WOW
MONERO_NETWORK=mainnet
SMIRK_ENABLED=false
HOSTED_BY=https://play.wowne.ro
OPERATED_PRODUCT_PROFILE=such-play-wow-prestige
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=wownerogue
DB_USER=wownerogue
DB_PASSWORD=CHANGE_ME_STRONG_DATABASE_PASSWORD
ADMIN_API_KEY=CHANGE_ME_WITH_OPENSSL_RAND_HEX_32
# Exact public operator/disclosure metadata for the Such Software operated service.
OPERATOR_NAME=Such Software
OPERATOR_CONTACT_URL=mailto:apps@such.software
OPERATOR_CONTACT_LABEL=apps@such.software
LEGAL_POLICY_VERSION=2026-07-22-v1
TERMS_EFFECTIVE_DATE=2026-07-22
MINIMUM_AGE=18
PAID_ACKNOWLEDGEMENT_REQUIRED=true
# Optional plain-language notice supplied after jurisdiction-specific legal review.
# RESTRICTED_LOCATIONS_NOTICE=
# Free runs rank on the Pleb board; purchased credits rank on the paid prestige board.
PAYMENTS_ENABLED=true
FREE_PLAY_ENABLED=true
GAME_MODE=PAID_CREDITS
PAYMENT_MODES=credits
ALLOW_MIXED_MODE=false
PREFER_CREDITS_FIRST=true
# Direct per-run payment is outside the operated product scope and must remain disabled.
DIRECT_PAYMENT_ENABLED=false
DIRECT_GAME_PRICE=100000000000
DIRECT_REQUIRES_ADDRESS=false
DIRECT_ALLOW_GUEST_PLAY=false
DIRECT_PAYOUTS_ENABLED=false
CREDITS_ENABLED=true
CREDITS_PER_GAME=1
CREDITS_REQUIRES_ADDRESS=false
CREDITS_PAYOUTS_ENABLED=false
CREDITS_PACKAGES='[{"id":"small","credits":10,"price":"900000000000","bonus":0}]'
# Master interlock: the mainnet prestige profile must never create or dispatch winnings.
PAYOUTS_ENABLED=false
ALLOW_MAINNET_PAYOUTS=false
PAYMENT_CONFIRMATIONS=1
LATE_PAYMENT_RECONCILE_HOURS=72
LATE_PAYMENT_RECONCILE_BATCH=100
# Optional mainnet-only accounting export. Configure URL and token together in the protected live
# environment only after the sink's Idempotency-Key contract and dead-letter monitoring are ready.
# FINANCIAL_EVENT_SINK_URL=https://ledger.such.software/v1/events
# FINANCIAL_EVENT_SINK_TOKEN=CHANGE_ME_STRONG_ACCOUNTING_SINK_TOKEN
FINANCIAL_EVENT_ACCOUNT_REF=wowngeon:wow-receipts
FINANCIAL_EVENT_POLL_MS=60000
FINANCIAL_EVENT_BATCH_SIZE=20
FINANCIAL_EVENT_MAX_ATTEMPTS=8
PRIMARY_WALLET_ENDPOINT=http://127.0.0.1:34570
WALLET_RPC_USER=wownerogue
WALLET_RPC_PASSWORD=CHANGE_ME_STRONG_RPC_PASSWORD
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; a node
# reachable over a separate path, a home node across the mesh, or a public/community node, is
# what actually adds availability.
#
# 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. A wallet outage therefore declines paid intake
# while credits and free play keep working.
RPC_POLL_INTERVAL=2000
DIFFICULTY_PRESET=normal
EARLY_ENTRY_ENABLED=true
EARLY_ENTRY_FREE_MODE=true
EARLY_ENTRY_CREDITS_MODE=true
SOLO_ENABLED=true
TAVERN_ENABLED=true
TAVERN_TICK_MS=100
MATCH_ENABLED=true
MATCH_RULESET_ID=race
MATCH_MAX_PLAYERS=4
MATCH_PAID_ENTROPY_DELAY_BLOCKS=2
MATCH_PAID_ENTROPY_CONFIRMATIONS=2
MATCH_TICK_MS=250
MATCH_MIN_DURATION_MS=20000
MATCH_HARD_CEILING_MS=240000
MATCH_CREDITS_COST=1
MATCH_CRYPTO_RACE_ENABLED=false
MATCH_PAYOUTS_ENABLED=false