Skip to content

Commit febd82a

Browse files
georgeglarsonclaude
andcommitted
Revamp aggro system and fix coordinate system confusion
Replace ad-hoc safe zone patches with zone-aware AggroPolicy module that handles aggro decisions through zone passivity, transition gradients, level scaling, and density capping. Fix pervasive coordinate confusion where entity tile positions were incorrectly multiplied/divided by 16 (treating them as pixels), causing inflated aggro ranges, broken melee checks, and inconsistent leash distances. Key changes: - Add aggro-policy.ts: pure function module for zone-aware aggro - Add combat-constants.ts: shared MELEE_RANGE, leash distance helpers - Fix 9 incorrect * 16 / / 16 conversions across 7 server files - Unify two leash systems (move_callback + aggro tick) via getLeashDistance() - Fix mob chase: moveEntity → mob.move() to broadcast movement to clients - Fix stuck mob state: HURT handler skips damage on range fail without clearing aggro (prevents chooseMobTarget from being permanently blocked) - Aggro tick re-broadcasts attack when mob is adjacent to maintain combat loop - Reduce rat density in starting areas (23→19 total) - 42 test files, 2224 tests, 0 failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fb258b8 commit febd82a

84 files changed

Lines changed: 23588 additions & 8290 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [20.x, 22.x]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Install pnpm
21+
uses: pnpm/action-setup@v4
22+
with:
23+
version: 9
24+
25+
- name: Use Node.js ${{ matrix.node-version }}
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: ${{ matrix.node-version }}
29+
cache: pnpm
30+
31+
- name: Install dependencies
32+
run: pnpm install --frozen-lockfile
33+
34+
- name: Build server
35+
run: pnpm run build:server
36+
37+
- name: Build client
38+
run: pnpm run build:client
39+
40+
- name: Run tests
41+
run: pnpm test
42+
43+
- name: Run tests with coverage
44+
if: matrix.node-version == '22.x'
45+
run: pnpm test:coverage
46+
47+
lint:
48+
runs-on: ubuntu-latest
49+
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
- name: Install pnpm
54+
uses: pnpm/action-setup@v4
55+
with:
56+
version: 9
57+
58+
- name: Use Node.js 22.x
59+
uses: actions/setup-node@v4
60+
with:
61+
node-version: 22.x
62+
cache: pnpm
63+
64+
- name: Install dependencies
65+
run: pnpm install --frozen-lockfile
66+
67+
- name: Type check server
68+
run: pnpm run build:server

README.md

Lines changed: 132 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,150 @@
1-
Fracture
2-
========
1+
# Fracture
32

4-
A modern HTML5/TypeScript multiplayer RPG with AI-powered NPCs.
3+
A multiplayer action RPG built with TypeScript, HTML5 Canvas, and AI-powered NPCs. Play it live at **[fracture.georgelarson.me](https://fracture.georgelarson.me)**.
54

6-
Features
7-
--------
5+
Originally forked from BrowserQuest (Little Workshop, 2012) and its TypeScript port, Fracture has been rebuilt from the ground up into a modern, fully-tested multiplayer RPG with AI integration, endgame systems, and production-grade architecture.
86

9-
- **AI-Powered NPCs**: Dynamic dialogue, quests, and companions powered by Venice AI
10-
- **Real-time Multiplayer**: WebSocket-based gameplay with Socket.IO
11-
- **Modern Architecture**: TypeScript with Single Responsibility Principle design
12-
- **Progression System**: XP, levels, achievements, and daily rewards
13-
- **Economy**: Gold, shops, and item trading
7+
## Architecture
148

15-
Tech Stack
16-
----------
9+
```
10+
┌─────────────────────────────────────────────────────────┐
11+
│ Client (25k LOC TypeScript) │
12+
│ HTML5 Canvas renderer, input handling, UI controllers │
13+
│ Webpack build, sprite animation system │
14+
├─────────────────────────────────────────────────────────┤
15+
│ Socket.IO (WebSocket transport) │
16+
├─────────────────────────────────────────────────────────┤
17+
│ Server (21k LOC TypeScript) │
18+
│ ┌──────────┬──────────┬──────────┬──────────────────┐ │
19+
│ │ Combat │ Rifts │ Party │ Progression │ │
20+
│ │ System │ Manager │ Service │ Service │ │
21+
│ ├──────────┼──────────┼──────────┼──────────────────┤ │
22+
│ │ Entity │ Zone │ Shop │ Achievement │ │
23+
│ │ Manager │ Manager │ Service │ Service │ │
24+
│ ├──────────┴──────────┴──────────┴──────────────────┤ │
25+
│ │ Storage Layer (better-sqlite3) │ │
26+
│ ├───────────────────────────────────────────────────┤ │
27+
│ │ Venice AI SDK (llama-3.3-70b) + Fish Audio TTS │ │
28+
│ └───────────────────────────────────────────────────┘ │
29+
├─────────────────────────────────────────────────────────┤
30+
│ Shared (4k LOC TypeScript) │
31+
│ Game types, equipment stats, zone definitions, │
32+
│ event bus, achievement definitions, skill data │
33+
└─────────────────────────────────────────────────────────┘
34+
```
1735

18-
- **Client**: TypeScript, Webpack, HTML5 Canvas
19-
- **Server**: Node.js, TypeScript, Socket.IO
20-
- **AI**: Venice AI SDK for NPC intelligence
36+
## Game Systems
2137

22-
Getting Started
23-
---------------
38+
**Combat** -- Real-time melee combat with Chebyshev distance calculations, mob aggro/hate tracking, critical hits, and equipment set bonuses. Mobs use a hate-ranked targeting system with stun and phase immunity mechanics.
2439

25-
```bash
26-
# Install dependencies
27-
pnpm install
40+
**Fracture Rifts** -- Endgame challenge mode with procedurally modified dungeon floors. Modifiers stack multiplicatively on mob stats and player abilities. Floor progression, reward scaling, and persistent leaderboards.
41+
42+
**Nemesis System** -- Mobs that kill players power up and become named nemeses. Revenge kills grant multiplied rewards. Nemesis data persists across sessions.
2843

29-
# Build client and server
30-
pnpm run build:client
31-
pnpm run build:server
44+
**Progression** -- Tiered exponential XP curve across 50 levels with 4 difficulty tiers. Ascension system resets level for permanent stat bonuses. Session efficiency tracking with diminishing returns and rested XP accumulation.
3245

33-
# Start the server
34-
pnpm start
46+
**AI NPCs** -- Venice AI SDK integration for dynamic NPC dialogue, quest generation, and world narration. Fish Audio TTS for voice synthesis. Companion system with personality-driven responses.
47+
48+
**Party System** -- Real-time party formation with invite/accept/decline/kick/leave. Shared XP with proximity-based distribution and party size bonuses. Position and HP tracking across party members.
49+
50+
**Economy** -- Per-NPC shop inventories with limited stock tracking. Tiered item generation with rarity rolls, bonus properties, and zone-specific drop modifiers. Equipment comparison and set collection.
51+
52+
## Test Suite
53+
54+
```
55+
40 test files | 2,140 tests | 0 failures
3556
```
3657

37-
Documentation
38-
-------------
58+
Coverage by server module:
59+
60+
| Module | Statements | Branches | Functions |
61+
|--------|-----------|----------|-----------|
62+
| Combat | 91% | 78% | 94% |
63+
| Rifts | 98% | 93% | 100% |
64+
| Party | 100% | 96% | 100% |
65+
| Shop | 100% | 100% | 100% |
66+
| Storage | 82% | 88% | 92% |
67+
| Zones | 100% | 100% | 100% |
68+
| Events | 100% | 100% | 100% |
69+
| Player Handlers | 71% | 68% | 61% |
70+
| Items | 64% | 63% | 54% |
71+
| Utils | 88% | 75% | 50% |
72+
73+
Tests are written in Vitest with v8 coverage. Storage tests use in-memory SQLite for real SQL execution without filesystem access.
74+
75+
## Tech Stack
76+
77+
| Layer | Technology |
78+
|-------|-----------|
79+
| Language | TypeScript 5.8 |
80+
| Client | HTML5 Canvas, Webpack 5, jQuery |
81+
| Server | Node.js, Express, Socket.IO 4 |
82+
| Database | better-sqlite3 |
83+
| AI | Venice AI SDK, Fish Audio TTS |
84+
| Testing | Vitest 4, v8 coverage |
85+
| CI | GitHub Actions (Node 20.x, 22.x) |
86+
87+
## Development
3988

40-
Documentation is located in client and server directories.
89+
```bash
90+
pnpm install
91+
pnpm run dev # concurrent client + server watch mode
92+
pnpm test # run test suite
93+
pnpm test:coverage # run with coverage report
94+
pnpm test:watch # watch mode
95+
```
4196

42-
License
43-
-------
97+
### Build & Deploy
4498

45-
Code is licensed under MPL 2.0. Content is licensed under CC-BY-SA 3.0.
46-
See the LICENSE file for details.
99+
```bash
100+
pnpm run build:client # webpack production build
101+
pnpm run build:server # tsc compilation
102+
pnpm start # start server on port 8000
103+
```
104+
105+
### Project Structure
106+
107+
```
108+
server/ts/
109+
combat/ # CombatSystem, CombatTracker, KillStreak, Nemesis
110+
entities/ # EntityManager (lifecycle, spatial groups)
111+
equipment/ # EquipmentManager (slots, set bonuses, stats)
112+
inventory/ # Inventory (20-slot, stacking, serialization)
113+
items/ # ItemGenerator (rarity, bonuses, loot tables)
114+
party/ # PartyService (invite/accept/leave/kick, XP sharing)
115+
player/ # Handler modules (achievement, equipment, inventory,
116+
# party, persistence, progression, rift, shop, skill,
117+
# venice, zone) + MessageRouter
118+
rifts/ # RiftManager (floors, modifiers, leaderboards)
119+
shop/ # ShopService (NPC inventories, pricing, stock)
120+
storage/ # SQLite persistence (characters, inventory, achievements)
121+
zones/ # ZoneManager (boundaries, level warnings, bonuses)
122+
ai/ # Venice AI integration (NPC dialogue, quests, narration)
123+
124+
client/ts/
125+
controllers/ # AchievementController, ProgressionController
126+
entity/ # Entity hierarchy (Character > Player/Mob/NPC)
127+
handlers/ # Server message handlers (combat, inventory, party, etc.)
128+
network/ # GameClient (Socket.IO), message dispatch
129+
player/ # MovementController, CombatController
130+
quest/ # QuestController
131+
ui/ # Achievement UI, context menus, player inspect
132+
133+
shared/ts/
134+
events/ # EventBus (typed pub/sub, singleton factories)
135+
equipment/ # Equipment stat definitions
136+
zones/ # Zone boundary and bonus data
137+
skills/ # Skill definitions and cooldowns
138+
achievements.ts # Achievement definitions and progress tracking
139+
gametypes.ts # Entity types, message types, constants
140+
```
47141

48-
Credits
49-
-------
142+
## Credits
50143

51-
Original game created by [Little Workshop](http://www.littleworkshop.fr):
52-
* Franck Lecollinet - [@whatthefranck](http://twitter.com/whatthefranck)
53-
* Guillaume Lecollinet - [@glecollinet](http://twitter.com/glecollinet)
144+
Original game by [Little Workshop](http://www.littleworkshop.fr) (Franck & Guillaume Lecollinet).
145+
TypeScript port by [Matthew Javelet](https://github.com/0xMatt).
146+
Modernized and expanded by [George Larson](https://georgelarson.me).
54147

55-
TypeScript port by [Matthew Javelet](https://github.com/0xMatt)
148+
## License
56149

57-
Modernized by [George Larson](https://georgelarson.me)
150+
Code is licensed under MPL 2.0. Content is licensed under CC-BY-SA 3.0. See [LICENSE](LICENSE) for details.

build-check.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
2-
cd /root/BrowserQuest-Ultra
2+
cd "$(dirname "$0")"
33
echo "=== SERVER BUILD ==="
4-
./node_modules/.bin/tsc -p ./server 2>&1 || echo "Server build failed"
4+
npx tsc -p ./server 2>&1 || echo "Server build failed"
55
echo ""
66
echo "=== CLIENT BUILD ==="
7-
./node_modules/.bin/webpack --config webpack.config.js 2>&1 | head -50 || echo "Client build failed"
7+
npx webpack --config webpack.config.js 2>&1 | head -50 || echo "Client build failed"

client/config/config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"host": "bq.venice.guru",
3-
"port": 443
2+
"host": "localhost",
3+
"port": 8000
44
}

client/config/config.prod.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"host": "pq.venice.guru",
2+
"host": "fracture.georgelarson.me",
33
"port": 443
4-
}
4+
}

client/ts/animation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ export class Animation {
1818
this.width = width;
1919
this.height = height;
2020
this.reset();
21-
// hi
2221
}
2322

2423
tick() {

client/ts/assets/sprite-loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class SpriteLoader {
106106
*/
107107
initHurtSprites(): void {
108108
const sprites = this.sprites;
109-
Types.forEachArmorKind((kind, kindName) => {
109+
Types.forEachArmor((kind, kindName) => {
110110
if (sprites[kindName]) {
111111
sprites[kindName].createHurtSprite();
112112
}

client/ts/audio.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ export class AudioManager {
320320
}, { once: true });
321321

322322
this.npcVoiceAudio.load();
323-
console.log('[Audio] Playing NPC voice:', audioUrl);
323+
console.debug('[Audio] Playing NPC voice:', audioUrl);
324324
}
325325

326326
/**

0 commit comments

Comments
 (0)