{"id":245,"date":"2025-04-19T20:17:34","date_gmt":"2025-04-19T19:17:34","guid":{"rendered":"https:\/\/guillaumesblog.net\/?p=245"},"modified":"2025-04-19T20:47:45","modified_gmt":"2025-04-19T19:47:45","slug":"run-a-opendaoc-game-server","status":"publish","type":"post","link":"https:\/\/guillaumesblog.net\/index.php\/run-a-opendaoc-game-server\/","title":{"rendered":"Run an OpenDAOC Game Server"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Does anyone remember this game? I absolutely use to love this game and still do, and I recently had the weird idea to set-up my own server and though that maybe I could find some source code online to run, and boom, I came across this mod of the famous 2001 Mythic game. It is called OpenDAOC thanks to the instructions it is actually really easy to spin your own server up, so let&#8217;s do it.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">First thing we want to do is to have the correct Operating server, in my case I have used Ubuntu 22, so get a virtual machine with it or a spare machine connected to your LAN. Then, we are going to install docker and docker compose on it, there are plenty of resources online to do it and its a matter of copy paste. Follow steps here: <a href=\"https:\/\/docs.docker.com\/compose\/install\/\">https:\/\/docs.docker.com\/compose\/install\/<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The process now starts, go to the folder of your choice in my case<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\nmkdir daoc\ncd daoc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once in there create a file docker compose like so<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vim docker-compose.yml<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and copy paste the code at <a href=\"https:\/\/www.opendaoc.com\/docs\/core\/docker-setup\/\">https:\/\/www.opendaoc.com\/docs\/core\/docker-setup\/<\/a> but we are going to add a port mapping to the database, so we can access the database from the docker host, our physical machine, via our mysql client. Why? I&#8217;ll tell you in a bit. (see below in bold).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>networks:\n  opendaoc-network:\n    driver: bridge\n\nvolumes:\n  opendaoc-db-data:\n  base-db:\n\nservices:\n  db:\n    image: mariadb:10.6\n    container_name: opendaoc-db\n    stdin_open: true\n    tty: true\n    command: --default-authentication-plugin=mysql_native_password --lower_case_table_names=1 --character-set-server=utf8mb3 --collation-server=utf8mb3_general_ci --innodb_large_prefix=1 --innodb_file_format=Barracuda --innodb_file_per_table=1\n    restart: always\n    environment:\n      MYSQL_DATABASE: opendaoc\n      MYSQL_ROOT_PASSWORD: my-secret-pw\n    volumes:\n      - opendaoc-db-data:\/var\/lib\/mysql\n      - base-db:\/docker-entrypoint-initdb.d\n    networks:\n      - opendaoc-network\n   <strong> ports:\n      - \"3306:3306\"<\/strong>\n\n  gameserver:\n    image: ghcr.io\/opendaoc\/opendaoc-core:latest\n    container_name: opendaoc-server\n    stdin_open: true\n    tty: true\n    ports:\n      - \"10300:10300\"\n      - \"10400:10400\"\n    depends_on:\n      - db\n    environment:\n      UID: \"1000\"\n      GID: \"1000\"\n      AUTO_ACCOUNT_CREATION: \"True\"\n      CHEAT_LOGGER_NAME: \"cheats\"\n      CPU_USE: \"8\"\n      DB_AUTOSAVE: \"True\"\n      DB_AUTOSAVE_INTERVAL: \"10\"\n      DB_CONNECTION_STRING: \"server=db;port=3306;database=opendaoc;userid=root;password=my-secret-pw;treattinyasboolean=true\"\n      DB_TYPE: \"MYSQL\"\n      DETECT_REGION_IP: \"True\"\n      ENABLE_COMPILATION: \"True\"\n      ENABLE_UPNP: \"False\"\n      GAME_TYPE: \"Normal\"\n      GM_ACTION_LOGGER_NAME: \"gmactions\"\n      INVALID_NAMES_FILE: \".\/config\/invalidnames.txt\"\n      LOG_CONFIG_FILE: \".\/config\/logconfig.xml\"\n      REGION_IP: \"0.0.0.0\"\n      REGION_PORT: \"10400\"\n      SCRIPT_ASSEMBLIES: \"\"\n      SCRIPT_COMPILATION_TARGET: \".\/lib\/GameServerScripts.dll\"\n      SERVER_IP: \"0.0.0.0\"\n      SERVER_NAME: \"OpenDAoC\"\n      SERVER_NAME_SHORT: \"OPENDAOC\"\n      SERVER_PORT: \"10300\"\n      UDP_IP: \"0.0.0.0\"\n      UDP_PORT: \"10400\"\n      DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: \"False\"\n    volumes:\n      - base-db:\/tmp\/opendaoc-db\n    networks:\n      - opendaoc-network<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cool, so now inside the ~\/daoc folder just type <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose up -d<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is going to immediately pull the correct prepackaged image from the db service and same for the game server. As you can see both of the containers are on the same network &#8220;opendaoc-network&#8221; and as such can reach each other, which is what we want. So in a nutshell we have nothing to do.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>guillaume@upper:~$ docker ps\nCONTAINER ID   IMAGE                                   COMMAND                  CREATED       STATUS       PORTS                                                                                              NAMES\n48f408225c78   ghcr.io\/opendaoc\/opendaoc-core:latest   \"\/bin\/sh \/app\/entryp\u2026\"   8 hours ago   Up 8 hours   0.0.0.0:10300-&gt;10300\/tcp, &#91;::]:10300-&gt;10300\/tcp, 0.0.0.0:10400-&gt;10400\/tcp, &#91;::]:10400-&gt;10400\/tcp   opendaoc-server\ndae8f104ae3b   mariadb:10.6                            \"docker-entrypoint.s\u2026\"   8 hours ago   Up 8 hours   0.0.0.0:3306-&gt;3306\/tcp, &#91;::]:3306-&gt;3306\/tcp                                                        opendaoc-db<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both containers are running, and we could launch the game at this stage by downloading the OpenDAOC client here: <a href=\"https:\/\/www.opendaoc.com\/docs\/client\/\">https:\/\/www.opendaoc.com\/docs\/client\/<\/a> but before we do that and we edit the client launch file we need to have a look at the database: it needs to be filled with mobs, quests, drops, weapons, and so in order to have a complete game! Otherwise you&#8217;d launch the game with an also empty world.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Download and install mysql client on your machine, typically<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install mysql-client<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then go to <a href=\"https:\/\/github.com\/OpenDAoC\/OpenDAoC-Database\">https:\/\/github.com\/OpenDAoC\/OpenDAoC-Database<\/a> and download or git pull the folder. Now it downloaded and you know where you&#8217;ve put the downloaded files? good.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Connect to the mysql database, look at the databases available and create a new one in which we are going to apply all the &#8220;OpenDAOC-Database&#8221;.sql files we&#8217;ve just downloaded. Below we are creating <em>dummydaoc<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>guillaume@upper:~$ mysql -h 127.0.0.1 -u root -pWelcome1\nmysql: &#91;Warning] Using a password on the command line interface can be insecure.\nWelcome to the MySQL monitor.  Commands end with ; or \\g.\nYour MySQL connection id is 17\nServer version: 5.5.5-10.6.21-MariaDB-ubu2004 mariadb.org binary distribution\n\nCopyright (c) 2000, 2025, Oracle and\/or its affiliates.\n\nOracle is a registered trademark of Oracle Corporation and\/or its\naffiliates. Other names may be trademarks of their respective\nowners.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nmysql&gt; show databases;\n+--------------------+\n| Database           |\n+--------------------+\n| information_schema |\n| mysql              |\n| opendaoc           |\n| performance_schema |\n| sys                |\n+--------------------+\n6 rows in set (0.00 sec)\n\nmysql&gt; CREATE DATABASE dummydaoc;\nQuery OK, 1 row affected (0.00 sec)\n\nmysql&gt; show databases;\n+--------------------+\n| Database           |\n+--------------------+\n|<strong> dummydaoc  <\/strong>        |\n| information_schema |\n| mysql              |\n| opendaoc           |\n| performance_schema |\n| sys                |\n+--------------------+\n7 rows in set (0.00 sec)\n\nmysql&gt; exit\nBye!<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, we are going to apply the bunch of .sql files to dummydaoc. Travel to the folder with the sql file, in my case<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>guillaume@upper:~\/daoc\/OpenDAoC-Database-master\/opendaoc-db-core$ pwd\n\/home\/guillaume\/daoc\/OpenDAoC-Database-master\/opendaoc-db-core\nguillaume@upper:~\/daoc\/OpenDAoC-Database-master\/opendaoc-db-core$ ls\nability.sql                          languagegameobject.sql\naccount.sql                          languagenpc.sql\n<strong><em>&#91;...] \/\/ I've shortened the output<\/em><\/strong><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and type in<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for file in *.sql; do\n  echo \"Applying $file to your_database_name...\"\n  mysql -u root -p'my-secret-pw' dummydaoc &lt; \"$file\"\n  echo \"\"\ndone<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Normally all files have been applied to dummydaoc, so you can connect to the database again and verify, you should see a massive list of tables.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>guillaume@upper:~$ mysql -h 127.0.0.1 -u root -pWelcome1\nmysql&gt; use dummydaoc;\nmysql&gt; show tables;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We need to use the correct database for the world to be populated, you remember? We need to relaunch the gameserver service from above with the correct newly created database change, it&#8217;s just matter of saying &#8220;point to dummydaoc&#8221;, instead of &#8220;opendaoc&#8221;, so go back to the docker compose file and edit it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>networks:\n  opendaoc-network:\n    driver: bridge\n\nvolumes:\n  opendaoc-db-data:\n  base-db:\n\nservices:\n  db:\n    image: mariadb:10.6\n    container_name: opendaoc-db\n    stdin_open: true\n    tty: true\n    command: --default-authentication-plugin=mysql_native_password --lower_case_table_names=1 --character-set-server=utf8mb3 --collation-server=utf8mb3_general_ci --innodb_large_prefix=1 --innodb_file_format=Barracuda --innodb_file_per_table=1\n    restart: always\n    environment:\n      MYSQL_DATABASE: opendaoc\n      MYSQL_ROOT_PASSWORD: my-secret-pw\n    volumes:\n      - opendaoc-db-data:\/var\/lib\/mysql\n      - base-db:\/docker-entrypoint-initdb.d\n    networks:\n      - opendaoc-network\n<strong>    ports:\n      - \"3306:3306\"<\/strong>\n\n  gameserver:\n    image: ghcr.io\/opendaoc\/opendaoc-core:latest\n    container_name: opendaoc-server\n    stdin_open: true\n    tty: true\n    ports:\n      - \"10300:10300\"\n      - \"10400:10400\"\n    depends_on:\n      - db\n    environment:\n      UID: \"1000\"\n      GID: \"1000\"\n      AUTO_ACCOUNT_CREATION: \"True\"\n      CHEAT_LOGGER_NAME: \"cheats\"\n      CPU_USE: \"8\"\n      DB_AUTOSAVE: \"True\"\n      DB_AUTOSAVE_INTERVAL: \"10\"\n  <strong>    DB_CONNECTION_STRING: \"server=db;port=3306;database=dummydaoc;userid=root;password=my-secret-pw;treattinyasboolean=true\"<\/strong>\n      DB_TYPE: \"MYSQL\"\n      DETECT_REGION_IP: \"True\"\n      ENABLE_COMPILATION: \"True\"\n      ENABLE_UPNP: \"False\"\n      GAME_TYPE: \"Normal\"\n      GM_ACTION_LOGGER_NAME: \"gmactions\"\n      INVALID_NAMES_FILE: \".\/config\/invalidnames.txt\"\n      LOG_CONFIG_FILE: \".\/config\/logconfig.xml\"\n      REGION_IP: \"0.0.0.0\"\n      REGION_PORT: \"10400\"\n      SCRIPT_ASSEMBLIES: \"\"\n      SCRIPT_COMPILATION_TARGET: \".\/lib\/GameServerScripts.dll\"\n      SERVER_IP: \"0.0.0.0\"\n      SERVER_NAME: \"OpenDAoC\"\n      SERVER_NAME_SHORT: \"OPENDAOC\"\n      SERVER_PORT: \"10300\"\n      UDP_IP: \"0.0.0.0\"\n      UDP_PORT: \"10400\"\n      DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: \"False\"\n    volumes:\n      - base-db:\/tmp\/opendaoc-db\n    networks:\n      - opendaoc-network<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Relaunch the gameserver service<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker-compose rm -f gameserver &amp;&amp; docker-compose up -d gameserver<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can verify with docker ps command that you&#8217;ve got both container are live, db and gameserver. Now this is done let&#8217;s go back to our client. Install the client on a simple path e.g. C:\/openDAOC or something you can remember, create a .txt on your Desktop and go to the first line and key in<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"<strong>E:\\OpenDAoC\\<\/strong>connect.exe\" \"<strong>E:\\OpenDAoC\\<\/strong>game1127.dll\" yourip Patrick Welcome1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not skip the &#8220;&#8221; but change the path to your game so the script can find the files connect.exe and game1127.dll, at <strong>yourip<\/strong> you can either enter either your public IP, your domain or your local IP. Then enter a name which will create an account in the database automatically and the password of your choice, it does not matter, use whatever, but re-use the same credentials in order to find your characters again though.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1299\" height=\"444\" src=\"https:\/\/guillaumesblog.net\/wp-content\/uploads\/2025\/04\/launcher.png\" alt=\"\" class=\"wp-image-263\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file and change the extension to .bat, you can now launch the game by double clicking, you are in.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"904\" height=\"655\" src=\"https:\/\/guillaumesblog.net\/wp-content\/uploads\/2025\/04\/ingame.png\" alt=\"\" class=\"wp-image-264\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, two things, one make sure that the machine, in my case the ubuntu VM, does have its firewall down for ports 10300 and 10400, because if you look at the docker compose file these are the ports used for the application to listen onto incoming connections. If you want your friends to join over the internet your server it needs to be reachable, you need to enable port forwarding on your home router, and state that connections on 10300 and 10400 must be routed to local ip e.g. 192.168.1.74 or your machine name or FQDN &#8220;in my case it is <strong>upper.home<\/strong>&#8221; if you have your dns service working (set up on your router as well), you may have to take a firewall setting down on the router as well.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>guillaume@upper:~\/daoc$ ip addr | grep 192\n    inet 192.168.1.74\/24 brd 192.168.1.255 scope global dynamic noprefixroute eno1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Happy gaming.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Does anyone remember this game? I absolutely use to love this game and still do, and I recently had the weird idea to set-up my own server and though that maybe I could find some source code online to run, and boom, I came across this mod of the famous 2001 Mythic game. It is &hellip; <a href=\"https:\/\/guillaumesblog.net\/index.php\/run-a-opendaoc-game-server\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Run an OpenDAOC Game Server&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-245","post","type-post","status-publish","format-standard","hentry","category-conversation"],"_links":{"self":[{"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/posts\/245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":25,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"predecessor-version":[{"id":273,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/posts\/245\/revisions\/273"}],"wp:attachment":[{"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/guillaumesblog.net\/index.php\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}