Skip to content

Setting up

Everything on this page holds whatever language you script in; the language pages start where this one ends.

  • The game - Kingdom Come: Deliverance II on Steam, the build the current KCD:MP release was made for (the release notes say which). The server itself does not need the game, but the world data it wants is exported from a copy of it.
  • The KCD:MP client - the launcher and the client, from the download page at kcd-mp.com, on every machine that plays. The launcher starts the game with KCD:MP inside it and connects it to a server. Unpack it anywhere once; from then on the launcher tells you when a newer release is out and updates itself on your say-so.
  • The server folder - the dedicated server, from the same download page under Host your own: one archive with a windows/ and a linux/ folder inside; unpack it and take the folder for your system. It is a .NET 10 program: the machine that runs it installs the .NET 10 runtime once. A server needs one UDP port (7777 by default).

The folder is the same on both systems:

KcdMp.Server (.exe) the server
server.toml every setting, every key documented; the server reads it from the folder it runs in
gamemodes/ the game modes: freeroam.lua, duel_arena.lua, the marker example (a mode with a client half) and a README
sdk/ what your editor and a C# project use: KcdMp.Api.dll + .xml, KcdMp.d.lua, KcdMp-client.d.lua
data/ what the server keeps (the player records) and reads (the game's tables, the world data) - with a README
tools/ Windows only: the exporters that make the game's data from your own copy of the game

server.toml is read from the working directory (or --config <path>); every key is optional and Server configuration lists them all with their defaults. A command-line flag overrides the file (--max-players 64 beats [server] max_players).

Run the server in its folder - KcdMp.Server.exe on Windows, ./KcdMp.Server on Linux - and read its first lines: the version and the protocol number, the tick rate, which game mode it loaded, and one line per data file it found or could not use (combat tables: ..., heightmap: ..., navmesh: ..., collision: ...). A missing file turns one thing off and nothing else; the server runs without any of them. Ctrl+C stops it; --version prints the version and exits.

Two settings are worth a look before anyone else joins:

[server]
name = "KCD:MP dev server" # what the players see in the launcher
password = "" # "" = anyone may join
[master]
url = "https://kcd-mp.com/server-list" # the public list; "" = announce nowhere, a private server

A server announces itself to the public list by default, so a test server is best made private (url = "") or passworded until it is meant to be found. Putting a server on the list has the rest - the port, the address the list should show, what players see.

Open the launcher with Steam running, type the name the other players will see, and connect: Servers lists the public list, Direct connect takes an address - 127.0.0.1:7777 for a server on the same machine, the machine’s address on a LAN. The launcher asks the server for its level and boots the game onto it; the first load takes a little longer than usual. In the game, T opens the chat, Tab the scoreboard, Esc the menu; /help in the chat lists the commands the server answers.

The server does not have the game. Four files, each made once from your own copy of it with the tools in tools/ (Windows - the machine the game is installed on) and put under data/, give it what it lacks; a server on Linux gets the files copied over. Each is one job, one guide:

File What it turns on Guide
data/combat/items.json damage from the game’s own weapon and armour tables; items, souls, buffs and meshes by name (/give shortswordBroad, a horse breed by name, a potion the server owns); the reference lists as the server resolves them Exporting the game’s tables
data/heightmaps/<level>.hmap the terrain check - a player far under or over the ground is pulled back - and the terrain height for a game mode Exporting the terrain
data/navmesh/<level>.knav NPC actors that walk around walls instead of into them; paths and reachability for a game mode Exporting the navigation mesh
data/collision/<level>.kcol line of sight on hits and shots, the floor under a player as the ground, rays for a game mode Exporting the collision geometry

Do the tables first: without them the server knows items, souls and buffs by their GUIDs only and takes the damage the players’ games report. The other three are per level and can wait until the server needs them.

[gamemode] script names it; the command line (--gamemode gamemodes/duel_arena.lua) wins over the file:

[gamemode]
script = "gamemodes/freeroam.lua" # everyone in one world around the spawn, global chat, parties, the NPC actor demo
# script = "gamemodes/duel_arena.lua" # /duel queues you; two at a time fight in the arena, nobody else can be hurt
# script = "gamemodes/marker/marker.lua" # the example with a client half: a checkpoint run drawn in each player's game
# script = "gamemodes/arena/Arena.dll" # a C# plugin, in a folder of its own
# script = "" # the built-in freeroam
watch = false # true: a changed script is reloaded by itself (a development server)

A mode is reloaded without a restart by /reload in the chat (admins), by the mode itself, or by watch = true whenever its file changes on disk.

  • In Lua: a file next to the shipped modes, named in server.toml. Getting started on the server is the first script, the tick, ids and units and what happens on an error; the Server API index has every callback and function. A mode that wants something on the players’ screens adds a client script in a client/ folder next to itself.
  • In C#: a class library compiled against sdk/KcdMp.Api.dll, published into a folder of its own under gamemodes/. The C# server API has the project file, the loading, a database behind a plugin and every interface. A C# mode’s client half is a Lua client script all the same.

Whichever it is, the mode runs on the server’s simulation thread, one tick at a time, 30 times a second: a slow callback stalls every player, and the server log says so when it happens.

The server’s own commands - /give, /tp, /horse, /time, /weather, /kick, /reload and the rest - answer admins only. An admin is a registered name that [accounts] admins lists, once its owner has logged in:

[accounts]
admins = ["Henry"]

Join, /register <password> to claim the name, and from the next visit /login <password>; a name in the list becomes an admin the moment it is registered. Chat commands lists every built-in and who may use it; a game mode can promote a player itself.

The server folder carries the whole API in the two forms editors read, so completion, documentation on hover and a warning for a wrong name or argument are there before the server ever runs a line:

  • Lua - sdk/KcdMp.d.lua (the game mode API) and sdk/KcdMp-client.d.lua (the client script API) are definitions for the Lua language server (LuaLS). In VS Code install the “Lua” extension (sumneko) and open the gamemodes folder: its .luarc.json already points the language server at ../sdk. Any other editor that runs the Lua language server takes the same file. For a mode in a folder of its own, put a .luarc.json next to the script:

    { "runtime.version": "Lua 5.4", "workspace.library": ["../../sdk"], "workspace.checkThirdParty": false }

    or copy the .d.lua file into the folder and point workspace.library at ".". lua-language-server --check . in that folder is the same check from a terminal: an unknown name or a wrong argument type is a diagnostic there and a silent nil on the server. The files are also downloadable from this site: KcdMp.d.lua, KcdMp-client.d.lua.

  • C# - sdk/KcdMp.Api.dll with KcdMp.Api.xml next to it: a project that references the DLL gets IntelliSense with every member’s description in Visual Studio, Rider or VS Code with the C# extension. The project file is on the C# page.

The same files are what a coding assistant reads: AI assistants says how to give one the whole reference.