This document provides guidelines for developers and AI assistants working on the Kalaazu project. Adhering to these guidelines ensures a smooth and consistent development workflow.
Kalaazu is a private server for the game DarkOrbit. It is a multi-module Java project built with the Spring Boot framework.
The project is a monolith composed of several key modules:
Launcher: The main entry point of the application. It starts a JavaFX dashboard for server management and initializes all other modules.Server: Contains the core game server logic. It uses Netty for socket communication and an * Entity-Component-System (ECS)* architecture with Artemis-ODB. Key services includeMapService,GameLoopService, andChannelManager.Persistence: Manages database interaction using Spring JPA and Hibernate. It also contains the raw SQL files for the database schema.CMS: Contains a Vue.js frontend (src/main/www) and its corresponding Java API (src/main/java) for user-facing features like registration.Utils: A shared module for cross-cutting concerns and utility functions.
Modules communicate in a decoupled manner using the Spring Event Bus. For example, a UI action in the Launcher
module can publish an event (e.g., StartServer) that the Server module listens for to trigger an action. When
contributing, please follow this event-driven pattern.
- Event Publishing Example:
com.kalaazu.ui.presenter.MainLayoutpublishes acom.kalaazu.event.StartServerevent. - Event Handling Example: The
start(StartServer event)method incom.kalaazu.server.Serverlistens for this event.
To work on this project, you will need the following installed:
- JDK: Version 26 or higher.
- Gradle: Version 8.0 or higher.
- Database: MariaDB.
- Node.js: Required for frontend development (version is flexible).
The primary way to run the project for development is by executing the main class from your IDE:
- Main Class:
com.kalaazu.Launcher
This will start the Spring Boot context and launch the JavaFX server dashboard.
The project uses a MariaDB database. Schema management is currently a manual process.
Initial Setup Steps:
- Ensure you have a running MariaDB instance.
- Create an empty database named
kalaazu. - The database schema is defined in multiple SQL files within the
Persistence/database/directory. These are compiled into a single file.- Note: The
Persistence/database/compiler.phpscript was previously used for this. This is being migrated to a Gradle task. For now, you can use the pre-compiledPersistence/database/dump.sqlfile.
- Note: The
- Import the
Persistence/database/dump.sqlfile into yourkalaazudatabase using a tool like phpMyAdmin, DBeaver, or the command line. - Configure your database connection credentials in
Launcher/src/main/resources/application.yml. You can use a profile-specific file (e.g.,application-dev.yml) or set the values using environment variables as defined in the default file.
Making Schema Changes:
- There is no automated migration tool like Flyway or Liquibase.
- To add or modify a table, edit the corresponding files in
Persistence/database/<table_name>/. - After editing, you must manually apply the SQL changes to your local database.
- Incoming Packets:
- Netty decodes raw data into a version-specific
InCommandobject. - The
ChannelManagerreceives the command. - In its
processPacketmethod, it iterates through a list ofPacketHandlers for the current client version and invokes the handler that matches the incoming command.
- Netty decodes raw data into a version-specific
- Outgoing Packets:
- To send data to clients, publish a Spring
ApplicationEvent. - The
ChannelManagerlistens for these events and sends the commands to the appropriateGameSession(s). - Key Events:
SendCommand(to one session),SendCommands(multiple commands to one session),SendCommandToSessions(one command to many sessions),BroadcastCommand(to all sessions).
- To send data to clients, publish a Spring
- The process starts in the Vue.js frontend within the
CMSmodule. - The frontend calls a registration API endpoint in the
CMSmodule's Java backend. - This endpoint utilizes the
Persistencemodule to create a newUserrecord. - It then creates the necessary associated entries in the
accounts,accounts_hangars,accounts_ships, and otheraccounts_*tables. - When the user later chooses a faction, the
factions_idcolumn in theiraccountstable record is updated.
- When the
Servermodule starts, theMapServiceis initialized. MapServiceretrieves allMapsEntityrecords from the database.- For each map, it creates a dedicated game world, which is an instance of
com.artemis.World(Artemis-ODB). MapServicethen queries the database for all entities belonging to that map (e.g.,maps_npcs,maps_portals,maps_collectables).- The
GameLoopServiceis then called to populate the world. It creates an entity for each object (NPC, portal, etc.) and attaches the necessary components (e.g.,PositionComponent,IdComponent,NpcComponent). - Finally,
GameLoopServicemanages aGameLoopinstance for each map. ThisRunnableis scheduled to run at a fixed rate, callingworld.process()to update the game state for that specific map.
-
Target Selection:
- The client sends a
SelectShipCommandwith the target's public ID (fromIdComponent). - The
SelectShipHandlerreceives this and adds an action to theGameLoopServiceto update the player'sTargetComponentin the ECS world before the next game tick.
- The client sends a
-
Initiating Attack (To be implemented):
- With a target selected, the client will send an
AttackCommand. - A new
AttackHandlerwill process this, likely by adding anAttackingComponentto the player's entity, which a newAttackSystemwill then process.
- With a target selected, the client will send an
-
Damage & Stats:
- To optimize performance, ship stats like laser damage, health, and shield are pre-calculated and stored in the
AccountsConfigurationsEntity. - Game systems should read from this configuration rather than calculating stats from raw equipment data on the fly.
- To optimize performance, ship stats like laser damage, health, and shield are pre-calculated and stored in the
-
Projectiles & Visuals:
- Projectile physics are not simulated on the server.
- The server's role is to validate an attack, calculate damage, and then notify the client.
- It sends commands like
AttackStartedCommandorRocketFiredCommandcontaining visual information (e.g., laser GFX ID). The client is responsible for rendering the animations.
-
Entity Destruction (To be implemented):
- When an entity's health reaches zero, a system will need to handle its destruction.
- This process will involve removing the entity from the world and triggering a reward calculation and distribution process (for experience, currency, honor, etc.).
The database schema (dump.sql) is the single source of truth for the game's data structures. Understanding these
relationships is critical for implementing new features.
users: Stores the master login credentials (name,password,email).accounts: Represents a single in-game character. Ausercan have multipleaccounts. This table is the central hub for a player's state, linking to their faction, level, rank, and clan.accounts_hangars: Eachaccounthas one or more hangars. Theaccountstable points to the currently active hangar viaaccounts_hangars_id.accounts_ships: Stores the ships owned by an account. It tracks the ship's current state, includinghealth,shield,position, andmaps_id.
accounts_configurations: This is a crucial performance optimization. Each hangar has two configurations (config 1 and 2). This table stores the pre-calculated, denormalized stats (damage,health,shield,speed) for each configuration.- Guideline: Combat systems should always read these final stats from the
AccountsConfigurationsEntity. * Do not* recalculate stats from individual items during the game loop.
- Guideline: Combat systems should always read these final stats from the
accounts_items: The player's master inventory of all owned items (lasers, shields, generators, etc.).accounts_configurations_accounts_items: This is the join table that defines which items fromaccounts_itemsare equipped in a specific configuration (accounts_configurations_id), ship, drone, or P.E.T.
items: The master catalog for every item in the game. Thecategoryandtypecolumns are essential for logic (e.g.,category=4for generators,type=16for lasers).ships: Defines the base stats for each ship type (base health, speed, cargo, and slot counts).npcs: Defines the base stats for all alien types (health, shield, damage, speed, AI type).rewards: A master list of all possible reward packages (e.g., 100 Uridium, 2000 Credits).
The reward system is highly normalized:
rewards_npcs: Links annpcsID to one or morerewardsIDs. This defines the loot table for each alien.rewards_galaxygates: Links agalaxygatesID to its completion rewards.rewards_collectables: Links acollectablesID (e.g., a bonus box) to its potential rewards.
maps: Defines all maps, their names, and whether they are PvP enabled.maps_portals: Defines the jump gates on each map, including their position and target map/position.maps_stations: Defines the positions of faction bases on the maps.maps_npcs: Defines which NPCs spawn on which map and in what quantity. This is used by theMapServiceto populate the game world.
- Clans:
clans,clans_roles,clans_diplomacies,permissions. This structure supports a rich social system with roles, permissions, and diplomacy (War, NAP, Alliance). - Galaxy Gates:
galaxygates,galaxygates_waves,galaxygates_spawns. Defines the structure for the wave-based PvE system. Thegalaxygates_spinsandgalaxygates_probabilitiestables define the materializer/spinner rewards. - Skill Tree:
skilltree_skillsandskilltree_levelsdefine the available skills and their upgrade progression.accounts_skillsstores the player's progress. - Skylab & Techfactory:
skylab_modules,techfactory_items, andtechfactory_costsdefine the data for the long-term resource production and item crafting systems.
- Build Tool: The project is built using Gradle. Dependencies are managed in the
build.gradlefile of each module. - ORM: Database entities (ORMs) are located in the
Persistence/src/main/javadirectory. When you modify the schema, ensure the corresponding JPA entity is updated. - Game Logic: The core game logic resides in the
Servermodule. It uses Netty for networking and Artemis-ODB for the ECS architecture.
- Location: The frontend source code is located at
CMS/src/main/www. - Development Server: To work on the frontend, navigate to the
CMS/src/main/wwwdirectory and use standard npm commands:npm installto install dependencies.npm run dev(or similar) to start the local development server.
- Build Integration: The Gradle build for the
CMSmodule (CMS/build.gradle) is configured to build the frontend assets, but this step is currently disabled to speed up backend development.
- Language: The primary backend language is Java 26.
- Code Style: Please adhere to the default code style and conventions for the language you are working with (Java, Vue.js). Maintain consistency with the existing codebase.
- ORM Entities: JPA entities are located in the
Persistencemodule. Ensure they are kept in sync with the database schema.
| Command | Purpose |
|---|---|
Run com.kalaazu.Launcher from IDE |
Starts the entire application, including the JavaFX dashboard. |
./gradlew build |
Compiles and builds all modules. |
./gradlew :Launcher:bootRun |
Runs the application using Gradle. |
cd CMS/src/main/www && npm run dev |
Starts the frontend development server. |
php Persistence/database/compiler.php |
(Legacy) Compiles database schema files into a single SQL file. |
Following these practices ensures that the development workflow remains efficient and consistent.