This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Reldens is an MMORPG Platform (v4.0.0-beta.39) built on Node.js, designed for developers to create multiplayer games. The platform integrates:
- Server: Colyseus 0.16 for multiplayer game server
- Client: Phaser 3 for game engine, Parcel for bundling
- Database: Supports multiple storage drivers (objection-js, mikro-orm, prisma)
- Architecture: Client-server with authoritative server, real-time synchronization via WebSockets
Node Version: >= 20.0.0
- @reldens/utils - Core utilities, Shortcuts class (imported as
sc), EventsManagerSingleton, Logger - @reldens/server-utils - Server utilities, FileHandler, configuration helpers
- @reldens/storage - Multi-ORM database layer (ObjectionJS, MikroORM, Prisma)
- @reldens/cms - Content management system and admin panel
- @reldens/items-system - Items and inventory system
- @reldens/modifiers - Stats and modifiers system
- @reldens/skills - Skills and abilities system
# Testing
npm test
node tests/manager.js --filter="test-name" --break-on-error
# Building
reldens buildSkeleton # Build both styles and client
reldens fullRebuild # Complete rebuild from scratch
# Database
reldens generateEntities [--override] # Generate entities from database schema
# User management
reldens createAdmin --user=username --pass=password --email=email@example.com
reldens resetPassword --user=username --pass=newpasswordFull command reference: See .claude/commands-reference.md
The codebase follows a client/server split architecture within each feature module:
lib/
├── {feature}/
│ ├── client/ # Client-side code (Phaser, UI, rendering)
│ ├── server/ # Server-side code (Colyseus rooms, logic)
│ ├── constants.js # Shared constants
│ └── schemas/ # Colyseus state schemas (if applicable)
- Server:
server.js→lib/game/server/manager.js(ServerManager) - Client:
client.js→lib/game/client/game-manager.js(GameManager) - Theme:
theme/default/index.jsinitializes client with custom plugins
The platform includes 23 feature modules: Game, Rooms, World, Config, Features, Actions, Inventory, Respawn, Rewards, Scores, Teams, Users, Chat, Audio, Prediction, Admin, Firebase, Ads, Import, Objects, Snippets, Bundlers.
Detailed list: See .claude/feature-modules.md
Reldens uses a database-driven configuration with runtime overrides:
- Database Config (
configtable): Path-based keys, scoped byscopefield - Environment Variables (
.env): PrefixRELDENS_*for all settings - Custom Classes: Passed via
customClassesto override defaults
Key Environment Variables:
RELDENS_STORAGE_DRIVER- Storage driver (objection-js, mikro-orm, prisma)RELDENS_DB_HOST,RELDENS_DB_PORT,RELDENS_DB_NAME,RELDENS_DB_USER,RELDENS_DB_PASSWORDRELDENS_HOT_PLUG- Enable hot-plug configuration updates (0/1)
Full environment variables list: See .claude/environment-variables.md
The platform uses @reldens/utils EventsManagerSingleton for extensibility:
Common Event Patterns:
reldens.{action}Before- Hook before operationreldens.{action}After- Hook after operation- Events are synchronous (
emitSync) or async (emit)
Key Events:
reldens.serverConfigFeaturesReady- Features loadedreldens.beforeJoinGame- Before player joinsreldens.startGameAfter- Game initializedreldens.roomLoginOnAuth- Custom authentication logic
Plugin Pattern:
class ServerPlugin {
setup({events}) {
events.on('reldens.serverConfigFeaturesReady', (props) => {
// Custom logic here
});
}
}dataServer.getEntity() returns a BaseDriver instance from @reldens/storage, NOT an Entity or Model class.
// Correct - returns BaseDriver
let statsRepository = this.dataServer.getEntity('stats');
// BaseDriver provides unified interface:
await statsRepository.create({key: 'hp', label: 'Health Points'});
await statsRepository.loadAll();
await statsRepository.loadOneBy('key', 'hp');
await statsRepository.updateById(1, {label: 'HP'});Type Annotation:
/** @type {import('@reldens/storage').BaseDriver} */
this.statsRepository = this.dataServer.getEntity('stats');Storage Drivers:
prisma(current default): Modern ORM with type safety, custom validationobjection-js: Uses Knex.js, direct SQL, no validationmikro-orm: ORM with decorators, supports MongoDB
Detailed architecture: See .claude/storage-architecture.md
Entity list: See .claude/entities-reference.md
Theme Structure (theme/):
plugins/- Custom client/server plugins for game-specific logicdefault/- Default theme assets (HTML, CSS, sprites, audio)admin/- Admin panel customizations
Theme Management:
ThemeManager (lib/game/server/theme-manager.js) handles asset copying, bundling, and CSS compilation.
CRITICAL: Always use themeManager.createClientBundle() instead of calling buildClient() or buildCss() directly:
- createClientBundle() - Wrapper that checks
RELDENS_ALLOW_RUN_BUNDLERenvironment variable (used during server startup) - buildClient() - Direct method that checks
RELDENS_ALLOW_BUILD_CLIENTenvironment variable - buildCss() - Direct method that checks
RELDENS_ALLOW_BUILD_CSSenvironment variable
Environment Variables:
RELDENS_ALLOW_RUN_BUNDLER- ControlscreateClientBundle()execution (default: 0)RELDENS_ALLOW_BUILD_CLIENT- ControlsbuildClient()execution (default: 1)RELDENS_ALLOW_BUILD_CSS- ControlsbuildCss()execution (default: 1)
Why this matters: Production servers can regenerate clients and run Parcel builds for hot-reloading. These environment variables allow you to control when bundling happens, preventing unexpected builds during startup or deployment.
CRITICAL TIMING ISSUE: Colyseus 0.16 state synchronization is asynchronous.
listenMessages(room, gameManager) {
if(!room.state || !room.state.bodies){
return false; // ❌ WRONG - callbacks never set up!
}
this.setAddBodyCallback(room, gameManager);
}listenMessages(room, gameManager) {
if(!room.state || !room.state.bodies){
room.onStateChange.once((state) => {
this.setAddBodyCallback(room, gameManager); // ✅ Wait for state
});
return false;
}
this.setAddBodyCallback(room, gameManager);
}Alternative - Use Reactive Patterns:
activateRoom(room) {
this.playersManager = RoomStateEntitiesManager.onEntityAdd(
room,
'players',
(player, key) => {
this.handlePlayerAdded(player, key);
}
);
}CRITICAL: Colyseus auto-cleans all listeners. Never store manager references or add manual disposal code unless explicitly needed.
onCreate(options): Initialize world, physics, objects- Player joins →
onJoin(client, options) - Message handling →
onMessage(client, message) - Player leaves →
onLeave(client, consented) - Room disposal →
onDispose()
- Create feature module in
lib/{feature-name}/ - Add database table in
migrations/ - Create client/server subdirectories
- Add feature entry to
featurestable - Register in
lib/features/server/config-server.js - Implement
setup()method to hook events
- Combat/Skills: Edit
lib/actions/server/battle.jsorpve.js - Player Stats: Configure via database
statstable - Room Behavior: Extend
RoomSceneor hookreldens.createRoomAfterevent - Client Rendering: Modify Phaser scenes in
lib/game/client/scene-*.js
- Always use entity models via
dataServer.getEntity(), never raw SQL - Generated entities are read-only; extend in
server/models/ - Use migrations for schema changes
- Regenerate entities after schema changes:
reldens generateEntities --override
- Authoritative Server: All game logic runs on server; client is display-only
- Hot Plug: Admin panel changes reload without restart if
RELDENS_HOT_PLUG=1 - Logging: Use
@reldens/utils/Logger(configurable viaRELDENS_LOG_LEVEL) - File Operations: Always use
@reldens/server-utils FileHandler(never Node.jsfs) - Shortcuts Class: Import as
scfrom@reldens/utils- providessc.get,sc.hasOwn,sc.isArray, etc. - Colyseus 0.16: All client callbacks use
StateCallbacksManagerandRoomStateEntitiesManager - Buffer Polyfill: Required for Parcel bundling with Colyseus 0.16
When working on code issues:
- Always investigate thoroughly before making changes
- Read related files completely before proposing solutions
- Trace execution flows and dependencies
- Provide proof for issues, never guess or assume
- Verify file contents before creating patches
- A variable with an unexpected value is not an issue, it is the result of a previous issue
- Discord: https://discord.gg/HuJMxUY
- Demo: https://dev.reldens.com/
- Documentation: https://www.reldens.com/documentation/installation
- Issues: https://github.com/damian-pastorini/reldens/issues
- Contact: info@dwdeveloper.com
- Commands:
.claude/commands-reference.md- All CLI commands - Environment Variables:
.claude/environment-variables.md- All RELDENS_* variables - Feature Modules:
.claude/feature-modules.md- All 23 feature modules - Storage Architecture:
.claude/storage-architecture.md- Entity management deep dive - Entities:
.claude/entities-reference.md- All 60+ entity types - Installer:
.claude/installer-guide.md- Web-based installation wizard guide