

Private Server
AQW, rebuilt from scratch.
TypeScript + Node.js. Real SFS2X over raw TCP. No Java, no Rhino, no running decompiled AS3 through a 2008 runtime. Just the actual game database and a combat engine that doesn't cheat.
Why
A few reasons.
Artix killed the Flash client.
Moved to Unity in 2021. The new version exists and that's about the nicest thing I'll say about it. The Flash version had a specific pacing and feel that just isn't there anymore. Wanted to keep it alive somewhere that isn't a Wayback Machine screenshot.
I wanted to know how it actually worked.
SFS2X is a binary TCP protocol with XML frames. Figuring that out from Wireshark captures and a decompiled SWF took a while. Worth it. Turns out MMO servers are less magical than they look from the outside.
The existing options are bad.
Closed source, running AS3 through Rhino in Java, or dead since 2015. None of those are things I'd want to build on. Needed something modern and readable. So I built it.
How It Works
TCP handshake to combat tick.
Click a step.
Development Progress
What's done, what's next.
Core Server
- SFS2X TCP frame parser (XML + binary)
- Login / token auth flow
- Zone + area join sequence
- Player state (HP, MP, level, gold)
- SQLite persistence with better-sqlite3
- HTTP admin API
Game Database
- 12,580+ items imported from WOH SQL dump
- 26 monsters with HP/stats
- 16 maps with cell layout
- 4 playable classes (Warrior, Mage, Rogue, Healer)
- Starter inventory seeded on first login
Combat Engine
- aggroMon / attack / useSkill handlers
- Damage scaling with player level
- Real skill multipliers from WOH reference (a1-a4)
- Server-side cooldown enforcement per skill
- addGoldExp and XP/level-up on kill
- Monster respawn (restoreMon)
- Attack rate limiting (500ms min gap)
Persistence + Polish
- Inventory equip / unequip
- Gold and item grant admin API
- Online player push (real-time balance updates)
- Curated achievement system
- One-time DB migration pattern (meta table)
- 34/34 integration tests passing
Multiplayer
- Room roster broadcast (other players visible)
- Party / group system
- Shared combat room state
- Chat (zone + whisper)
Content Expansion
- More maps and quest chains
- Quest item drop tracking
- Guild system
- Auction house / trading
- Web-based character viewer
Tech Stack
What it's built with, and why.
Every choice here was made for a reason. Probably a good one.
Protocol parsing is basically just structs and state machines. Types caught a lot of bugs before they turned into 3AM debugging sessions.
tsx runs TS directly. Zero build step. When you're decoding a protocol from hex dumps you really don't want to wait for a compiler.
Sync API. WAL mode. Singleton so I stop getting 'database is locked' at the worst possible time. It's been fine.
Had MySQL in the dump. Converted it. One file, no server, no setup. If SQLite is enough, use SQLite.
What Artix's servers ran. Reverse-engineered the frame format from Wireshark captures. 4-byte big-endian length header then XML. Annoyingly underdocumented.
No Jest, no Vitest. Node's built-in runner is fine. 34 tests that spin up real TCP servers against a real DB. If it passes, it works.
Static export to plain HTML/CSS/JS. Probably overkill for a docs site. Didn't care.
Sources
Where the data actually comes from.
This is reverse-engineering work. Nothing came from Artix Entertainment directly. All game data came from publicly available SQL dumps, decompiled client code, and protocol captures.
Database export from the Wrath of Heroes AQW private server. Item definitions, class skills with real damage multipliers, monster stats, map data. Ground truth for basically all game content here.
Original Flash client decompiled with JPEXS. Gives you the exact XT command names (aggroMon, attack, useSkill, ct, addGoldExp, die, restoreMon) and the XML framing. The client is effectively the spec.
Live traffic captures from the real Flash client against live and private servers. This is how the SFS2X frame format got confirmed: 4-byte big-endian length header, then XML payload. Without these you're just guessing.
Official SFS2X documentation for the room system and extension API. Useful as a baseline but doesn't cover what Artix actually changed. Cross-referenced constantly against the captures.
Item names, class descriptions, quest data. Mostly used to sanity-check the SQL dump and fill gaps where the data was ambiguous or just missing.