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-server

Server 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.4

Modules

ModuleDescription
authLogin, character creation, session management
movementPosition sync, zone transitions
combatTargeting, auto-attack, damage, death
partyInvites, member sync, leader promotion
companionAI 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.

ProtocolPortUse Case
TCP7777Login, authentication, reliable packets
UDP7778Movement, 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 --debug

Need Help?

Check the GitHub repository for issues, discussions, and examples.

Visit GitHub →