Back to Home
Documentation
Quick Start
Prerequisites
- Zig 0.11+ (build system)
- Lua 5.4
Build & Run
# Clone the repository
git clone https://github.com/LoxleyX/havyn
cd havyn
# Build the server
zig build
# Start the server
./zig-out/bin/havyn-serverServer Ports
- Login (TCP):
7777 - Map (UDP):
7778
Architecture
Havyn separates the C++ server framework from Lua game content. The server handles networking and performance-critical systems while Lua scripts define game behavior.
havyn/
├── src/
│ ├── core/ # Server framework (game-agnostic)
│ │ ├── server.* # Main server, module loading
│ │ ├── session.* # Client session management (TCP+UDP)
│ │ ├── packet.* # Protocol, MessagePack serialization
│ │ └── zone.* # World zones, entity containers
│ │
│ ├── lua/ # Sol2 Lua bindings
│ │ ├── lua_manager.* # VM init, script loading
│ │ └── lua_entity.* # Entity API for scripts
│ │
│ └── modules/ # Pluggable game systems
│ ├── auth/ # Login, character creation
│ ├── movement/ # Position sync, zone transitions
│ ├── combat/ # Targeting, damage, death
│ ├── party/ # Group/crew system
│ └── companion/ # AI followers
│
├── scripts/ # Lua game content
│ ├── mobs/ # Mob AI and stats
│ ├── abilities/ # Skill effects
│ └── companions/ # Companion behaviors
│
└── deps/ # Header-only libraries
├── asio/ # Networking
├── msgpack/ # Serialization
├── sol2/ # Lua bindings
└── lua/ # Lua 5.4Modules
| Module | Description |
|---|---|
| auth | Login, character creation, session management |
| movement | Position sync, zone transitions |
| combat | Targeting, auto-attack, damage, death |
| party | Invites, member sync, leader promotion |
| companion | AI followers with Lua-scripted behavior |
Lua API
Game content is defined in Lua scripts. The C++ server exposes entity methods through Sol2 bindings.
Entity Methods
-- Identity
entity:getID()
entity:getName()
-- Health
entity:getHP()
entity:setHP(value)
entity:getHPP() -- Health percentage
-- Stats
entity:getStat(name)
entity:setMod(name, value)
-- Combat
entity:takeDamage(amount, type, attacker)
entity:addStatusEffect(id, duration)
-- Communication
entity:say(message)
-- Variables
entity:setLocalVar(name, value)
entity:getLocalVar(name)
-- Movement
entity:distanceTo(target)
entity:pathTo(x, y, z)Mob Callbacks
return {
name = "Skeleton Pirate",
stats = { hp = 50, str = 8, def = 3 },
onSpawn = function(mob)
-- Called when mob spawns
end,
onEngage = function(mob, target)
-- Called when combat starts
end,
onFight = function(mob, target)
-- Called during combat (periodic)
end,
onDeath = function(mob, killer)
-- Called when mob dies
end
}Companion Callbacks
return {
onSpawn = function(companion, owner)
-- Called when companion is summoned
end,
onCombatStart = function(companion, target)
-- Called when owner enters combat
end,
onOwnerDamaged = function(companion, attacker, damage)
-- Called when owner takes damage
end
}Protocol
Havyn uses a dual-protocol design for optimal performance.
| Protocol | Port | Use Case |
|---|---|---|
| TCP | 7777 | Login, authentication, reliable packets |
| UDP | 7778 | Movement, combat, real-time sync |
Packets use MessagePack serialization with a 4-byte length prefix.
Packet Structure
// Packet header
struct PacketHeader {
uint32_t length; // Total packet length
uint16_t opcode; // Packet type
};
// Example: Position update
struct PositionUpdate {
uint32_t entity_id;
float x, y, z;
float rotation;
};Configuration
Server configuration is handled via command-line arguments.
# Custom ports
./zig-out/bin/havyn-server --tcp-port 7777 --udp-port 7778
# Debug mode
./zig-out/bin/havyn-server --debugNeed Help?
Check the GitHub repository for issues, discussions, and examples.
Visit GitHub →