IdleRPG-style IRC game platform with two runtime surfaces:
- A Node.js bot (
src/) that owns gameplay, timers, penalties, and state updates. - A PHP dashboard/API (
public/) that reads the same SQLite file for leaderboard and live views.
The web stack is read-only against game state. The bot is authoritative.
| Live demo | idlerpg.netirc.eu |
| Concept | IdleRPG |
| Related implementations | falsovsky/idlerpg, idlerpg-site-ng |
Additional docs: DEPLOY.md, SECURITY.md, LICENSE
- Architecture
- Requirements
- Quick start
- Configuration guide
- Operations and verification
- Gameplay reference
- IRC command reference
- HTTP API reference
- Web/SEO/PWA notes
- Development
- Optional components
- Troubleshooting checklist
- License
| Layer | Responsibility |
|---|---|
src/ IRC bot |
Gameplay engine, session handling, level ticks, penalties, events, optional V3 systems, chronicle writes. |
public/ PHP UI |
Leaderboard, player details, realm chronicle feed, guild standings, season standings, rules pages, PWA shell. |
public/api/*.php |
Read-only JSON endpoints for health, leaderboard, player detail, chronicle feed. |
| SQLite DB | Shared source of truth. Bot writes state; website reads state. |
Important: bot and site must point to the same database file path.
| Component | Required version / note |
|---|---|
| Node.js | 20+ |
| npm | bundled with Node.js |
| PHP | 8+ |
| PHP extensions | pdo, pdo_sqlite |
| HTTP server | Apache (recommended) or Nginx equivalent config |
Apache notes:
- VirtualHost
DocumentRootshould targetpublic/. - Enable
AllowOverridesopublic/.htaccesscan apply rewrite/security headers. - Enable
mod_rewriteandmod_headers.
git clone https://github.com/NetIRC/idlerpg.git
cd idlerpgnpm install
cp .env.example .env
npm startEdit .env before first production run:
- IRC connection values
IRPG_DB_PATH- channel and policy settings
- optional V3 and AI settings
cp site.config.php.example site.config.phpEdit site.config.php:
db_path: must matchIRPG_DB_PATHcase_sensitive_names: must matchIRPG_CASE_SENSITIVE_NAMESdebug:falsein production
If site.config.php is stored outside project root, copy
public/includes/local-root.php.example to public/includes/local-root.php
and return the path that contains site.config.php.
chmod +x scripts/idlerpg.sh
chmod +x scripts/idlerpg-watchdog.sh
./scripts/idlerpg.sh start
./scripts/idlerpg.sh stop
./scripts/idlerpg.sh restart
./scripts/idlerpg.sh start -f
./scripts/idlerpg.sh watch
./scripts/idlerpg.sh start --watch
./scripts/idlerpg-watchdog.shSet-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\scripts\idlerpg-watchdog.ps1| Concern | Location |
|---|---|
| Bot runtime, gameplay, V3 toggles, IRC, rate limits | .env (from .env.example) |
| Web runtime values | site.config.php (from site.config.php.example) |
| Build/release version branding | src/config.ts (IDLE_RPG_VERSION) and package.json |
- Bot DB path and web DB path must be identical.
- Name case sensitivity must match in bot and web.
- Keep V3 feature flags (
IRPG_V3_*) aligned between bot and web runtime environments. - If you run multiple shards/environments, isolate each DB path.
Use IRPG_AI_* in .env.
Keep API keys only in local secrets (.env is gitignored).
Never commit real keys.
- Keep SQLite database outside web document root.
- Use HTTPS in production.
- Set
debugtofalsein production web config. - Treat admin identity config as privileged access.
After deploy/startup, verify:
| Check | Expected result |
|---|---|
GET /api/health.php |
JSON includes "ok": true |
GET /api/leaderboard.php |
JSON includes leaderboard rows and realm/season previews |
GET /api/player.php?name=<hero> |
JSON includes hero detail, medals, and recent activity |
GET /api/chronicle.php |
JSON includes events array |
Runtime notes:
- Bot heartbeat controls whether web shows online/offline state.
- Timers do not progress while bot is offline/disconnected.
| Topic | Behavior |
|---|---|
| Main goal | Gain levels by idling while logged in and present in game channel. |
| Timer model | next_seconds counts down while eligible. |
| Speaking in channel | Adds penalty based on level and message characteristics. |
Recognized !commands |
No speech penalty if command is valid. |
Unrecognized !something |
Treated as normal speech and can be penalized. |
| Login requirement | Register/login via PM while your nick is in game channel. |
| PART while logged in | Session is suspended; resume on rejoin. |
| QUIT while logged in | Session usually closed with quit penalty (netsplit grace optional). |
| Not in channel | No idle progression. |
| Bot offline | No idle progression. |
Defaults reflect current code paths in src/game/* and config defaults in src/config.ts.
| System | Default behavior (high level) |
|---|---|
| Hand of God | Random timer swing event; chance increases during lucky hour. |
| Omen | Personal cooldown action with neutral/boon/curse/rare branches. |
| Duel | PvP action with level-gap limit, cooldowns, and timer swing outcomes. |
| Gauntlet | PvE trial with cooldown, risk/reward timer outcomes, possible epic branch. |
| Daily trial (V3) | Timed challenge with bounded reward/penalty. |
| Idle streak (V3) | Periodic timer reductions for uninterrupted idle presence. |
| Bounty board (V3) | Daily progress objective with one timer reward on completion. |
| Season pass (V3) | Separate seasonal progression with no base hero reset. |
| World boss (V3) | Cooperative passive-damage event with shared rewards. |
| Guilds/relics (V3) | Social bonus and one active relic perk. |
If README text and runtime differ, runtime is authoritative.
!prestige has two modes:
!prestige: shows your current prestige rank, idle bonus, and required level for rebirth.!prestige now: performs rebirth only if your level is at leastIRPG_V3_PRESTIGE_MIN_LEVEL(default60).
When rebirth succeeds, current code does this:
- sets hero level to
0 - resets level timer to base (
rpbase) - increases
prestige_rankby1 - increments prestige points
- resets idle streak seconds
- keeps your account/hero identity and grants permanent idle-rate bonus from rank
This is intentional "reset progress now, gain permanent meta-speed later" behavior.
General command notes:
- Commands are case-insensitive on command token (
!HELP,!helpboth valid). - Channel command syntax uses
!. - PM command syntax uses plain words without
!.
| Command | Args | Description |
|---|---|---|
!help |
- | Short help. |
!cmds / !commands |
- | Extended public command list. |
!rules |
- | One-line rules summary. |
!ping |
- | Bot liveness/version ping. |
!top |
- | Top 3 heroes snapshot. |
!stats |
[name] |
Hero profile summary. |
!time |
[name] |
Time to next level. |
!whoami |
- | Identity plus cooldown summary. |
!records |
- | Realm highs/records. |
!quest |
- | Quest status. |
!bounty |
- | V3 daily contract status. |
!season |
- | Season label, XP/tier, time left. |
!boss |
- | World boss active/next status. |
!guild |
status/create/join/leave ... |
Guild operations. |
!relic |
status/list/equip <key> |
Relic operations. |
!prestige |
[now] |
Prestige status or rebirth action. |
!realm / !pulse |
- | Realm pulse line. |
!chronicle |
- | Recent realm events summary line. |
!omen |
- | Personal omen action (cooldown). |
!duel |
<irc_nick> |
PvP duel action. |
!gauntlet |
- | PvE gauntlet action. |
!lore |
[topic] |
Optional AI flavor text. |
!medals / !badges |
[name] |
Medal rack summary. |
PM commands map to channel equivalents plus account/admin actions:
| PM Command | Args | Description |
|---|---|---|
HELP / CMDS |
- | PM help pages. |
REGISTER |
Name Password Class... |
Create hero/account. |
LOGIN |
Name Password |
Open game session. |
LOGOUT |
- | Close session with logout penalty. |
PING |
- | Liveness/version ping. |
STATS, TOP, WHOAMI, TIME, RECORDS, QUEST |
optional args | Same purpose as channel forms. |
BOUNTY, SEASON, BOSS, GUILD, RELIC, PRESTIGE |
optional args | Same purpose as channel forms. |
REALM / PULSE |
- | Same as !realm. |
CHRONICLE |
- | Same as !chronicle. |
OMEN, DUEL, GAUNTLET |
optional args | Same gameplay checks as channel forms. |
LORE |
[topic] |
Same as !lore. |
MEDALS / BADGES |
[name] |
Same as !medals. |
ADMIN |
subcommand |
Admin-only control commands. |
Eligibility is controlled by configured admin nicks and/or admin player identity.
By default, admin PM commands also require your nick to be present in the game channel (IRPG_ADMIN_REQUIRE_IN_CHANNEL=true).
Use ADMIN HELP in PM.
| Subcommand | Syntax | Effect |
|---|---|---|
FORCELOGOUT |
ADMIN FORCELOGOUT <CharacterName> |
Clears active session for that hero. |
DELETEUSER / DELETE |
ADMIN DELETEUSER <CharacterName> |
Permanent hero deletion and related cleanup. |
RESETPASS / SETPASS |
ADMIN RESETPASS <CharacterName> <newpassword> |
Set new password and clear session. |
STARTQUEST |
ADMIN STARTQUEST |
Force start quest (subject to runtime checks). |
LUCKY |
ADMIN LUCKY |
Force lucky-hour style broadcast. |
SAY |
ADMIN SAY <text...> |
Send bot message to game channel. |
SHUTDOWN |
ADMIN SHUTDOWN [note...] |
Broadcast/log shutdown and exit bot process. |
RESTART |
ADMIN RESTART [note...] |
Broadcast/log restart and exit bot process (for supervisor auto-restart). |
Treat admin credentials as root-equivalent access.
All API responses are JSON.
| Endpoint | Purpose | Notes |
|---|---|---|
/api/health.php |
Service health check | Includes "ok": true when healthy. |
/api/leaderboard.php |
Public leaderboard + realm/season slices | Used by web home dashboard. |
/api/player.php?name=... |
Hero detail lookup | Returns hero profile by character name. |
/api/chronicle.php |
Realm event feed | Supports filters such as limit, kind, search, since, until. |
/api/php-diag.php |
PHP runtime diagnostics | Local-only by default; non-local access requires explicit IRPG_PHP_DIAG_ENABLED=true. |
Public robots.txt blocks indexing of /api/ and API endpoints emit noindex headers.
A hardened read-only operations panel is available at /admin/index.php.
Security controls implemented:
- explicit enable flag in
site.config.php(admin_panel.enabled) - password hash verification (
password_hash/password_verify) - optional TOTP second factor (
totp_enabled,totp_secret_base32) - strict session cookie flags + session rotation + idle TTL
- CSRF token validation on authenticated state-changing posts (logout/password rotation/TOTP settings/backup download)
- login attempt rate limiting by source IP
- IP allowlist with exact IP or CIDR (
ip_allowlist) - optional HTTPS enforcement (
require_https) - no-store cache headers + CSP + frame denial + noindex
- in-panel password rotation form (current password + confirmation + secure hash rewrite)
- password rotation rewrite is regex-safe for bcrypt hashes and invalidates PHP opcache for immediate effect
- DB health diagnostics (integrity check, DB/WAL sizes, free-page ratio, maintenance recommendation)
- authenticated backup download (CSRF-protected snapshot stream)
- in-panel TOTP management (enable/disable, issuer/secret update, optional secret regeneration)
Regenerate secret automaticallyrotates TOTP secret even when TOTP is currently disabled- deterministic PRG feedback for login/TOTP/password/session/CSRF outcomes (banner + inline field hints)
Example site.config.php block:
'admin_panel' => [
'enabled' => true,
'password_hash' => '$2y$10$replace_with_password_hash',
'totp_enabled' => true,
'totp_secret_base32' => 'BASE32SECRET',
'totp_issuer' => 'IdleRPG Admin',
'ip_allowlist' => ['127.0.0.1', '::1', '10.0.0.0/24'],
'require_https' => true,
'session_ttl_sec' => 1800,
],Generate a password hash:
php -r "echo password_hash('StrongPassHere', PASSWORD_DEFAULT), PHP_EOL;"The web layer includes:
- canonical/social tags and JSON-LD metadata
- landing pages (
how-to-play,commands,faq) - XML sitemap endpoint
- web app manifest + service worker + offline fallback
Post-deploy checklist:
- Set
IRPG_PUBLIC_URLto final HTTPS domain. - Validate
/sitemap.php. - Submit sitemap to search consoles.
- Request indexing for main/editorial pages.
npm run dev:botWindows production-friendly watchdog (auto-restart on crash or ADMIN RESTART):
npm run start:watchdogLinux/macOS watchdog options:
chmod +x scripts/idlerpg-watchdog.sh
./scripts/idlerpg-watchdog.sh # foreground watchdog
./scripts/idlerpg.sh start --watch # background watchdog
./scripts/idlerpg.sh stopBehavior:
- exit code
0(used byADMIN SHUTDOWN) stops the watchdog - non-zero exit codes (including
ADMIN RESTART) trigger automatic restart
Useful principles during development:
- gameplay state is persisted in SQLite
- if bot is disconnected, time does not advance
- for balancing, inspect
src/game/*andsrc/config.ts
| Path / command | Purpose |
|---|---|
web/ |
React + Vite sandbox front-end for local experiments. |
npm run api |
Optional Express API for local development workflows. |
Production can run entirely on public/api/*.php plus bot process.
If something looks wrong, check in this order:
- Bot process is running and connected to IRC.
- Bot and web point to the exact same SQLite file path.
- PHP has
pdo_sqliteenabled and DB file permissions are valid. - Hero is logged in and currently present in game channel.
site.config.phpand.envcase-sensitivity settings match.- For prestige confusion: confirm
IRPG_V3_PRESTIGE_MIN_LEVELand use!prestigeto inspect current threshold.
For deployment/server-specific deep troubleshooting, use DEPLOY.md.
MIT. Original IdleRPG concept: idlerpg.net.