From e1576f40cfa7cba4bb6950c87d21fe5e79bb4243 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Mon, 9 Mar 2015 12:34:32 +0100
Subject: [PATCH] Remove C variant of server, redefine build system to match
 this change.

---
 all.do                                  |   4 +-
 build/compiler_flags                    |   2 +-
 compile-server.sh                       |   2 -
 redo                                    |   4 -
 roguelike                               |   3 +
 plomrogue-server.py => roguelike-server |   0
 roguelike-server.do                     |  10 -
 roguelike_python                        |  12 -
 src/server/ai.c                         | 486 ----------------------
 src/server/ai.h                         |  30 --
 src/server/cleanup.c                    |  70 ----
 src/server/cleanup.h                    |  39 --
 src/server/field_of_view.c              | 381 -----------------
 src/server/field_of_view.h              |  28 --
 src/server/god_commands.c               | 524 ------------------------
 src/server/god_commands.h               |  25 --
 src/server/hardcoded_strings.c          |  62 ---
 src/server/hardcoded_strings.h          |  69 ----
 src/server/init.c                       | 257 ------------
 src/server/init.h                       |  46 ---
 src/server/io.c                         | 441 --------------------
 src/server/io.h                         |  31 --
 src/server/main.c                       |  49 ---
 src/server/map.c                        | 241 -----------
 src/server/map.h                        |  47 ---
 src/server/rrand.c                      |  18 -
 src/server/rrand.h                      |  25 --
 src/server/run.c                        | 467 ---------------------
 src/server/run.h                        |  46 ---
 src/server/thing_actions.c              | 393 ------------------
 src/server/thing_actions.h              |  54 ---
 src/server/things.c                     | 411 -------------------
 src/server/things.h                     | 136 ------
 src/server/world.h                      |  46 ---
 start_server_client_union.sh            |   5 -
 start_server_python_client_union.sh     |  46 ---
 36 files changed, 6 insertions(+), 4504 deletions(-)
 delete mode 100755 compile-server.sh
 rename plomrogue-server.py => roguelike-server (100%)
 delete mode 100644 roguelike-server.do
 delete mode 100755 roguelike_python
 delete mode 100644 src/server/ai.c
 delete mode 100644 src/server/ai.h
 delete mode 100644 src/server/cleanup.c
 delete mode 100644 src/server/cleanup.h
 delete mode 100644 src/server/field_of_view.c
 delete mode 100644 src/server/field_of_view.h
 delete mode 100644 src/server/god_commands.c
 delete mode 100644 src/server/god_commands.h
 delete mode 100644 src/server/hardcoded_strings.c
 delete mode 100644 src/server/hardcoded_strings.h
 delete mode 100644 src/server/init.c
 delete mode 100644 src/server/init.h
 delete mode 100644 src/server/io.c
 delete mode 100644 src/server/io.h
 delete mode 100644 src/server/main.c
 delete mode 100644 src/server/map.c
 delete mode 100644 src/server/map.h
 delete mode 100644 src/server/rrand.c
 delete mode 100644 src/server/rrand.h
 delete mode 100644 src/server/run.c
 delete mode 100644 src/server/run.h
 delete mode 100644 src/server/thing_actions.c
 delete mode 100644 src/server/thing_actions.h
 delete mode 100644 src/server/things.c
 delete mode 100644 src/server/things.h
 delete mode 100644 src/server/world.h
 delete mode 100755 start_server_python_client_union.sh

diff --git a/all.do b/all.do
index 96e8536..77be8b6 100644
--- a/all.do
+++ b/all.do
@@ -1,8 +1,8 @@
-# redo build file to build executables "roguelike-server", "roguelike-client".
+# redo build file to build "roguelike-server", "libplomrogue.so".
 
 # This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
 # or any later version. For details on its copyright, license, and warranties,
 # see the file NOTICE in the root directory of the PlomRogue source package.
 
-redo-ifchange roguelike-server
+redo-ifchange libplomrogue.so
 redo-ifchange roguelike-client
diff --git a/build/compiler_flags b/build/compiler_flags
index 59fcb18..198da87 100644
--- a/build/compiler_flags
+++ b/build/compiler_flags
@@ -2,4 +2,4 @@
 # or any later version. For details on its copyright, license, and warranties,
 # see the file NOTICE in the root directory of the PlomRogue source package.
 
-CFLAGS='-std=c11 -pedantic-errors -Wall -Werror -Wextra -Wformat-security -g'
+CFLAGS='-std=c11 -pedantic-errors -Wall -Werror -Wextra -Wformat-security -O3'
diff --git a/compile-server.sh b/compile-server.sh
deleted file mode 100755
index 5fdc7b2..0000000
--- a/compile-server.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-gcc -shared -fPIC -std=c11 -pedantic-errors -Wall -Werror -Wextra -Wformat-security -O3 -o libplomrogue.so libplomrogue.c -lm
diff --git a/redo b/redo
index 8f459fb..4081117 100755
--- a/redo
+++ b/redo
@@ -18,9 +18,5 @@
 # <https://github.com/plomlompom/plomrogue/issues/2#issuecomment-50972436> for a
 # workaround.
 
-echo "non-redo stuff (preparing for future Python port sans redo needs):"
-echo "Building library for server's Python variant with mere shell one-liner."
-./compile-server.sh
-
 export PATH=$PATH:$PWD/build/redo_scripts
 redo "$@"
diff --git a/roguelike b/roguelike
index a0be8cc..b002721 100755
--- a/roguelike
+++ b/roguelike
@@ -2,7 +2,10 @@
 
 # Wrapper to the script so that its suppressed server messages get read on exit.
 ./start_server_client_union.sh "$@"
+
+# For some reason, mere sync won't ensure a log is written out, so wait a while.
 sync
+sleep 0.5
 if [ -e ./log ]
 then
     cat log
diff --git a/plomrogue-server.py b/roguelike-server
similarity index 100%
rename from plomrogue-server.py
rename to roguelike-server
diff --git a/roguelike-server.do b/roguelike-server.do
deleted file mode 100644
index ebe418d..0000000
--- a/roguelike-server.do
+++ /dev/null
@@ -1,10 +0,0 @@
-# redo build file to build the executable "roguelike-server".
-
-# This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
-# or any later version. For details on its copyright, license, and warranties,
-# see the file NOTICE in the root directory of the PlomRogue source package.
-
-redo-ifchange build/build_template
-TARGET=server
-LIBRARY_LINKS=-lm
-. ./build/build_template
diff --git a/roguelike_python b/roguelike_python
deleted file mode 100755
index 74f7f34..0000000
--- a/roguelike_python
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-# Wrapper to the script so that its suppressed server messages get read on exit.
-./start_server_python_client_union.sh "$@"
-
-# For some reason, mere sync won't ensure a log is written out, so wait a while.
-sync
-sleep 0.5
-if [ -e ./log ]
-then
-    cat log
-fi
diff --git a/src/server/ai.c b/src/server/ai.c
deleted file mode 100644
index 749a385..0000000
--- a/src/server/ai.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* src/server/ai.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "ai.h"
-#include <stdint.h> /* uint8_t, uint16_t, uint32_t, int16_t, UINT16_MAX */
-#include <stdlib.h> /* free() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "hardcoded_strings.h" /* s */
-#include "rrand.h" /* rrand() */
-#include "thing_actions.h" /* get_thing_action_id_by_name() */
-#include "things.h" /* Thing, ThingType, ThingInMemory, get_thing_type() */
-#include "world.h" /* world */
-
-#define N_DIRS 6
-
-
-
-/* Return "score_map"["pos"] unless "check_inhabitant" and cell is inhabited. */
-static uint16_t set_neighbor_val(uint16_t * score_map, uint8_t check_inhabitant,
-                                 uint16_t kill_score, uint16_t pos);
-
-/* Write into "neighbors" scores of the N_DIRS immediate neighbors of the
- * "score_map" cell at "pos_i" (array index), as found in the directions
- * north-east, east, south-east etc. (clockwise order). Use "kill_score" for
- * illegal neighborhoods (i.e. if direction would lead beyond the map's border,
- * or, if "check_inhabitants" is non-zero, into animate-inhabited cell).
- */
-static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i,
-                                uint16_t kill_score, uint16_t * neighbors,
-                                uint8_t check_inhabitants);
-
-/* Iterate over scored cells in "score_map" of world.map's geometry. Compare
- * each cell's score against the score of its immediate neighbors in N_DIRS
- * directions. If any neighbor's score is at least two points lower than the
- * current cell's score, re-set it to 1 point higher than its lowest-scored
- * neighbor. Repeat this whole process until all cells have settled on their
- * final score. Ignore cells whose score is greater than "max_score". Expect
- * "max_score" to be the maximum score for cells, marking them as unreachable.
- */
-static void dijkstra_map(uint16_t * score_map, uint16_t max_score);
-
-/* Helpers to init_score_map(), realizing individual filters. */
-static uint8_t score_map_filter_attack(uint8_t filter, uint16_t * score_map,
-                                       struct Thing * t_eye);
-static uint8_t score_map_filter_flee(uint8_t filter, uint16_t * score_map,
-                                     struct Thing * t_eye);
-static uint8_t score_map_filter_consume(uint8_t filter, uint16_t * score_map,
-                                        struct Thing * t_eye);
-static uint8_t score_map_filter_search(uint8_t filter, uint16_t * score_map,
-                                       struct Thing * t_eye);
-
-/* get_dir_to_nearest_target() helper: Prepare "score_map" for dijkstra_map(). */
-static void init_score_map(char filter, uint16_t * score_map, uint32_t map_size,
-                           struct Thing * t_eye);
-
-/* From "targets" select random "cmp" match as directory by order in "dirs". */
-static char rand_target_dir(char * dirs, uint16_t cmp, uint16_t * targets);
-
-/* Helper to get_dir_to_nearest_target(). */
-static char get_dir_from_neighbors(char filter, struct Thing * t_eye,
-                                   uint16_t * score_map);
-
-/* Set (if possible) as "t_eye"'s command a move to the path to the path-wise
- * nearest target that is not "t_eye" and fits criteria set by "filter". On
- * success, return !0, else 0. Values for "filter":
- * "a": thing in FOV is below a certain distance, animate, but of a type that is
- *      not "t_eye"'s, and starts out weaker than it is; build path as avoiding
- *      things of "t_eye"'s type
- * "f": neighbor cell (not inhabited by any animate thing) further away from
- *      animate thing not further than x steps away and in FOV and of a type
- *      that is not "t_eye"'s, and starts out stronger or as strong as "t_eye"
- *      is currently; or (cornered), if no such flight cell, but thing of above
- *      criteria is too near, a cell closer to it, or, if less near, just wait
- * "c": thing in memorized map is consumable
- * "s": memory map cell with greatest-reachable degree of unexploredness
- */
-static uint8_t get_dir_to_nearest_target(struct Thing * t_eye, char filter);
-
-/* Return 1 if any thing not "t_eye" is known and fulfills some criteria defined
- * by "filter", else 0. Values for "filter":
- * "a" or "f": thing in FOV is animate, but of type that not that of "t_eye",
- *             and starts out weaker ("a") / stronger ("f") than "t_eye" is
- * "c"       : thing in memorized map is consumable
- */
-static uint8_t seeing_thing(struct Thing * t_eye, char filter);
-
-/* Return slot ID of strongest consumable in "t_owner"'s inventory, else -1. */
-static int16_t get_inventory_slot_to_consume(struct Thing * t_owner);
-
-/* Return 1 if "t_standing" is standing on a consumable, else 0. */
-static uint8_t standing_on_consumable(struct Thing * t_standing);
-
-
-
-static uint16_t set_neighbor_val(uint16_t * score_map, uint8_t check_inhabitant,
-                                 uint16_t kill_score, uint16_t pos)
-{
-    if (check_inhabitant)
-    {
-        struct Thing * t = world.things;
-        for (; t; t = t->next)
-        {
-            if (t->lifepoints && pos == t->pos.y * world.map.length + t->pos.x)
-            {
-                return kill_score;
-            }
-        }
-    }
-    return score_map[pos];
-}
-
-
-
-static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i,
-                                uint16_t kill_score, uint16_t * neighbors,
-                                uint8_t check_inhabitants)
-{
-    uint32_t map_size = world.map.length * world.map.length;
-    uint8_t open_north     = pos_i >= world.map.length;
-    uint8_t open_east      = pos_i + 1 % world.map.length;
-    uint8_t open_south     = pos_i + world.map.length < map_size;
-    uint8_t open_west      = pos_i % world.map.length;
-    uint8_t is_indented    = (pos_i / world.map.length) % 2;
-    uint8_t open_diag_west = is_indented || open_west;
-    uint8_t open_diag_east = !is_indented || open_east;
-    neighbors[0] = !(open_north && open_diag_east) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i - world.map.length + is_indented);
-    neighbors[1] = !(open_east) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i + 1);
-    neighbors[2] = !(open_south && open_diag_east) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i + world.map.length + is_indented);
-    neighbors[3] = !(open_south && open_diag_west) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i + world.map.length - !is_indented);
-    neighbors[4] = !(open_west) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i - 1);
-    neighbors[5] = !(open_north && open_diag_west) ? kill_score :
-                   set_neighbor_val(score_map, check_inhabitants, kill_score,
-                                    pos_i - world.map.length - !is_indented);
-}
-
-
-
-static void dijkstra_map(uint16_t * score_map, uint16_t max_score)
-{
-    uint32_t map_size = world.map.length * world.map.length;
-    uint32_t pos;
-    uint16_t i_scans, neighbors[N_DIRS], min_neighbor;
-    uint8_t scores_still_changing = 1;
-    uint8_t i_dirs;
-    for (i_scans = 0; scores_still_changing; i_scans++)
-    {
-        scores_still_changing = 0;
-        for (pos = 0; pos < map_size; pos++)
-        {
-            if (score_map[pos] <= max_score)
-            {
-                get_neighbor_scores(score_map, pos, max_score, neighbors, 0);
-                min_neighbor = max_score;
-                for (i_dirs = 0; i_dirs < N_DIRS; i_dirs++)
-                {
-                    if (min_neighbor > neighbors[i_dirs])
-                    {
-                        min_neighbor = neighbors[i_dirs];
-                    }
-                }
-                if (score_map[pos] > min_neighbor + 1)
-                {
-                    score_map[pos] = min_neighbor + 1;
-                    scores_still_changing = 1;
-                }
-            }
-        }
-    }
-}
-
-
-
-static uint8_t score_map_filter_attack(uint8_t filter, uint16_t * score_map,
-                                       struct Thing * t_eye)
-{
-    if ('a' != filter)
-    {
-        return 0;
-    }
-    struct Thing * t = world.things;
-    for (; t; t = t->next)
-    {
-        if (   t != t_eye && t->lifepoints && t->type != t_eye->type
-            && 'v' == t_eye->fov_map[t->pos.y*world.map.length + t->pos.x]
-            && get_thing_type(t->type)->lifepoints < t_eye->lifepoints)
-        {
-            score_map[t->pos.y * world.map.length + t->pos.x] = 0;
-        }
-        else if (t->type == t_eye->type)
-        {
-            score_map[t->pos.y * world.map.length + t->pos.x] = UINT16_MAX;
-        }
-    }
-    return 1;
-}
-
-
-
-static uint8_t score_map_filter_flee(uint8_t filter, uint16_t * score_map,
-                                     struct Thing * t_eye)
-{
-    if ('f' != filter)
-    {
-        return 0;
-    }
-    struct Thing * t = world.things;
-    for (; t; t = t->next)
-    {
-        if (   t->lifepoints && t->type != t_eye->type
-            && 'v' == t_eye->fov_map[t->pos.y*world.map.length + t->pos.x]
-            && get_thing_type(t->type)->lifepoints >= t_eye->lifepoints)
-        {
-            score_map[t->pos.y * world.map.length + t->pos.x] = 0;
-        }
-    }
-    return 1;
-}
-
-
-
-static uint8_t score_map_filter_consume(uint8_t filter, uint16_t * score_map,
-                                        struct Thing * t_eye)
-{
-    if ('c' != filter)
-    {
-        return 0;
-    }
-    struct ThingInMemory * tm = t_eye->t_mem;
-    for (; tm; tm = tm->next)
-    {
-        if (   ' ' != t_eye->mem_map[tm->pos.y * world.map.length + tm->pos.x]
-            && get_thing_type(tm->type)->consumable)
-        {
-            score_map[tm->pos.y * world.map.length + tm->pos.x] = 0;
-        }
-    }
-    return 1;
-}
-
-
-
-static uint8_t score_map_filter_search(uint8_t filter, uint16_t * score_map,
-                                       struct Thing * t_eye)
-{
-    if (!(('0' < filter && '9' >= filter) || ' ' == filter))
-    {
-        return 0;
-    }
-    uint32_t i;
-    for (i = 0; i < (uint32_t) (world.map.length * world.map.length); i++)
-    {
-        score_map[i] = filter == t_eye->mem_depth_map[i] ? 0 : score_map[i];
-    }
-    return 1;
-}
-
-
-
-static void init_score_map(char filter, uint16_t * score_map, uint32_t map_size,
-                           struct Thing * t_eye)
-{
-    uint32_t i;
-    for (i = 0; i < map_size; i++)
-    {
-        score_map[i] = UINT16_MAX;
-        if ('.' == t_eye->mem_map[i])
-        {
-            score_map[i] = UINT16_MAX-1;
-        }
-    }
-    if (   score_map_filter_attack(filter, score_map, t_eye)
-        || score_map_filter_flee(filter, score_map, t_eye)
-        || score_map_filter_consume(filter, score_map, t_eye)
-        || score_map_filter_search(filter, score_map, t_eye))
-    {
-    }
-}
-
-
-static char rand_target_dir(char * dirs, uint16_t cmp, uint16_t * targets)
-{
-    char candidates[N_DIRS];
-    uint8_t n_candidates = 0;
-    uint8_t i;
-    for (i = 0; i < N_DIRS; i++)
-    {
-        if (cmp == targets[i])
-        {
-            candidates[n_candidates] = dirs[i];
-            n_candidates++;
-        }
-    }
-    return n_candidates ? candidates[rrand() % n_candidates] : 0;
-}
-
-
-
-static char get_dir_from_neighbors(char filter, struct Thing * t_eye,
-                                   uint16_t * score_map)
-{
-    char dir_to_nearest_target = 0;
-    uint16_t pos_i = (t_eye->pos.y * world.map.length) + t_eye->pos.x;
-    char * dirs = "edcxsw";   /* get_neighbor_scores()'s clockwise dir order. */
-    uint16_t neighbors[N_DIRS];
-    get_neighbor_scores(score_map, pos_i, UINT16_MAX, neighbors, 'f'==filter);
-    uint16_t minmax_start = 'f' == filter ? 0 : UINT16_MAX-1;
-    uint16_t minmax_neighbor = minmax_start;
-    uint8_t i;
-    for (i = 0; i < N_DIRS; i++)
-    {
-        if (   (   'f' == filter && score_map[pos_i] < neighbors[i]
-                && minmax_neighbor < neighbors[i] && UINT16_MAX != neighbors[i])
-            || ('f' != filter && minmax_neighbor > neighbors[i]))
-        {
-            minmax_neighbor = neighbors[i];
-        }
-    }
-    if (minmax_neighbor != minmax_start)
-    {
-        dir_to_nearest_target = rand_target_dir(dirs,minmax_neighbor,neighbors);
-    }
-    if ('f' == filter)
-    {
-        if (!dir_to_nearest_target)
-        {
-            if (1 == score_map[pos_i])     /* Attack if cornered too closely. */
-            {
-                dir_to_nearest_target = rand_target_dir(dirs, 0, neighbors);
-            }
-            else if (3 >= score_map[pos_i])    /* If less closely, just wait. */
-            {
-                t_eye->command = get_thing_action_id_by_name(s[S_CMD_WAIT]);
-                return 1;
-            }
-        }
-        else if (dir_to_nearest_target && 3 < score_map[pos_i]) /* Don't flee */
-        {                                                       /* enemy of   */
-            dir_to_nearest_target = 0;                          /* a certain  */
-        }                                                       /* distance.  */
-    }
-    else if ('a' == filter && 10 <= score_map[pos_i])
-    {
-        dir_to_nearest_target = 0;
-    }
-    return dir_to_nearest_target;
-}
-
-
-
-static uint8_t get_dir_to_nearest_target(struct Thing * t_eye, char filter)
-{
-    char dir_to_nearest_target = 0;
-    uint8_t mem_depth_char = ' ';
-    uint8_t run_i = 's' == filter ? 9 /* max explored mem depth age */ + 1 : 1;
-    while (    run_i && !dir_to_nearest_target
-           && ('s' == filter || seeing_thing(t_eye, filter)))
-    {
-        run_i--;
-        uint32_t map_size = world.map.length * world.map.length;
-        uint16_t * score_map = try_malloc(map_size * sizeof(uint16_t),__func__);
-        init_score_map('s' == filter ? mem_depth_char : filter,
-                       score_map, map_size, t_eye);
-        mem_depth_char = ' ' == mem_depth_char ? '9' : mem_depth_char - 1;
-        dijkstra_map(score_map, UINT16_MAX-1);
-        dir_to_nearest_target = get_dir_from_neighbors(filter,t_eye,score_map);
-        free(score_map);
-        if (dir_to_nearest_target && 1 != dir_to_nearest_target)
-        {
-            t_eye->command = get_thing_action_id_by_name(s[S_CMD_MOVE]);
-            t_eye->arg = dir_to_nearest_target;
-        }
-    }
-    return dir_to_nearest_target;
-}
-
-
-
-static uint8_t seeing_thing(struct Thing * t_eye, char filter)
-{
-    if (t_eye->fov_map && ('a' == filter || 'f' == filter))
-    {
-        struct Thing * t = world.things;
-        for (; t; t = t->next)
-        {
-            if (   t != t_eye && t->lifepoints && t->type != t_eye->type
-                && 'v' == t_eye->fov_map[t->pos.y*world.map.length + t->pos.x])
-            {
-                struct ThingType * tt = get_thing_type(t->type);
-                if (   ('f' == filter && tt->lifepoints >= t_eye->lifepoints)
-                    || ('a' == filter && tt->lifepoints <  t_eye->lifepoints))
-                {
-                    return 1;
-                }
-            }
-        }
-    }
-    else if (t_eye->mem_map && 'c' == filter)
-    {
-        struct ThingInMemory * tm = t_eye->t_mem;
-        for (; tm; tm = tm->next)
-        {
-            if (     ' ' != t_eye->mem_map[tm->pos.y*world.map.length+tm->pos.x]
-                && get_thing_type(tm->type)->consumable)
-            {
-                return 1;
-            }
-        }
-    }
-    return 0;
-}
-
-
-
-static int16_t get_inventory_slot_to_consume(struct Thing * t_owner)
-{
-    uint8_t compare_consumability = 0;
-    int16_t selection = -1;
-    struct Thing * t = t_owner->owns;;
-    uint8_t i;
-    for (i = 0; t; t = t->next, i++)
-    {
-        struct ThingType * tt = get_thing_type(t->type);
-        if (tt->consumable > compare_consumability)
-        {
-            compare_consumability = tt->consumable;
-            selection = i;
-        }
-    }
-    return selection;
-}
-
-
-
-static uint8_t standing_on_consumable(struct Thing * t_standing)
-{
-    struct Thing * t = world.things;
-    for (; t; t = t->next)
-    {
-        if (   t != t_standing
-            && t->pos.y == t_standing->pos.y && t->pos.x == t_standing->pos.x
-            && get_thing_type(t->type)->consumable)
-        {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-
-
-extern void ai(struct Thing * t)
-{
-    t->command = get_thing_action_id_by_name(s[S_CMD_WAIT]);
-    if (!get_dir_to_nearest_target(t, 'f'))
-    {
-        int16_t sel = get_inventory_slot_to_consume(t);
-        if (-1 != sel)
-        {
-            t->command = get_thing_action_id_by_name(s[S_CMD_USE]);
-            t->arg = (uint8_t) sel;
-        }
-        else if (standing_on_consumable(t))
-        {
-            t->command = get_thing_action_id_by_name(s[S_CMD_PICKUP]);
-        }
-        else if (   !get_dir_to_nearest_target(t, 'c')
-                 && !get_dir_to_nearest_target(t, 'a'))
-        {
-            get_dir_to_nearest_target(t, 's');
-        }
-    }
-}
diff --git a/src/server/ai.h b/src/server/ai.h
deleted file mode 100644
index 966edd5..0000000
--- a/src/server/ai.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* src/server/ai.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Pseudo AI for actor movement.
- */
-
-#ifndef AI_H
-#define AI_H
-
-struct Thing;
-
-
-
-/* Determine next non-player actor command / arguments by the actor's AI. Actors
- * will look for, and move towards, enemies (animate things not of their own
- * type); if they see none, they will consume consumables in their inventory; if
- * there are none, they will pick up any consumables they stand on; if they
- * stand on none, they will move towards the next consumable they see or
- * remember on the map; if they see or remember none, they'll explore parts of
- * the map unseen since ever or for at least one turn; if there is nothing to
- * explore, they will simply wait.
- */
-extern void ai(struct Thing * t);
-
-
-
-#endif
diff --git a/src/server/cleanup.c b/src/server/cleanup.c
deleted file mode 100644
index ec8017d..0000000
--- a/src/server/cleanup.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* src/server/cleanup.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "cleanup.h"
-#include <stdint.h> /* uint32_t */
-#include <stdlib.h> /* free() */
-#include <unistd.h> /* unlink() */
-#include "../common/readwrite.h" /* try_fclose() */
-#include "hardcoded_strings.h" /* s */
-#include "thing_actions.h" /* free_thing_actions() */
-#include "things.h" /* free_things(), free_thing_types() */
-#include "world.h" /* global world */
-
-
-
-
-/* The clean-up flags set by set_cleanup_flag(). */
-static uint32_t cleanup_flags = 0x0000;
-
-
-
-extern void cleanup()
-{
-    free(world.queue);
-    free(world.map.cells);
-    if (cleanup_flags & CLEANUP_WORLDSTATE)
-    {
-        unlink(s[S_PATH_WORLDSTATE]);
-    }
-    if (cleanup_flags & CLEANUP_THINGS)
-    {
-        free_things(world.things);
-    }
-    if (cleanup_flags & CLEANUP_THING_TYPES)
-    {
-        free_thing_types(world.thing_types);
-    }
-    if (cleanup_flags & CLEANUP_THING_ACTIONS)
-    {
-        free_thing_actions(world.thing_actions);
-    }
-    if (cleanup_flags & CLEANUP_IN)
-    {
-        try_fclose(world.file_in, __func__);
-        unlink(s[S_PATH_IN]);
-    }
-    if (cleanup_flags & CLEANUP_OUT)
-    {
-        try_fclose(world.file_out, __func__);
-        free(world.server_test);
-        unlink(s[S_PATH_OUT]);
-    }
-}
-
-
-extern void set_cleanup_flag(enum cleanup_flag flag)
-{
-    cleanup_flags = cleanup_flags | flag;
-}
-
-
-
-extern void unset_cleanup_flag(enum cleanup_flag flag)
-{
-    cleanup_flags = cleanup_flags ^ flag;
-}
diff --git a/src/server/cleanup.h b/src/server/cleanup.h
deleted file mode 100644
index 2047510..0000000
--- a/src/server/cleanup.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* src/server/cleanup.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Stuff defining / performing the cleanup called by rexit.h's exit functions.
- */
-
-#ifndef CLEANUP_H
-#define CLEANUP_H
-
-
-
-/* set_cleanup_flag() sets any of the flags defined in cleanup_flag to announce
- * the resources that need cleaning up upon program exit. It is to be called at
- * the earliest moment possible after resource creation / initialization.
- */
-enum cleanup_flag
-{
-    CLEANUP_FIFO          = 0x0001,
-    CLEANUP_WORLDSTATE    = 0x0002,
-    CLEANUP_THING_TYPES   = 0x0004,
-    CLEANUP_THINGS        = 0x0008,
-    CLEANUP_THING_ACTIONS = 0x0010,
-    CLEANUP_IN            = 0x0020,
-    CLEANUP_OUT           = 0x0040
-};
-
-/* In addition, unset_cleanup_flag() may be used to unset flags. */
-extern void set_cleanup_flag(enum cleanup_flag flag);
-extern void unset_cleanup_flag(enum cleanup_flag flag);
-
-/* Frees memory and unlinks some files. */
-extern void cleanup();
-
-
-
-#endif
diff --git a/src/server/field_of_view.c b/src/server/field_of_view.c
deleted file mode 100644
index 45c90e6..0000000
--- a/src/server/field_of_view.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/* src/server/field_of_view.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "field_of_view.h"
-#include <math.h> /* pow() */
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, uint16_t, uint32_t, int32_t, UINT8_MAX */
-#include <stdlib.h> /* free() */
-#include <string.h> /* memset() */
-#include "../common/rexit.h" /* exit_trouble() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* yx_uint8 */
-#include "map.h" /* mv_yx_in_dir_legal(), init_empty_map() */
-#include "rrand.h" /* rrand() */
-#include "things.h" /* Thing, ThingInMemory, add_thing_to_memory_map() */
-#include "world.h" /* world  */
-
-
-
-/* Number of degrees a circle is divided into. The greater it is, the greater
- * the angle precision. But make it one whole zero larger and bizarre FOV bugs
- * appear on large maps, probably due to value overflows (TODO: more research!).
- */
-#define CIRCLE 3600000
-
-
-
-/* Angle of a shadow. */
-struct shadow_angle
-{
-    struct shadow_angle * next;
-    uint32_t left_angle;
-    uint32_t right_angle;
-};
-
-
-
-/* Recalculate angle < 0 or > CIRCLE to a value between these two limits. */
-static uint32_t correct_angle(int32_t angle);
-
-/* Try merging the angle between "left_angle" and "right_angle" to "shadow" if
- * it meets the shadow from the right or the left. Returns 1 on success, else 0.
- */
-static uint8_t try_merge(struct shadow_angle * shadow,
-                         uint32_t left_angle, uint32_t right_angle);
-
-/* Try merging the shadow angle between "left_angle" and "right_angle" into an
- * existing shadow angle in "shadows". On success, see if this leads to any
- * additional shadow angle overlaps and merge these accordingly. Return 1 on
- * success, else 0.
- */
-static uint8_t try_merging_angles(uint32_t left_angle, uint32_t right_angle,
-                                  struct shadow_angle ** shadows);
-
-/* Test whether angle between "left_angle" and "right_angle", or at least
- * "middle_angle", is captured inside one of the shadow angles in "shadows". If
- * so, set hex in "fov_map" indexed by "pos_in_map" to 'H'. If the whole angle
- * and not just "middle_angle" is captured, return 1. Any other case: 0.
- */
-static uint8_t shade_hex(uint32_t left_angle, uint32_t right_angle,
-                         uint32_t middle_angle, struct shadow_angle ** shadows,
-                         uint16_t pos_in_map, char * fov_map);
-
-/* To "shadows", add shadow defined by "left_angle" and "right_angle", either as
- * new entry or as part of an existing shadow (swallowed whole or extending it).
- */
-static void set_shadow(uint32_t left_angle, uint32_t right_angle,
-                       struct shadow_angle ** shadows);
-
-/* Free shadow angles list "angles". */
-static void free_angles(struct shadow_angle * angles);
-
-/* Evaluate map position "test_pos" in distance "dist" to the view origin, and
- * on the circle of that distance to the origin on hex "hex_i" (as counted from
- * the circle's rightmost point), for setting shaded hexes in "fov_map" and
- * potentially adding a new shadow to linked shadow angle list "shadows".
- */
-static void eval_position(uint16_t dist, uint16_t hex_i, char * fov_map,
-                          struct yx_uint8 * test_pos,
-                          struct shadow_angle ** shadows);
-
-/* Update "t_eye"'s things-on-map memory by removing from its .t_mem all
- * memorized thing in FOV, and adding inanimate things in FOV to it.
- */
-static void add_things_to_map_memory(struct Thing * t_eye);
-
-
-
-static uint32_t correct_angle(int32_t angle)
-{
-    while (angle < 0)
-    {
-        angle = angle + CIRCLE;
-    }
-    while (angle > CIRCLE)
-    {
-        angle = angle - CIRCLE;
-    }
-    return angle;
-}
-
-
-
-static uint8_t try_merge(struct shadow_angle * shadow,
-                         uint32_t left_angle, uint32_t right_angle)
-{
-    if      (   shadow->right_angle <= left_angle + 1
-             && shadow->right_angle >= right_angle)
-    {
-        shadow->right_angle = right_angle;
-    }
-    else if (   shadow->left_angle + 1 >= right_angle
-             && shadow->left_angle     <= left_angle)
-    {
-        shadow->left_angle = left_angle;
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static uint8_t try_merging_angles(uint32_t left_angle, uint32_t right_angle,
-                                  struct shadow_angle ** shadows)
-{
-    uint8_t angle_merge = 0;
-    struct shadow_angle * shadow;
-    for (shadow = *shadows; shadow; shadow = shadow->next)
-    {
-        if (try_merge(shadow, left_angle, right_angle))
-        {
-            angle_merge = 1;
-        }
-    }
-    if (angle_merge)
-    {
-        struct shadow_angle * shadow1;
-        for (shadow1 = *shadows; shadow1; shadow1 = shadow1->next)
-        {
-            struct shadow_angle * last_shadow = NULL;
-            struct shadow_angle * shadow2;
-            for (shadow2 = *shadows; shadow2; shadow2 = shadow2->next)
-            {
-                if (   shadow1 != shadow2
-                    && try_merge(shadow1, shadow2->left_angle,
-                                          shadow2->right_angle))
-                {
-                    struct shadow_angle * to_free = shadow2;
-                    if (last_shadow)
-                    {
-                        last_shadow->next = shadow2->next;
-                        shadow2 = last_shadow;
-                    }
-                    else
-                    {
-                        *shadows = shadow2->next;
-                        shadow2 = *shadows;
-                    }
-                    free(to_free);
-                }
-                last_shadow = shadow2;
-            }
-        }
-    }
-    return angle_merge;
-}
-
-
-
-static uint8_t shade_hex(uint32_t left_angle, uint32_t right_angle,
-                         uint32_t middle_angle, struct shadow_angle ** shadows,
-                         uint16_t pos_in_map, char * fov_map)
-{
-    struct shadow_angle * shadow_i;
-    if (fov_map[pos_in_map] == 'v')
-    {
-        for (shadow_i = *shadows; shadow_i; shadow_i = shadow_i->next)
-        {
-            if (   left_angle <=  shadow_i->left_angle
-                && right_angle >= shadow_i->right_angle)
-            {
-                fov_map[pos_in_map] = 'H';
-                return 1;
-            }
-            if (   middle_angle < shadow_i->left_angle
-                && middle_angle > shadow_i->right_angle)
-            {
-                fov_map[pos_in_map] = 'H';
-            }
-        }
-    }
-    return 0;
-}
-
-
-
-static void set_shadow(uint32_t left_angle, uint32_t right_angle,
-                       struct shadow_angle ** shadows)
-{
-    struct shadow_angle * shadow_i;
-    if (!try_merging_angles(left_angle, right_angle, shadows))
-    {
-        struct shadow_angle * shadow;
-        shadow = try_malloc(sizeof(struct shadow_angle), __func__);
-        shadow->left_angle  = left_angle;
-        shadow->right_angle = right_angle;
-        shadow->next = NULL;
-        if (*shadows)
-        {
-            for (shadow_i = *shadows; shadow_i; shadow_i = shadow_i->next)
-            {
-                if (!shadow_i->next)
-                {
-                    shadow_i->next = shadow;
-                    return;
-                }
-            }
-        }
-        *shadows = shadow;
-    }
-}
-
-
-
-static void free_angles(struct shadow_angle * angles)
-{
-    if (angles->next)
-    {
-        free_angles(angles->next);
-    }
-    free(angles);
-}
-
-
-
-static void eval_position(uint16_t dist, uint16_t hex_i, char * fov_map,
-                          struct yx_uint8 * test_pos,
-                          struct shadow_angle ** shadows)
-{
-    int32_t left_angle_uncorrected =   ((CIRCLE / 12) / dist)
-                                     - (hex_i * (CIRCLE / 6) / dist);
-    int32_t right_angle_uncorrected =   left_angle_uncorrected
-                                      - (CIRCLE / (6 * dist));
-    uint32_t left_angle  = correct_angle(left_angle_uncorrected);
-    uint32_t right_angle = correct_angle(right_angle_uncorrected);
-    uint32_t right_angle_1st = right_angle > left_angle ? 0 : right_angle;
-    uint32_t middle_angle = 0;
-    if (right_angle_1st)
-    {
-        middle_angle = right_angle + ((left_angle - right_angle) / 2);
-    }
-    uint16_t pos_in_map = test_pos->y * world.map.length + test_pos->x;
-    uint8_t all_shaded = shade_hex(left_angle, right_angle_1st, middle_angle,
-                                   shadows, pos_in_map, fov_map);
-    if (!all_shaded && 'X' == world.map.cells[pos_in_map])
-    {
-        set_shadow(left_angle, right_angle_1st, shadows);
-        if (right_angle_1st != right_angle)
-        {
-            left_angle = CIRCLE;
-            set_shadow(left_angle, right_angle, shadows);
-        }
-    }
-}
-
-
-
-static void add_things_to_map_memory(struct Thing * t_eye)
-{
-    struct ThingInMemory * tm = t_eye->t_mem;
-    struct ThingInMemory * tm_prev = NULL;
-    struct ThingInMemory * tm_next = NULL;
-    for (; tm; tm = tm_next)
-    {
-        tm_next = tm->next;
-        if ('v' == t_eye->fov_map[tm->pos.y * world.map.length + tm->pos.x])
-        {
-            if (tm_prev)
-            {
-                tm_prev->next = tm->next;
-            }
-            else
-            {
-                t_eye->t_mem = tm->next;
-            }
-            free(tm);
-            continue;
-        }
-        tm_prev = tm;
-    }
-    struct Thing * t = world.things;
-    for (; t; t = t->next)
-    {
-        if (   !t->lifepoints
-            && 'v' == t_eye->fov_map[t->pos.y * world.map.length + t->pos.x])
-        {
-            add_thing_to_memory_map(t_eye, t->type, t->pos.y, t->pos.x);
-        }
-    }
-}
-
-
-
-extern void update_map_memory(struct Thing * t_eye, uint8_t age_map)
-{
-    if (!t_eye->mem_map)
-    {
-        init_empty_map(&(t_eye->mem_map));
-    }
-    if (!t_eye->mem_depth_map)
-    {
-        init_empty_map(&(t_eye->mem_depth_map));
-    }
-    uint32_t i;
-    for (i = 0; i < (uint32_t) (world.map.length * world.map.length); i++)
-    {
-        if ('v' == t_eye->fov_map[i])
-        {
-            t_eye->mem_depth_map[i] = '0';
-            if (' ' == t_eye->mem_map[i])
-            {
-                t_eye->mem_map[i] = world.map.cells[i];
-            }
-            continue;
-        }
-        if (age_map &&
-            '0' <= t_eye->mem_depth_map[i] && '9' > t_eye->mem_depth_map[i]
-            && !(rrand() % (uint16_t) pow(2, t_eye->mem_depth_map[i] - 48)))
-        {
-            t_eye->mem_depth_map[i]++;
-        }
-    }
-    add_things_to_map_memory(t_eye);
-}
-
-
-
-extern void build_fov_map(struct Thing * t)
-{
-    uint32_t map_size = world.map.length * world.map.length;
-    t->fov_map = t->fov_map ? t->fov_map : try_malloc(map_size, __func__);
-    memset(t->fov_map, 'v', map_size);
-    struct shadow_angle * shadows = NULL;
-    struct yx_uint8 test_pos = t->pos;
-    char * circledirs_string = "xswedc";
-    uint16_t circle_i;
-    uint8_t circle_is_on_map;
-    for (circle_i = 1, circle_is_on_map = 1; circle_is_on_map; circle_i++)
-    {
-        circle_is_on_map = 0;
-        if (1 < circle_i)                      /* All circles but the 1st are */
-        {                                      /* moved into starting from a  */
-            mv_yx_in_dir_legal('c', &test_pos);/* previous circle's last hex, */
-        }                                      /* i.e. from the upper left.   */
-        char dir_char = 'd'; /* Circle's 1st hex is entered by rightward move.*/
-        uint8_t dir_char_pos_in_circledirs_string = UINT8_MAX;
-        uint16_t dist_i, hex_i;
-        for (hex_i=0, dist_i=circle_i; hex_i < 6 * circle_i; dist_i++, hex_i++)
-        {
-            if (circle_i < dist_i)
-            {
-                dist_i = 1;
-                dir_char=circledirs_string[++dir_char_pos_in_circledirs_string];
-            }
-            if (mv_yx_in_dir_legal(dir_char, &test_pos))
-            {
-                eval_position(circle_i, hex_i, t->fov_map, &test_pos, &shadows);
-                circle_is_on_map = 1;
-            }
-        }
-    }
-    mv_yx_in_dir_legal(0, NULL);
-    free_angles(shadows);
-}
diff --git a/src/server/field_of_view.h b/src/server/field_of_view.h
deleted file mode 100644
index be6324b..0000000
--- a/src/server/field_of_view.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* src/server/field_of_view.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Generate field of view maps.
- */
-
-#ifndef FIELD_OF_VIEW_H
-#define FIELD_OF_VIEW_H
-
-#include <stdint.h> /* uint8_t, uint32_t */
-struct Thing;
-
-
-
-/* Update "t_eye"'s .mem_map memory with what's in its current FOV, and update
- * and age the .mem_depth_map.
- */
-extern void update_map_memory(struct Thing * t_eye, uint8_t age_map);
-
-/* Build "t"'s field of view. */
-extern void build_fov_map(struct Thing * t);
-
-
-
-#endif
diff --git a/src/server/god_commands.c b/src/server/god_commands.c
deleted file mode 100644
index 0dbf1a3..0000000
--- a/src/server/god_commands.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* src/server/god_commands.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "god_commands.h"
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t */
-#include <stdlib.h> /* atoi(), free() */
-#include <string.h> /* strcmp(), memset(), memcpy() */
-#include <unistd.h> /* F_OK, access(), unlink() */
-#include "../common/parse_file.h" /* err_line(), parse_val(), parsetest_int() */
-#include "../common/rexit.h" /* exit_trouble() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* unset_cleanup_flag() */
-#include "field_of_view.h" /* build_fov_map(), update_map_memory() */
-#include "hardcoded_strings.h" /* s */
-#include "init.h" /* remake_world() */
-#include "map.h" /* init_empty_map(), remake_map() */
-#include "thing_actions.h" /* ThingAction, actor_wait(), actor_move(),
-                            * actor_use(), actor_pickup(), actor_drop()
-                            */
-#include "things.h" /* Thing, ThingType, add_thing(), get_thing(), own_thing(),
-                     * free_things(), add_thing_to_memory_map(),get_thing_type(),
-                     * get_player()
-                     */
-#include "world.h" /* world */
-
-
-
-/* Parse/apply god command in "tok0"/tok1" to manipulate a ThingType*/
-static uint8_t parse_thingtype_manipulation(char * tok0, char * tok1);
-
-/* If "name" fits "ta"->name, set "ta"->func to "func". (Derives ThingAction
- * .func from .name for set_members().
- */
-static uint8_t try_func_name(struct ThingAction * ta, char * name,
-                             void (* func) (struct Thing *));
-
-/* Parse/apply god command in "tok0"/"tok1" to manipulate a ThingAction. */
-static uint8_t parse_thingaction_manipulation(char * tok0, char * tok1);
-
-/* Parse/apply god command in "tok0"/"tok1" oo setting "t"'s thing type. */
-static uint8_t parse_thing_type(char * tok0, char * tok1, struct Thing * t);
-
-/* Parse/apply god command in "tok0"/"tok1" on setting up thing "t". */
-static uint8_t parse_thing_command(char * tok0, char * tok1, struct Thing * t);
-
-/* Parse/apply god command in "tok0"/"tok1" on positioning a thing "t". */
-static uint8_t parse_position(char* tok0, char * tok1, struct Thing * t);
-
-/* Parse/apply god command in "tok0"/"tok1" on "t" owning another thing. */
-static uint8_t parse_carry(char * tok0, char * tok1, struct Thing * t);
-
-/* Parse/apply god command in "tok0"/"tok1" to manipulate a Thing. */
-static uint8_t parse_thing_manipulation_1arg(char * tok0, char * tok1);
-
-/* Performs parse_world_active()'s world activation legality tests. */
-static uint8_t world_may_be_set_active();
-
-/* Unlink worldstate file if it exists. */
-static void remove_worldstate_file();
-
-/* Parse/apply god command in "tok0"/"tok1" on toggling world.exists. Unset if
- * argument is 0 and unlink worldstate file, but only set it on positive
- * argument if it is not already set and a thing action of name S_CMD_WAIT, a
- * player thing and a map are defined. On setting it, rebuild all FOVs.
- */
-static uint8_t parse_world_active(char * tok0, char * tok1);
-
-/* Parse/apply god command in "tok0"/"tok1" to reset world.map.length. On
- * re-set, set world.exists to 0, remove all things and free world.map.cells
- */
-static uint8_t set_map_length(char * tok0, char * tok1);
-
-
-
-/* Thing, ThingType or ThingAction selected to be manipulated. */
-static struct Thing * t = NULL;
-static struct ThingType * tt = NULL;
-static struct ThingAction * ta = NULL;
-
-
-
-static uint8_t parse_thingtype_manipulation(char * tok0, char * tok1)
-{
-    if (!tt &&
-        (   !strcmp(tok0, s[S_CMD_TT_CONSUM]) || !strcmp(tok0, s[S_CMD_TT_SYMB])
-         || !strcmp(tok0, s[S_CMD_TT_STARTN]) || !strcmp(tok0, s[S_CMD_TT_NAME])
-         || !strcmp(tok0, s[S_CMD_TT_CORPS])  || !strcmp(tok0, s[S_CMD_TT_HP])
-         || !strcmp(tok0, s[S_CMD_TT_PROL])))
-    {
-        return err_line(1, "No thing type defined to manipulate yet.");
-    }
-    int16_t id;
-    if (   parse_val(tok0,tok1,s[S_CMD_TT_CONSUM],'u',(char *) &tt->consumable)
-        || parse_val(tok0,tok1,s[S_CMD_TT_HP],'8',(char *) &tt->lifepoints)
-        || parse_val(tok0,tok1,s[S_CMD_TT_STARTN],'8',(char *) &tt->start_n)
-        || parse_val(tok0,tok1,s[S_CMD_TT_SYMB],'c',(char *) &tt->char_on_map)
-        || parse_val(tok0,tok1,s[S_CMD_TT_PROL],'8',(char *) &tt->proliferate)
-        || parse_val(tok0,tok1,s[S_CMD_TT_NAME],'s',(char *) &tt->name))
-    {
-        ;
-    }
-    else if (parse_val(tok0, tok1, s[S_CMD_TT_CORPS],'8',(char *)&id))
-    {
-        if (!get_thing_type(id))
-        {
-            return err_line(1, "Corpse ID belongs to no known thing type.");
-        }
-        tt->corpse_id = id;
-    }
-    else if (parse_val(tok0, tok1, s[S_CMD_TT_ID], 'i', (char *) &id))
-    {
-        tt = get_thing_type(id);
-        if (!tt)
-        {
-            tt = add_thing_type(id);
-        }
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static uint8_t try_func_name(struct ThingAction * ta, char * name,
-                             void (* func) (struct Thing *))
-{
-    if (0 == strcmp(ta->name, name))
-    {
-        ta->func = func;
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_thingaction_manipulation(char * tok0, char * tok1)
-{
-    if (!ta &&
-        (!strcmp(tok0, s[S_CMD_TA_EFFORT]) || !strcmp(tok0, s[S_CMD_TA_NAME])))
-    {
-        return err_line(1, "No thing action defined to manipulate yet.");
-    }
-    int16_t id;
-    if      (parse_val(tok0, tok1, s[S_CMD_TA_EFFORT],'8',(char *)&ta->effort));
-    else if (parse_val(tok0, tok1, s[S_CMD_TA_NAME], 's', (char *)&ta->name))
-    {
-        if (!(   try_func_name(ta, s[S_CMD_MOVE], actor_move)
-              || try_func_name(ta, s[S_CMD_PICKUP], actor_pick)
-              || try_func_name(ta, s[S_CMD_WAIT], actor_wait)
-              || try_func_name(ta, s[S_CMD_DROP], actor_drop)
-              || try_func_name(ta, s[S_CMD_USE], actor_use)))
-        {
-            return err_line(1, "Invalid action function name.");
-        }
-        if (world.exists)
-        {         /* Legal worlds have at least one thing action for waiting. */
-            world.exists = 0 != get_thing_action_id_by_name(s[S_CMD_WAIT]);
-            if (!world.exists)
-            {
-                remove_worldstate_file();
-            }
-        }
-    }
-    else if (parse_val(tok0, tok1, s[S_CMD_TA_ID], '8', (char *) &id))
-    {
-        ta = get_thing_action(id);
-        if (!ta)
-        {
-            ta = add_thing_action(id);
-        }
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static uint8_t parse_thing_type(char * tok0, char * tok1, struct Thing * t)
-{
-    uint8_t type;
-    if (parse_val(tok0, tok1, s[S_CMD_T_TYPE], '8', (char *) &type))
-    {
-        struct ThingType * tt = get_thing_type(type);
-        if (!err_line(!tt, "Thing type does not exist."))
-        {
-            t->type = type;
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_thing_command(char * tok0, char * tok1, struct Thing * t)
-{
-    uint8_t command;
-    if (parse_val(tok0, tok1, s[S_CMD_T_COMMAND], '8', (char *) &command))
-    {
-        if (!command)
-        {
-            t->command = command;
-            return 1;
-        }
-        struct ThingAction * ta = world.thing_actions;
-        for (; ta && command != ta->id; ta = ta->next);
-        if (!err_line(!ta, "Thing action does not exist."))
-        {
-            t->command = command;
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_position(char* tok0, char * tok1, struct Thing * t)
-{
-    char axis = 0;
-    if      (!strcmp(tok0, s[S_CMD_T_POSY]))
-    {
-        axis = 'y';
-    }
-    else if (!strcmp(tok0, s[S_CMD_T_POSX]))
-    {
-        axis = 'x';
-    }
-    if (axis && !parsetest_int(tok1, '8'))
-    {
-        uint8_t length = atoi(tok1);
-        char * err = "Position is outside of map.";
-        if (!err_line(length >= world.map.length, err))
-        {
-            if      ('y' == axis)
-            {
-                t->pos.y = length;
-            }
-            else if ('x' == axis)
-            {
-                t->pos.x = length;
-            }
-            if (world.exists && t->lifepoints)
-            {
-                build_fov_map(t);
-                if (t == get_player())
-                {
-                    update_map_memory(t, 1);
-                }
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_carry(char * tok0, char * tok1, struct Thing * t)
-{
-    uint8_t id;
-    if (parse_val(tok0, tok1, s[S_CMD_T_CARRIES], '8', (char *) &id))
-    {
-        if (!err_line(id == t->id, "Thing cannot carry itself."))
-        {
-            struct Thing * o = get_thing(world.things, id, 0);
-            if (!err_line(!o, "Thing not available for carrying."))
-            {
-                own_thing(&(t->owns), &world.things, id);
-                o->pos = t->pos;
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_thing_manipulation_1arg(char * tok0, char * tok1)
-{
-    if (!t &&
-        (   !strcmp(tok0, s[S_CMD_T_PROGRESS]) || !strcmp(tok0, s[S_CMD_T_TYPE])
-         || !strcmp(tok0, s[S_CMD_T_CARRIES]) || !strcmp(tok0, s[S_CMD_T_POSY])
-         || !strcmp(tok0, s[S_CMD_T_POSY]) || !strcmp(tok0, s[S_CMD_T_ARGUMENT])
-         || !strcmp(tok0, s[S_CMD_T_HP]) || !strcmp(tok0, s[S_CMD_T_COMMAND])
-         || !strcmp(tok0, s[S_CMD_T_SATIATION])))
-    {
-        return err_line(1, "No thing defined to manipulate yet.");
-    }
-    int16_t id;
-    if (   parse_thing_type(tok0, tok1, t)
-        || parse_thing_command(tok0, tok1, t)
-        || parse_val(tok0,tok1, s[S_CMD_T_ARGUMENT], '8', (char *)&t->arg)
-        || parse_val(tok0,tok1, s[S_CMD_T_PROGRESS], '8', (char *)&t->progress)
-        || parse_val(tok0,tok1, s[S_CMD_T_HP], '8', (char *) &t->lifepoints)
-        || parse_val(tok0,tok1, s[S_CMD_T_SATIATION], 'i',(char *)&t->satiation)
-        || parse_position(tok0, tok1, t)
-        || parse_carry(tok0, tok1, t));
-    else if (parse_val(tok0, tok1, s[S_CMD_T_ID], 'i', (char *) &id))
-    {
-        t = get_thing(world.things, id, 1);
-        char * err = "No thing type found to initialize new thing.";
-        if (!t && !err_line(!world.thing_types, err))
-        {
-            t = add_thing(id, world.thing_types->id, 0, 0);
-        }
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static uint8_t world_may_be_set_active()
-{
-    if (!get_thing_action_id_by_name(s[S_CMD_WAIT]))
-    {
-        err_line(1, "No thing action of name 'wait' found.");
-        return 0;
-    }
-    if (!get_player())
-    {
-        err_line(1, "No un-owned player thing (of id=0) found.");
-        return 0;
-    }
-    if (!world.map.cells)
-    {
-        err_line(1, "No map found.");
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static void remove_worldstate_file()
-{
-    if (!access(s[S_PATH_WORLDSTATE], F_OK))
-    {
-        int test = unlink(s[S_PATH_WORLDSTATE]);
-        exit_trouble(-1 == test, __func__, "unlink");
-    }
-}
-
-
-
-static uint8_t parse_world_active(char * tok0, char * tok1)
-{
-    if (!strcmp(tok0, s[S_CMD_WORLD_ACTIVE]) && !parsetest_int(tok1, '8'))
-    {
-        if (!parsetest_int(tok1, '8'))
-        {
-            uint8_t argument = atoi(tok1);
-            if (!argument)
-            {
-                remove_worldstate_file();
-                world.exists = 0;
-            }
-            else if (world.exists)
-            {
-                err_line(1, "World already active.");
-            }
-            else if (world_may_be_set_active())
-            {
-                struct Thing * ti;
-                for (ti = world.things; ti; ti = ti->next)
-                {
-                    if (ti->lifepoints)
-                    {
-                        build_fov_map(ti);
-                        if (ti == get_player())
-                        {
-                            update_map_memory(ti, 0);
-                        }
-                    }
-                }
-                world.exists = 1;
-            }
-            return 1;
-        }
-    }
-    return 0;
-}
-
-
-
-static uint8_t set_map_length(char * tok0, char * tok1)
-{
-    if (!strcmp(tok0, s[S_CMD_MAPLENGTH]) && !parsetest_int(tok1, 'u'))
-    {
-        uint16_t argument = atoi(tok1);
-        if (argument < 1 || argument > 256)
-        {
-            return err_line(1, "Value must be >= 1 and <= 256.");
-        }
-        world.exists = 0;
-        remove_worldstate_file();
-        free_things(world.things);
-        free(world.map.cells);
-        world.map.cells = NULL;    /* Since remake_map() runs free() on this. */
-        world.map.length = argument;
-        return 1;
-    }
-    return 0;
-}
-
-
-
-extern uint8_t parse_god_command_1arg(char * tok0, char * tok1)
-{
-    if (   parse_thingtype_manipulation(tok0, tok1)
-        || parse_thingaction_manipulation(tok0, tok1)
-        || parse_thing_manipulation_1arg(tok0, tok1)
-        || set_map_length(tok0,tok1)
-        || parse_val(tok0,tok1,s[S_CMD_SEED_RAND],'U', (char *)&world.seed)
-        || parse_val(tok0,tok1,s[S_CMD_TURN],'u',(char *)&world.turn)
-        || parse_val(tok0,tok1,s[S_CMD_PLAYTYPE],'8',(char *)&world.player_type)
-        || parse_world_active(tok0, tok1));
-    else if (parse_val(tok0,tok1,s[S_CMD_SEED_MAP],'U',(char *)&world.seed_map))
-
-    {
-        remake_map();
-    }
-    else if (parse_val(tok0, tok1, s[S_CMD_MAKE_WORLD],'U',(char *)&world.seed))
-    {
-        uint8_t test = remake_world();
-        err_line(1 == test, "No player type with start number of >0 defined.");
-        err_line(2 == test, "No thing action with name 'wait' defined.");
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-extern uint8_t parse_god_command_2arg(char * tok0, char * tok1, char * tok2)
-{
-    if (!t && (   !strcmp(tok0, s[S_CMD_T_MEMMAP])
-               || !strcmp(tok0, s[S_CMD_T_MEMDEPTHMAP])))
-    {
-        return err_line(1, "No thing defined to manipulate yet.");
-    }
-    if (!strcmp(tok0,s[S_CMD_T_MEMMAP]) || !strcmp(tok0,s[S_CMD_T_MEMDEPTHMAP]))
-    {
-        uint8_t y = atoi(tok1);
-        if (parsetest_int(tok1, '8') || y >= world.map.length)
-        {
-            return err_line(1, "Illegal value for map line number.");
-        }
-        if (strlen(tok2) != world.map.length)
-        {
-            return err_line(1, "Map line length is unequal map width.");
-        }
-        if (!strcmp(tok0,s[S_CMD_T_MEMMAP]))
-        {
-            if (!t->mem_map)
-            {
-                init_empty_map(&(t->mem_map));
-            }
-            memcpy(t->mem_map + y * world.map.length, tok2, world.map.length);
-        }
-        else
-        {
-            if (!t->mem_depth_map)
-            {
-                init_empty_map(&(t->mem_depth_map));
-            }
-            memcpy(t->mem_depth_map+y*world.map.length, tok2, world.map.length);
-        }
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-extern uint8_t parse_god_command_3arg(char * tok0, char * tok1, char * tok2,
-                                      char * tok3)
-{
-    if (!t && !strcmp(tok0, s[S_CMD_T_MEMTHING]))
-    {
-        return err_line(1, "No thing defined to manipulate yet.");
-    }
-    if (!strcmp(tok0, s[S_CMD_T_MEMTHING]))
-    {
-        uint8_t id = atoi(tok1);
-        uint8_t y  = atoi(tok2);
-        uint8_t x  = atoi(tok3);
-        if (   parsetest_int(tok1, '8') || !get_thing_type(id)
-            || parsetest_int(tok2, '8') || y >= world.map.length
-            || parsetest_int(tok3, '8') || x >= world.map.length)
-        {
-            return err_line(1, "Illegal value for thing type or position.");
-        }
-        add_thing_to_memory_map(t, id, y, x);
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
diff --git a/src/server/god_commands.h b/src/server/god_commands.h
deleted file mode 100644
index bfe7454..0000000
--- a/src/server/god_commands.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* src/server/god_commands.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * God commands and their interpretation by the server.
- */
-
-#ifndef GOD_COMMANDS_H
-#define GOD_COMMANDS_H
-
-#include <stdint.h> /* uint8_t */
-
-
-
-/* Parse/apply god command "tok0" with argument "tok1", "tok2" etc. . */
-extern uint8_t parse_god_command_1arg(char * tok0, char * tok1);
-extern uint8_t parse_god_command_2arg(char * tok0, char * tok1, char * tok2);
-extern uint8_t parse_god_command_3arg(char * tok0, char * tok1, char * tok2,
-                                      char * tok3);
-
-
-
-#endif
diff --git a/src/server/hardcoded_strings.c b/src/server/hardcoded_strings.c
deleted file mode 100644
index dfb30e1..0000000
--- a/src/server/hardcoded_strings.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* hardcoded_strings.c *
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "hardcoded_strings.h"
-
-
-
-char * s[44];
-
-
-
-extern void init_strings()
-{
-    s[S_PATH_CONFIG] = "confserver/world";
-    s[S_PATH_WORLDSTATE] = "server/worldstate";
-    s[S_PATH_OUT] = "server/out";
-    s[S_PATH_IN] = "server/in";
-    s[S_PATH_RECORD] = "record";
-    s[S_PATH_SAVE] = "savefile";
-    s[S_FCN_SPRINTF] = "sprintf";
-    s[S_CMD_TA_ID] = "TA_ID";
-    s[S_CMD_TA_EFFORT] = "TA_EFFORT";
-    s[S_CMD_TA_NAME] = "TA_NAME";
-    s[S_CMD_TT_ID] = "TT_ID";
-    s[S_CMD_TT_CONSUM] = "TT_CONSUMABLE";
-    s[S_CMD_TT_STARTN] = "TT_START_NUMBER";
-    s[S_CMD_TT_HP] = "TT_LIFEPOINTS";
-    s[S_CMD_TT_SYMB] = "TT_SYMBOL";
-    s[S_CMD_TT_NAME] = "TT_NAME";
-    s[S_CMD_TT_CORPS] = "TT_CORPSE_ID";
-    s[S_CMD_TT_PROL] = "TT_PROLIFERATE";
-    s[S_CMD_T_ID] = "T_ID";
-    s[S_CMD_T_TYPE] = "T_TYPE";
-    s[S_CMD_T_POSY] = "T_POSY";
-    s[S_CMD_T_POSX] = "T_POSX";
-    s[S_CMD_T_COMMAND] =  "T_COMMAND";
-    s[S_CMD_T_ARGUMENT] = "T_ARGUMENT";
-    s[S_CMD_T_PROGRESS] = "T_PROGRESS";
-    s[S_CMD_T_HP] = "T_LIFEPOINTS";
-    s[S_CMD_T_SATIATION] = "T_SATIATION";
-    s[S_CMD_T_CARRIES] = "T_CARRIES";
-    s[S_CMD_T_MEMMAP] = "T_MEMMAP";
-    s[S_CMD_T_MEMDEPTHMAP] = "T_MEMDEPTHMAP";
-    s[S_CMD_T_MEMTHING] = "T_MEMTHING";
-    s[S_CMD_AI] = "ai";
-    s[S_CMD_WAIT] = "wait";
-    s[S_CMD_MOVE] = "move";
-    s[S_CMD_PICKUP] = "pick_up";
-    s[S_CMD_DROP] = "drop";
-    s[S_CMD_USE] = "use";
-    s[S_CMD_MAKE_WORLD] = "MAKE_WORLD";
-    s[S_CMD_WORLD_ACTIVE] = "WORLD_ACTIVE";
-    s[S_CMD_SEED_MAP] = "SEED_MAP";
-    s[S_CMD_SEED_RAND] = "SEED_RANDOMNESS";
-    s[S_CMD_TURN] = "TURN";
-    s[S_CMD_MAPLENGTH] = "MAP_LENGTH";
-    s[S_CMD_PLAYTYPE] = "PLAYER_TYPE";
-}
diff --git a/src/server/hardcoded_strings.h b/src/server/hardcoded_strings.h
deleted file mode 100644
index 4725bc2..0000000
--- a/src/server/hardcoded_strings.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* hardcoded_strings.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * For re-used hardcoded strings.
- */
-
-#ifndef STRINGS_H
-#define STRINGS_H
-
-
-
-enum string_num
-{
-    S_PATH_CONFIG,
-    S_PATH_WORLDSTATE,
-    S_PATH_OUT,
-    S_PATH_IN,
-    S_PATH_RECORD,
-    S_PATH_SAVE,
-    S_FCN_SPRINTF,
-    S_CMD_TA_ID,
-    S_CMD_TA_EFFORT,
-    S_CMD_TA_NAME,
-    S_CMD_TT_ID,
-    S_CMD_TT_CONSUM,
-    S_CMD_TT_STARTN,
-    S_CMD_TT_HP,
-    S_CMD_TT_SYMB,
-    S_CMD_TT_NAME,
-    S_CMD_TT_CORPS,
-    S_CMD_TT_PROL,
-    S_CMD_T_ID,
-    S_CMD_T_TYPE,
-    S_CMD_T_POSY,
-    S_CMD_T_POSX,
-    S_CMD_T_COMMAND,
-    S_CMD_T_ARGUMENT,
-    S_CMD_T_PROGRESS,
-    S_CMD_T_HP,
-    S_CMD_T_SATIATION,
-    S_CMD_T_CARRIES,
-    S_CMD_T_MEMMAP,
-    S_CMD_T_MEMDEPTHMAP,
-    S_CMD_T_MEMTHING,
-    S_CMD_AI,
-    S_CMD_WAIT,
-    S_CMD_MOVE,
-    S_CMD_PICKUP,
-    S_CMD_DROP,
-    S_CMD_USE,
-    S_CMD_MAKE_WORLD,
-    S_CMD_WORLD_ACTIVE,
-    S_CMD_SEED_MAP,
-    S_CMD_SEED_RAND,
-    S_CMD_TURN,
-    S_CMD_MAPLENGTH,
-    S_CMD_PLAYTYPE
-};
-
-extern void init_strings();
-
-extern char * s[44];
-
-
-
-#endif
diff --git a/src/server/init.c b/src/server/init.c
deleted file mode 100644
index f44c504..0000000
--- a/src/server/init.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/* src/server/init.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#define _POSIX_C_SOURCE 2 /* getopt(), optarg */
-#include "init.h"
-#include <errno.h> /* global errno, EEXIST */
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint32_t */
-#include <stdio.h> /* FILE, sprintf(), fflush() */
-#include <stdlib.h> /* exit(), free(), atoi() */
-#include <string.h> /* strlen() */
-#include <sys/stat.h> /* mkdir() */
-#include <sys/types.h> /* defines pid_t, time_t */
-#include <time.h> /* time() */
-#include <unistd.h> /* optarg, getopt(), access(), getpid() */
-#include "../common/parse_file.h" /* err_line_zero(), err_line_inc() */
-#include "../common/readwrite.h" /* try_fopen(), try_fclose(), textfile_width(),
-                                  * try_fgets(), try_fwrite(),
-                                  * detect_atomic_leftover()
-                                  */
-#include "../common/rexit.h" /* exit_err(), exit_trouble() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* set_cleanup_flag() */
-#include "field_of_view.h" /* update_map_memory() */
-#include "hardcoded_strings.h" /* s */
-#include "map.h" /* remake_map() */
-#include "things.h" /* Thing, ThingType, free_things(), add_things(),
-                     * get_thing_id_action_id_by_name(), get_player()
-                     */
-#include "run.h" /* obey_msg(), io_loop(), record(), send_to_outfile() */
-#include "world.h" /* global world */
-
-
-
-
-/* Pass to obey_msg() lines from file at "path", on "record" write to same. Do
- * not pass lines that consist only of a newline character. Transform newline
- * in the line passed to \0.
- */
-static void obey_lines_from_file(char * path, uint8_t record);
-
-/* Replay game from record file up to the turn named in world.replay, then turn
- * over to manual replay via io_loop().
- */
-static void replay_game();
-
-/* Return 1 if the type defined by world.player_type has a .start_n of 0.
- * Return 2 if no thing action with .name of s[S_CMD_WAIT] is defined.
- * Else, return 0.
- */
-static uint8_t world_cannot_be_made();
-
-
-static void obey_lines_from_file(char * path, uint8_t record)
-{
-    FILE * file = try_fopen(path, "r", __func__);
-    uint32_t linemax = textfile_width(file);
-    char * line = try_malloc(linemax + 1, __func__);
-    while (try_fgets(line, linemax + 1, file, __func__))
-    {
-        if (strlen(line))
-        {
-            if (strcmp("\n", line))
-            {
-                char * nl = strchr(line, '\n');
-                if (nl)
-                {
-                    *nl = '\0';
-                }
-                obey_msg(line, record);
-            }
-            err_line_inc();
-        }
-    }
-    free(line);
-    try_fclose(file, __func__);
-}
-
-
-
-static void replay_game()
-{
-    exit_err(access(s[S_PATH_RECORD], F_OK), "No record found to replay.");
-    FILE * file = try_fopen(s[S_PATH_RECORD], "r", __func__);
-    uint32_t linemax = textfile_width(file);
-    char * line = try_malloc(linemax + 1, __func__);
-    while (   world.turn < world.replay
-           && try_fgets(line, linemax + 1, file, __func__))
-    {
-        obey_msg(line, 0);
-        err_line_inc();
-    }
-    uint8_t end = 0;
-    while (3 == io_loop(2))
-    {
-        if (!end)
-        {
-            end = (NULL == try_fgets(line, linemax + 1, file, __func__));
-            if (!end)
-            {
-                obey_msg(line, 0);
-                err_line_inc();
-            }
-        }
-    }
-    free(line);
-    try_fclose(file, __func__);
-}
-
-
-
-static uint8_t world_cannot_be_made()
-{
-    uint8_t player_will_be_generated = 0;
-    struct ThingType * tt;
-    for (tt = world.thing_types; tt; tt = tt->next)
-    {
-        if (world.player_type == tt->id)
-        {
-            player_will_be_generated = 0 < tt->start_n;
-            break;
-        }
-    }
-    if (!player_will_be_generated)
-    {
-        return 1;
-    }
-    if (!get_thing_action_id_by_name(s[S_CMD_WAIT]))
-    {
-        return 2;
-    }
-    return 0;
-}
-
-
-
-extern void obey_argv(int argc, char * argv[])
-{
-    int opt;
-    while (-1 != (opt = getopt(argc, argv, "vs::")))
-    {
-        if      ('v' == opt)
-        {
-            world.is_verbose = 1;
-        }
-        else if ('s' == opt)
-        {
-            world.replay = 1;
-            if (optarg)
-            {
-                world.replay = atoi(optarg);
-            }
-        }
-        else
-        {
-            exit(EXIT_FAILURE);
-        }
-    }
-}
-
-
-
-extern void setup_server_io()
-{
-    int test = mkdir("server", 0777);
-    exit_trouble(test && EEXIST != errno, __func__, "mkdir");
-    world.file_out = try_fopen(s[S_PATH_OUT], "w", __func__);
-    world.server_test = try_malloc(10 + 1 + 10 + 1 + 1, __func__);
-    test = sprintf(world.server_test, "%d %d\n", getpid(), (int) time(0));
-    exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-    try_fwrite(world.server_test, strlen(world.server_test), 1,
-               world.file_out, __func__);
-    fflush(world.file_out);
-    set_cleanup_flag(CLEANUP_OUT);
-    char * path_in = s[S_PATH_IN];
-    if (!access(path_in, F_OK))        /* This keeps out input from old input */
-    {                                  /* file streams of clients             */
-        unlink(path_in)   ;            /* communicating with server processes */
-    }                                  /* superseded by this current one.     */
-    world.file_in = try_fopen(path_in, "w", __func__);
-    try_fclose(world.file_in, __func__);
-    world.file_in = try_fopen(path_in, "r", __func__);
-    set_cleanup_flag(CLEANUP_IN);
-}
-
-
-
-extern uint8_t remake_world()
-{
-    uint8_t test = world_cannot_be_made();
-    if (test)
-    {
-        return test;
-    }
-    world.seed_map = world.seed;
-    free_things(world.things);
-    remake_map();
-    world.exists = 1;
-    struct ThingType * tt;
-    for (tt = world.thing_types; tt; tt = tt->next)
-    {
-        if (world.player_type == tt->id)
-        {
-            add_things(tt->id, tt->start_n);
-            break;
-        }
-    }
-    update_map_memory(get_player(), 1);
-    for (tt = world.thing_types; tt; tt = tt->next)
-    {
-        if (world.player_type != tt->id)
-        {
-            add_things(tt->id, tt->start_n);
-        }
-    }
-    world.turn = 1;
-    send_to_outfile("NEW_WORLD\n", 1);
-    return 0;
-}
-
-
-
-extern void run_game()
-{
-    detect_atomic_leftover(s[S_PATH_SAVE]);
-    detect_atomic_leftover(s[S_PATH_RECORD]);
-    err_line_zero();
-    if (world.replay)
-    {
-        replay_game();
-        return;
-    }
-    if (!access(s[S_PATH_SAVE], F_OK))
-    {
-        obey_lines_from_file(s[S_PATH_SAVE], 0);
-    }
-    else
-    {
-        char * err = "No world config file from which to start a new world.";
-        exit_err(access(s[S_PATH_CONFIG], F_OK), err);
-        obey_lines_from_file(s[S_PATH_CONFIG], 1);
-        err_line_zero();
-        char * command = s[S_CMD_MAKE_WORLD];
-        char * msg = try_malloc(strlen(command) + 1 + 11 + 1, __func__);
-        int test = sprintf(msg, "%s %d", command, (int) time(NULL));
-        exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-        obey_msg(msg, 1);
-        free(msg);
-    }
-    err_line_zero();
-    io_loop(1);
-    record(NULL, 1);
-}
diff --git a/src/server/init.h b/src/server/init.h
deleted file mode 100644
index 6161200..0000000
--- a/src/server/init.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* src/server/init.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Server, world and game state initialization.
- */
-
-#ifndef INIT_H
-#define INIT_H
-
-#include <stdint.h> /* uint8_t */
-
-
-
-/* Parses command line arguments -v and -s into server configuration. */
-extern void obey_argv(int argc, char * argv[]);
-
-/* Start server in file and out file, latter with server process test string. */
-extern void setup_server_io();
-
-/* Dissolves old game world if it exists, generates a new one from world.seed.
- * The map is populated according to world.thing_types start numbers. world.turn
- * is set to 1, as is .exists and .do_update, so that io_round() is told to
- * update the worldstate file. Returns 0 on success, and if the world cannot be
- * generated 1 since there is no player type or it has .n_start of 0, 2 if no
- * "wait" thing action is defined.
- */
-extern uint8_t remake_world();
-
-/* Create a game world state, then enter play or replay mode.
- *
- * If replay mode is called for, try for the record file and follow its commands
- + up to the turn specified by the user, then enter manual replay. Otherwise,
- * start into play mode after having either recreated a game world state from
- * the savefile, or, if none exists, having created a new world with first
- * following the commands from the world config file, then running the
- * MAKE_WORLD command. Manual replay as well as manual play mode take place
- * inside io_loop().
- */
-extern void run_game();
-
-
-
-#endif
diff --git a/src/server/io.c b/src/server/io.c
deleted file mode 100644
index 06ee838..0000000
--- a/src/server/io.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/* src/server/io.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#define _POSIX_C_SOURCE 200112L /* snrpintf() */
-#include "io.h"
-#include <errno.h> /* global errno */
-#include <limits.h> /* PIPE_BUF */
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, uint16_t, uint32_t, int32_t, UINT8_MAX */
-#include <stdio.h> /* defines FILE, sprintf(), fprintf() */
-#include <stdlib.h> /* free() */
-#include <string.h> /* strlen(), snprintf(), memcpy(), strchr() */
-#include <sys/types.h> /* time_t */
-#include <time.h> /* time(), nanosleep() */
-#include "../common/readwrite.h" /* atomic_write_start(), atomic_write_finish(),
-                                  * get_message_from_queue(), try_fwrite(),
-                                  * read_file_into_queue(), try_fputc()
-                                  */
-#include "../common/rexit.h" /* exit_trouble() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* set_cleanup_flag() */
-#include "hardcoded_strings.h" /* s */
-#include "map.h" /* init_empty_map() */
-#include "run.h" /* send_to_outfile() */
-#include "things.h" /* Thing, ThingType, ThingInMemory, ThingAction,
-                     * get_thing_type(), get_player()
-                     */
-#include "world.h" /* global world  */
-
-
-
-/* Helpers to write lines of god commands to recreate thing "t". */
-static void write_key_space(FILE * file, char * key);
-static void write_uvalue(FILE * file, uint32_t value);
-static void write_string(FILE * file, char * string);
-static void write_key_space_uvalue(FILE * file, char * key, uint32_t value);
-static void write_key_space_svalue(FILE * file, char * key, int32_t value);
-static void write_key_space_string(FILE * file, char * key, char * string);
-
-/* Write to "file" game-map-sized "map" in "command"-prefixed numbered lines. */
-static void write_mem_map(FILE * file, char * map, char * command);
-
-/* Write to "file" \n-delimited line of "key" + space + "value" as string. */
-static void write_thing(FILE * file, struct Thing * t);
-
-/* Poll input file for world.queue input. Wait a few seconds until giving up;
- * poll only every 0.03 seconds. Translate '\n' chars in input file into '\0'.
- */
-static void try_growing_queue();
-
-/* Write world state as visible to clients to its file. Write single dot line to
- * server output file to satisfy client ping mechanisms.
- */
-static void update_worldstate_file();
-
-/* Write "value" to new \n-delimited line of "file". */
-static void write_value_as_line(int32_t value, FILE * file);
-
-/* Write to "file" player's inventory, one item name per line. End in "%\n". */
-static void write_inventory(struct Thing * player, FILE * file);
-
-/* Return map cells sequence as visible to the "player", with invisible cells as
- * whitespace. Super-impose over visible map cells things positioned there,
- * with animate things overwriting inanimate things, and inanimate consumable
- * things overwriting inanimate non-consumable things.
- */
-static char * build_visible_map(struct Thing * player);
-
-/* Write to "file" game map as visible to "player" right now, as drawn by
- * build_visible_map(), and thereafter game map as memorized by player in its
- * .mem_map and .t_mem. Write one row per \n-delimited line.
- */
-static void write_map(struct Thing * player, FILE * file);
-
-
-
-static void write_key_space(FILE * file, char * key)
-{
-    try_fwrite(key, strlen(key), 1, file, __func__);
-    try_fputc(' ', file, __func__);
-}
-
-
-
-static void write_uvalue(FILE * file, uint32_t value)
-{
-    char * line = try_malloc(11, __func__);
-    exit_trouble(-1 == sprintf(line, "%u", value), __func__, s[S_FCN_SPRINTF]);
-    try_fwrite(line, strlen(line), 1, file, __func__);
-    free(line);
-}
-
-
-
-static void write_string(FILE * file, char * string)
-{
-    try_fputc('\'', file, __func__);
-    try_fwrite(string, strlen(string), 1, file, __func__);
-    try_fputc('\'', file, __func__);
-}
-
-
-
-static void write_key_space_uvalue(FILE * file, char * key, uint32_t value)
-{
-    write_key_space(file, key);
-    write_uvalue(file, value);
-    try_fputc('\n', file, __func__);
-}
-
-
-
-static void write_key_space_svalue(FILE * file, char * key, int32_t value)
-{
-    write_key_space(file, key);
-    char * line = try_malloc(11, __func__);
-    exit_trouble(-1 == sprintf(line, "%d", value), __func__, s[S_FCN_SPRINTF]);
-    try_fwrite(line, strlen(line), 1, file, __func__);
-    free(line);
-    try_fputc('\n', file, __func__);
-}
-
-
-
-static void write_key_space_string(FILE * file, char * key, char * string)
-{
-    write_key_space(file, key);
-    write_string(file, string);
-    try_fputc('\n', file, __func__);
-}
-
-
-
-static void write_mem_map(FILE * file, char * map, char * command)
-{
-    if (map)
-    {
-        uint32_t map_size = world.map.length * world.map.length;/* snprintf() */
-        char * map_copy = try_malloc(map_size + 1, __func__);    /* reads one */
-        memcpy(map_copy, map, map_size);              /* byte beyond map_size */
-        map_copy[map_size] = '\0';         /* if string is not \0-terminated. */
-        uint16_t y;
-        char string[UINT8_MAX + 1 + 1];
-        for (y = 0; y < world.map.length; y++)
-        {
-            int test = snprintf(string, world.map.length + 1, "%s",
-                                map_copy + (y * world.map.length));
-            exit_trouble(test < 0, __func__, "snprintf()");
-            write_key_space(file, command);
-            write_uvalue(file, y);
-            try_fputc(' ', file, __func__);
-            write_string(file, string);
-            try_fputc('\n', file, __func__);
-        }
-        free(map_copy);
-    }
-}
-
-
-
-static void write_thing(FILE * file, struct Thing * t)
-{
-    struct Thing * o;
-    for (o = t->owns; o; o = o->next)
-    {
-        write_thing(file, o);
-    }
-    write_key_space_uvalue(file, s[S_CMD_T_ID], t->id);
-    struct ThingInMemory * tm = t->t_mem;
-    for (; tm; tm = tm->next)
-    {
-        write_key_space(file, s[S_CMD_T_MEMTHING]);
-        write_uvalue(file, tm->type);
-        try_fputc(' ', file, __func__);
-        write_uvalue(file, tm->pos.y);
-        try_fputc(' ', file, __func__);
-        write_uvalue(file, tm->pos.x);
-        try_fputc('\n', file, __func__);
-    }
-    write_key_space_uvalue(file, s[S_CMD_T_COMMAND], t->command);
-    write_key_space_uvalue(file, s[S_CMD_T_HP], t->lifepoints);
-    write_key_space_uvalue(file, s[S_CMD_T_TYPE], t->type);
-    write_key_space_uvalue(file, s[S_CMD_T_ARGUMENT], t->arg);
-    write_key_space_uvalue(file, s[S_CMD_T_POSY], t->pos.y);
-    write_key_space_uvalue(file, s[S_CMD_T_POSX], t->pos.x);
-    write_key_space_uvalue(file, s[S_CMD_T_PROGRESS], t->progress);
-    write_mem_map(file, t->mem_depth_map, s[S_CMD_T_MEMDEPTHMAP]);
-    write_key_space_svalue(file, s[S_CMD_T_SATIATION], t->satiation);
-    write_mem_map(file, t->mem_map, s[S_CMD_T_MEMMAP]);
-}
-
-
-
-static void write_thing_carrying(FILE * file, struct Thing * t)
-{
-    if (t->owns)
-    {
-        write_key_space_uvalue(file, s[S_CMD_T_ID], t->id);
-        struct Thing * o;
-        for (o = t->owns; o; o = o->next)
-        {
-            write_key_space_uvalue(file, s[S_CMD_T_CARRIES], o->id);
-        }
-    }
-}
-
-
-
-static void try_growing_queue()
-{
-    uint8_t wait_seconds = 5;
-    time_t now = time(0);
-    struct timespec dur;
-    dur.tv_sec = 0;
-    dur.tv_nsec = 33333333;
-    while (1)
-    {
-        if (read_file_into_queue(world.file_in, &world.queue))
-        {
-            return;
-        }
-        nanosleep(&dur, NULL);
-        if (time(0) > now + wait_seconds)
-        {
-            return;
-        }
-    }
-}
-
-
-
-static void update_worldstate_file()
-{
-    char * path_tmp;
-    FILE * file = atomic_write_start(s[S_PATH_WORLDSTATE], &path_tmp);
-    struct Thing * player = get_player();
-    write_value_as_line(world.turn, file);
-    write_value_as_line(player->lifepoints, file);
-    write_value_as_line(player->satiation, file);
-    write_inventory(player, file);
-    write_value_as_line(player->pos.y, file);
-    write_value_as_line(player->pos.x, file);
-    write_value_as_line(world.map.length, file);
-    write_map(player, file);
-    atomic_write_finish(file, s[S_PATH_WORLDSTATE], path_tmp);
-    set_cleanup_flag(CLEANUP_WORLDSTATE);
-    char * dot = ".\n";
-    try_fwrite(dot, strlen(dot), 1, world.file_out, __func__);
-    fflush(world.file_out);
-}
-
-
-
-static void write_value_as_line(int32_t value, FILE * file)
-{
-    char write_buf[13]; /* Hold "+"/"-" + 10 digits of int32_t max + \n + \0. */
-    exit_trouble(sprintf(write_buf,"%u\n",value) < 0,__func__,s[S_FCN_SPRINTF]);
-    try_fwrite(write_buf, strlen(write_buf), 1, file, __func__);
-}
-
-
-
-static void write_inventory(struct Thing * player, FILE * file)
-{
-    struct Thing * owned = player->owns;
-    if (!owned)
-    {
-        char * empty = "(none)\n";
-        try_fwrite(empty, strlen(empty), 1, file, __func__);
-    }
-    else
-    {
-        uint8_t q;
-        for (q = 0; owned; q++)
-        {
-            struct ThingType * tt = get_thing_type(owned->type);
-            try_fwrite(tt->name, strlen(tt->name), 1, file, __func__);
-            try_fputc('\n', file, __func__);
-            owned = owned->next;
-        }
-    }
-    try_fputc('%', file, __func__);
-    try_fputc('\n', file, __func__);
-}
-
-
-
-static char * build_visible_map(struct Thing * player)
-{
-    char * visible_map;
-    init_empty_map(&visible_map);
-    if (player->fov_map) /* May fail if player thing was created / positioned */
-    {                    /* by god command after turning off FOV building.    */
-        uint32_t pos_i = 0;
-        for (; pos_i < (uint32_t) world.map.length * world.map.length; pos_i++)
-        {
-            if (player->fov_map[pos_i] == 'v')
-            {
-                visible_map[pos_i] = world.map.cells[pos_i];
-            }
-        }
-        struct Thing * t;
-        char c;
-        uint8_t i;
-        for (i = 0; i < 3; i++)
-        {
-            for (t = world.things; t != 0; t = t->next)
-            {
-                if ('v' == player->fov_map[t->pos.y*world.map.length+t->pos.x])
-                {
-                    struct ThingType * tt = get_thing_type(t->type);
-                    if (   (0 == i && !t->lifepoints && !tt->consumable)
-                        || (1 == i && !t->lifepoints &&  tt->consumable)
-                        || (2 == i &&  t->lifepoints))
-                    {
-                        c = tt->char_on_map;
-                        visible_map[t->pos.y * world.map.length + t->pos.x] = c;
-                    }
-                }
-            }
-        }
-    }
-    return visible_map;
-}
-
-
-
-static void write_map(struct Thing * player, FILE * file)
-{
-    char * visible_map = build_visible_map(player);
-    uint16_t x, y;
-    for (y = 0; y < world.map.length; y++)
-    {
-        for (x = 0; x < world.map.length; x++)
-        {
-            try_fputc(visible_map[y * world.map.length + x], file, __func__);
-        }
-        try_fputc('\n', file, __func__);
-    }
-    free(visible_map);
-    uint32_t map_size = world.map.length * world.map.length;
-    char * mem_map = try_malloc(map_size, __func__);
-    memcpy(mem_map, player->mem_map, map_size);
-    uint8_t i;
-    struct ThingInMemory * tm;
-    for (i = 0; i < 2; i++)
-    {
-        for (tm = player->t_mem; tm; tm = tm->next)
-        {
-            if (' ' != player->mem_map[tm->pos.y*world.map.length+tm->pos.x])
-            {
-                struct ThingType * tt = get_thing_type(tm->type);
-                if (   (0 == i && !tt->consumable)
-                    || (1 == i &&  tt->consumable))
-                {
-                    char c = tt->char_on_map;
-                    mem_map[tm->pos.y * world.map.length + tm->pos.x] = c;
-                }
-            }
-        }
-    }
-    for (y = 0; y < world.map.length; y++)
-    {
-        for (x = 0; x < world.map.length; x++)
-        {
-            try_fputc(mem_map[y * world.map.length + x], file, __func__);
-        }
-        try_fputc('\n', file, __func__);
-    }
-    free(mem_map);
-}
-
-
-
-extern char * io_round()
-{
-    if (world.queue && strlen(world.queue))
-    {
-        return get_message_from_queue(&world.queue);
-    }
-    if (world.do_update)
-    {
-        update_worldstate_file();
-        send_to_outfile("WORLD_UPDATED\n", 1);
-        world.do_update = 0;
-    }
-    try_growing_queue();
-    return get_message_from_queue(&world.queue);
-}
-
-
-
-extern void save_world()
-{
-    char * path_tmp;
-    FILE * file = atomic_write_start(s[S_PATH_SAVE], &path_tmp);
-    write_key_space_uvalue(file, s[S_CMD_TURN], world.turn);
-    write_key_space_uvalue(file, s[S_CMD_PLAYTYPE], world.player_type);
-    write_key_space_uvalue(file, s[S_CMD_MAPLENGTH], world.map.length);
-    write_key_space_uvalue(file, s[S_CMD_SEED_MAP], world.seed_map);
-    struct ThingAction * ta;
-    for (ta = world.thing_actions; ta; ta = ta->next)
-    {
-        write_key_space_uvalue(file, s[S_CMD_TA_ID], ta->id);
-        write_key_space_uvalue(file, s[S_CMD_TA_EFFORT], ta->effort);
-        write_key_space_string(file, s[S_CMD_TA_NAME], ta->name);
-    }
-    struct ThingType * tt;
-    for (tt = world.thing_types; tt; tt = tt->next)
-    {
-        write_key_space_uvalue(file, s[S_CMD_TT_ID], tt->id);
-        write_key_space_uvalue(file, s[S_CMD_TT_STARTN], tt->start_n);
-        int test = fprintf(file, "%s '%c'\n", s[S_CMD_TT_SYMB], tt->char_on_map);
-        exit_trouble(test < 0, __func__, "fprintf");
-        write_key_space_string(file, s[S_CMD_TT_NAME], tt->name);
-        write_key_space_uvalue(file, s[S_CMD_TT_PROL], tt->proliferate);
-        write_key_space_uvalue(file, s[S_CMD_TT_HP], tt->lifepoints);
-        write_key_space_uvalue(file, s[S_CMD_TT_CONSUM], tt->consumable);
-    }
-    for (tt = world.thing_types; tt; tt = tt->next)
-    {
-        write_key_space_uvalue(file, s[S_CMD_TT_ID], tt->id);
-        write_key_space_uvalue(file, s[S_CMD_TT_CORPS], tt->corpse_id);
-    }
-    struct Thing * t;
-    for (t = world.things; t; t = t->next)
-    {
-        write_thing(file, t);
-    }
-    for (t = world.things; t; t = t->next)
-    {
-        write_thing_carrying(file, t);
-    }
-    write_key_space_uvalue(file, s[S_CMD_SEED_RAND], world.seed);
-    write_key_space_uvalue(file, s[S_CMD_WORLD_ACTIVE], 1);
-    atomic_write_finish(file, s[S_PATH_SAVE], path_tmp);
-}
diff --git a/src/server/io.h b/src/server/io.h
deleted file mode 100644
index 7c9148d..0000000
--- a/src/server/io.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* io.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Communication of the server with the outside world and its client via input,
- * output and world state files.
- */
-
-#ifndef IO_H
-#define IO_H
-
-
-
-/* Return single \0-terminated string read from input queue (world.queue); or,
- * if queue is empty and world.do_update is set, update world state file (and
- * unset world.do_update) and write a single dot line to server out file, then
- * read server in file for the next load of bytes to put onto the input queue.
- * (Queueing ensures only complete messages are interpreted.)
- */
-extern char * io_round();
-
-/* Write to savefile (atomically) god commands (one per line) to rebuild the
- * current world state.
- */
-extern void save_world();
-
-
-
-#endif
diff --git a/src/server/main.c b/src/server/main.c
deleted file mode 100644
index 1ae00f1..0000000
--- a/src/server/main.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* src/server/main.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include <stdio.h> /* printf() */
-#include <stdlib.h> /* exit() */
-#include "../common/rexit.h" /* exit_err, set_cleanup_func() */
-#include "cleanup.h" /* set_cleanup_flag(), cleanup() */
-#include "hardcoded_strings.h" /* s */
-#include "init.h" /* run_game(), obey_argv(), obey_argv(), setup_server_io() */
-#include "world.h" /* struct World */
-
-
-
-struct World world;
-
-
-
-int main(int argc, char ** argv)
-{
-    /* So error exits also go through the server's cleanup() function. */
-    set_cleanup_func(cleanup);
-
-    /* Init settings from command line / hard-coded values. Print start info. */
-    init_strings();
-    obey_argv(argc, argv);
-    if (world.is_verbose)
-    {
-        char * printf_err = "Trouble in main() with printf().";
-        int test = printf("Starting plomrogue-server.\n");
-        exit_err(-1 == test, printf_err);
-        if (world.replay)
-        {
-            test = printf("Replay mode. Auto-replaying up to turn %d.\n",
-                          world.replay);
-            exit_err(-1 == test, printf_err);
-        }
-    }
-    world.map.length = 64;                      /* Just a sane default value. */
-
-    /* Init server i/o, Enter play or replay mode loops, then leave properly. */
-    setup_server_io();
-    run_game();
-    cleanup();
-    exit(EXIT_SUCCESS);
-}
diff --git a/src/server/map.c b/src/server/map.c
deleted file mode 100644
index 3a5a0a2..0000000
--- a/src/server/map.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* src/server/map.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "map.h"
-#include <stdint.h> /* uint8_t, int8_t, uint16_t, uint32_t, (U)INT*_(MIN|MAX) */
-#include <stdlib.h> /* free() */
-#include <string.h> /* memset() */
-#include "../common/rexit.h" /* exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* yx_uint8 */
-#include "rrand.h" /* rrand() */
-#include "world.h" /* global world */
-
-
-
-/* Helper to mv_yx_in_dir_legal(). Move "yx" into hex direction "d". */
-static void mv_yx_in_dir(char d, struct yx_uint8 * yx);
-
-/* Call this too often with "init" of 0 and the game exits with an error message
- * about reaching an iteration limit. An "init" of 1 sets the iteration counter
- * to 0. Iteration limit is currently 256 * UINT16_MAX.
- */
-static uint8_t iter_limit(uint8_t init);
-
-/* Return 1 if cell on "pos" is neighbor to a cell of "type", else return 0. */
-static uint8_t is_neighbor(struct yx_uint8 pos, char type);
-
-/* Fill map with '~' cells. */
-static void make_sea();
-
-/* Put island of '.' cells inside map sea. */
-static void make_sea();
-
-/* Put tree cells of 'X' on island. */
-static void make_trees();
-
-
-
-static void mv_yx_in_dir(char d, struct yx_uint8 * yx)
-{
-    if      (d == 'e')
-    {
-        yx->x = yx->x + (yx->y % 2);
-        yx->y--;
-    }
-    else if (d == 'd')
-    {
-        yx->x++;
-    }
-    else if (d == 'c')
-    {
-        yx->x = yx->x + (yx->y % 2);
-        yx->y++;
-    }
-    else if (d == 'x')
-    {
-        yx->x = yx->x - !(yx->y % 2);
-        yx->y++;
-    }
-    else if (d == 's')
-    {
-        yx->x--;
-    }
-    else if (d == 'w')
-    {
-        yx->x = yx->x - !(yx->y % 2);
-        yx->y--;
-    }
-}
-
-
-
-static uint8_t iter_limit(uint8_t init)
-{
-    static uint32_t i = 0;
-    char * err = "Map generation reached iteration limit. Change map size?";
-    if (init)
-    {
-        i = 0;
-        return 0;
-    }
-    i++;
-    exit_err(256 * UINT16_MAX == i, err);
-    return 1;
-}
-
-
-
-static uint8_t is_neighbor(struct yx_uint8 pos, char type)
-{
-    uint8_t ind = pos.y % 2;
-    uint8_t diag_west = pos.x + ind > 0;
-    uint8_t diag_east = pos.x + ind <= world.map.length - 1;
-    uint16_t pos_i = (pos.y * world.map.length) + pos.x;
-    if (   (   pos.y > 0                    && diag_east
-            && type == world.map.cells[pos_i - world.map.length + ind])
-        || (   pos.x < world.map.length - 1
-            && type == world.map.cells[pos_i + 1])
-        || (   pos.y < world.map.length - 1 && diag_east
-            && type == world.map.cells[pos_i + world.map.length + ind])
-        || (   pos.y > 0                    && diag_west
-            && type == world.map.cells[pos_i - world.map.length - !ind])
-        || (   pos.x > 0
-            && type == world.map.cells[pos_i - 1])
-        || (   pos.y < world.map.length - 1 && diag_west
-            && type == world.map.cells[pos_i + world.map.length - !ind]))
-    {
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static void make_sea()
-{
-    uint16_t y, x;
-    for (y = 0; y < world.map.length; y++)
-    {
-        for (x = 0;
-             x < world.map.length;
-             world.map.cells[(y * world.map.length) + x] = '~', x++);
-    }
-}
-
-
-
-static void make_island()
-{
-    char type = '.';
-    uint8_t add_half_width = !(world.map.length % 2) * (world.map.length / 2);
-    uint32_t size = world.map.length * world.map.length;
-    world.map.cells[(size / 2) + add_half_width] = type;
-    struct yx_uint8 pos;
-    iter_limit(1);
-    while (iter_limit(0))
-    {
-        pos.y = rrand() % world.map.length;
-        pos.x = rrand() % world.map.length;
-        uint16_t pos_i = (pos.y * world.map.length) + pos.x;
-        if ('~' == world.map.cells[pos_i] && is_neighbor(pos, type))
-        {
-            if (   pos.y == 0 || pos.y == world.map.length - 1
-                || pos.x == 0 || pos.x == world.map.length - 1)
-            {
-                break;
-            }
-            world.map.cells[pos_i] = type;
-        }
-    }
-}
-
-
-
-static void make_trees()
-{
-    char type = 'X';
-    struct yx_uint8 pos;
-    uint16_t n_trees = (world.map.length * world.map.length) / 16;
-    uint16_t i_trees = 0;
-    iter_limit(1);
-    while (i_trees <= n_trees && iter_limit(0))
-    {
-        uint8_t single_allowed = rrand() % 32;
-        pos.y = rrand() % world.map.length;
-        pos.x = rrand() % world.map.length;
-        uint16_t pos_i = (pos.y * world.map.length) + pos.x;
-        if ('.' == world.map.cells[pos_i]
-            && (!single_allowed || is_neighbor(pos, type)))
-        {
-            world.map.cells[pos_i] = type;
-            i_trees++;
-        }
-    }
-}
-
-
-
-extern void remake_map()
-{
-    free(world.map.cells);
-    world.map.cells = try_malloc(world.map.length * world.map.length, __func__);
-    uint32_t store_seed = world.seed;
-    world.seed = world.seed_map;
-    make_sea();
-    make_island();
-    make_trees();
-    world.seed = store_seed;
-}
-
-
-
-extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx)
-{
-    static int8_t wrap_west_east   = 0;
-    static int8_t wrap_north_south = 0;
-    if (!yx)
-    {
-        wrap_west_east = wrap_north_south = 0;
-        return 0;
-    }
-    char * err = "Too much wrapping in mv_yx_in_dir_legal().";
-    exit_err(   INT8_MIN == wrap_west_east || INT8_MIN == wrap_north_south
-             || INT8_MAX == wrap_west_east || INT8_MAX == wrap_north_south,err);
-    struct yx_uint8 original = *yx;
-    mv_yx_in_dir(dir, yx);
-    if      (('e' == dir || 'd' == dir || 'c' == dir) && yx->x < original.x)
-    {
-        wrap_west_east++;
-    }
-    else if (('x' == dir || 's' == dir || 'w' == dir) && yx->x > original.x)
-    {
-        wrap_west_east--;
-    }
-    if      (('w' == dir || 'e' == dir)               && yx->y > original.y)
-    {
-        wrap_north_south--;
-    }
-    else if (('x' == dir || 'c' == dir)               && yx->y < original.y)
-    {
-        wrap_north_south++;
-    }
-    if (   !wrap_west_east && !wrap_north_south
-        && yx->x < world.map.length && yx->y < world.map.length)
-    {
-        return 1;
-    }
-    return 0;
-}
-
-
-
-extern void init_empty_map(char ** map)
-{
-    *map = try_malloc(world.map.length * world.map.length, __func__);
-    memset(*map, ' ', world.map.length * world.map.length);
-}
diff --git a/src/server/map.h b/src/server/map.h
deleted file mode 100644
index d9ebf74..0000000
--- a/src/server/map.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* src/server/map.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Routines to create and navigate game map.
- */
-
-#ifndef MAP_H_SERVER
-#define MAP_H_SERVER
-
-#include <stdint.h> /* uint8_t */
-struct yx_uint8;
-
-
-
-/* (Re-)make island map "~" cells representing water and "." cells representing
- * land. The island shape is built randomly from world.seed_map by starting with
- * a sea of one land cell in the middle, then going into a cycle of repeatedly
- * selecting a random sea cell and transforming it into land if it is neighbor
- * to land; the cycle ends when a land cell is due to be created right at the
- * border of the map. Lots of 'X' cells representing trees are put on the
- * island.
- */
-extern void remake_map();
-
-/* Move "yx" into hex direction "dir". Available hex directions are: 'e'
- * (north-east), 'd' (east), 'c' (south-east), 'x' (south-west), 's' (west), 'w'
- * (north-west). Returns 1 if the move was legal, else 0.
- *
- * A move is legal if "yx" ends up in the confines of the map and the original
- * wrap space. The latter is left to a neighbor wrap space if "yx" moves beyond
- * the minimal (0) or maximal (UINT8_MAX) column or row of possible map space –
- * in which case "yx".y or "yx".x will snap to the respective opposite side. The
- * current wrapping state is kept between successive calls until a "yx" of NULL
- * is passed, in which case the function does nothing but zero the wrap state.
- * Successive wrapping may move "yx" several wrap spaces into either direction,
- * or return it into the original wrap space.
- */
-extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx);
-
-/* Initialize (empty) map array at "map". */
-extern void init_empty_map(char ** map);
-
-
-#endif
diff --git a/src/server/rrand.c b/src/server/rrand.c
deleted file mode 100644
index 034b0e8..0000000
--- a/src/server/rrand.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* src/server/rrand.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "rrand.h"
-#include <stdint.h> /* uint16_t */
-#include "world.h" /* global world */
-
-
-
-extern uint16_t rrand()
-{   /* Constants as recommended by POSIX.1-2001 (see man page rand(3)). */
-    world.seed = ((world.seed * 1103515245) + 12345) % 4294967296;
-    return (world.seed >> 16); /* Ignore less random least significant bits. */
-}
diff --git a/src/server/rrand.h b/src/server/rrand.h
deleted file mode 100644
index 74f12fd..0000000
--- a/src/server/rrand.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* src/server/rrand.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Provides deterministic pseudo-randomness.
- */
-
-#ifndef RRAND_H
-#define RRAND_H
-
-#include <stdint.h> /* uint16_t */
-
-
-
-/* Return 16-bit number pseudo-randomly generated via Linear Congruential
- * Generator algorithm with some proven constants. Use instead of rand() to
- * ensure portability of the same pseudo-randomness across systems.
- */
-extern uint16_t rrand();
-
-
-
-#endif
diff --git a/src/server/run.c b/src/server/run.c
deleted file mode 100644
index ad04f71..0000000
--- a/src/server/run.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* src/server/run.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#define _POSIX_C_SOURCE 200809L /* strdup() */
-#include "run.h"
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, uint16_t, uint32_t, int16_t */
-#include <stdio.h> /* FILE, printf(), fflush() */
-#include <stdlib.h> /* atoi(), free() */
-#include <string.h> /* strlen(), strcmp(), strncmp(), strdup() */
-#include <time.h> /* time_t, time() */
-#include <unistd.h> /* access() */
-#include "../common/parse_file.h" /* set_err_line_options(), token_from_line(),
-                                   * err_line(), err_line_inc(), parse_val(),
-                                   * parestest_int()
-                                   */
-#include "../common/readwrite.h" /* try_fopen(), try_fcose(), try_fwrite(),
-                                  * try_fgets(), textfile_width(), try_fputc(),
-                                  * atomic_write_finish(), build_temp_path()
-                                  */
-#include "../common/rexit.h" /* exit_trouble(), exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "ai.h" /* ai() */
-#include "cleanup.h" /* unset_cleanup_flag() */
-#include "field_of_view.h" /* update_map_memory() */
-#include "god_commands.h" /* parse_god_command_(1|2|3)arg() */
-#include "hardcoded_strings.h" /* s */
-#include "io.h" /* io_round(), save_world() */
-#include "thing_actions.h" /* hunger(), try_healing() */
-#include "things.h" /* Thing, ThingType, ThingInMemory, get_player(),
-                     * get_thing_action_id_by_name(), try_thing_proliferation()
-                     */
-#include "world.h" /* world */
-
-
-
-/* If "string" and "comparand" match in string, set "c_to_set" to value."  */
-static uint8_t set_char_by_string_comparison(char * string, char * comparand,
-                                             char * c_to_set, char value);
-
-/* Return 1 on world.exists, else 0 and err_line() appropriate error message. */
-static uint8_t player_commands_allowed();
-
-/* Parse player commands "tok0" with optional argument "tok1" to player action.
- * Return 1 on success, 0 on failure.
- */
-static uint8_t parse_player_command_0arg(char * tok0);
-static uint8_t parse_player_command_1arg(char * tok0, char * tok1);
-
-/* Parse/apply (non-)meta command "tok0" (read further tokens as necessary).
- * Return 0 on failure, 1 on success, 2 on QUIT meta command.
- */
-static uint8_t parse_command_nonmeta(char * tok0);
-static uint8_t parse_command_meta(char * tok0);
-
-/* Compare 1st line of server out file to world.server_test, abort if they don't
- * match, but not before unsetting flags deleting files in the server directory,
- * for in that case those must be assumed to belong to another server process.
- */
-static void server_test();
-
-/* Return array of IDs of non-owned things in game world, ended by non-ID -1. */
-static int16_t * build_whitelist();
-
-/* Return 1 if value of "id" appears in "whitelist", else 0. */
-static uint8_t thing_in_whitelist(uint8_t id, int16_t * whitelist);
-
-/* Run the game world and its inhabitants (and their actions) until the player
- * avatar is free to receive new commands (or is dead). Only actions and
- * proliferations for non-owned things are performed that exist at the start of
- * the turn jumped into, or started anew by the cycle.
- */
-static void turn_over();
-
-
-
-static uint8_t set_char_by_string_comparison(char * string, char * comparand,
-                                             char * c_to_set, char value)
-{
-    if (!strcmp(string, comparand))
-    {
-        * c_to_set = value;
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t player_commands_allowed()
-{
-    if (!world.exists)
-    {
-        return !err_line(1, "No world exists in which to run player commands.");
-    }
-    return 1;
-}
-
-
-
-static uint8_t parse_player_command_0arg(char * tok0)
-{
-    struct Thing * player = get_player();
-    if (   !strcmp(tok0, s[S_CMD_WAIT]) || !strcmp(tok0, s[S_CMD_PICKUP])
-        || !strcmp(tok0, s[S_CMD_AI]))
-    {
-        if (player_commands_allowed())
-        {
-            if (!strcmp(tok0, s[S_CMD_AI]))
-            {
-                ai(player);
-            }
-            else
-            {
-                player->command = get_thing_action_id_by_name(tok0);
-            }
-            turn_over();
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_player_command_1arg(char * tok0, char * tok1)
-{
-    struct Thing * player = get_player();
-    if (   (   parse_val(tok0, tok1, s[S_CMD_DROP], '8', (char *) &player->arg)
-            || parse_val(tok0, tok1, s[S_CMD_USE], '8', (char *) &player->arg))
-        && player_commands_allowed())
-    {
-        player->command = get_thing_action_id_by_name(tok0);
-        turn_over();
-    }
-    else if (!strcmp(tok0, s[S_CMD_MOVE]) && player_commands_allowed())
-    {
-        char dir = '\0';
-        if (!(   set_char_by_string_comparison(tok1, "east",       &dir, 'd')
-              || set_char_by_string_comparison(tok1, "south-east", &dir, 'c')
-              || set_char_by_string_comparison(tok1, "south-west", &dir, 'x')
-              || set_char_by_string_comparison(tok1, "west",       &dir, 's')
-              || set_char_by_string_comparison(tok1, "north-west", &dir, 'w')
-              || set_char_by_string_comparison(tok1, "north-east", &dir, 'e')))
-        {
-            return 0;
-        }
-        player->arg = dir;
-        player->command = get_thing_action_id_by_name(tok0);
-        turn_over();
-    }
-    else
-    {
-        return 0;
-    }
-    return 1;
-}
-
-
-
-static uint8_t parse_command_nonmeta(char * tok0)
-{
-    if (parse_player_command_0arg(tok0))
-    {
-        return 1;
-    }
-    else
-    {
-        char * tok1 = token_from_line(NULL);
-        if (tok1 && (   parse_player_command_1arg(tok0, tok1)
-                     || parse_god_command_1arg(tok0, tok1)))
-        {
-            return 1;
-        }
-        else
-        {
-            char * tok2 = token_from_line(NULL);
-            if (tok2 && parse_god_command_2arg(tok0, tok1, tok2))
-            {
-                return 1;
-            }
-            else
-            {
-                char * tok3 = token_from_line(NULL);
-                if (tok2 && parse_god_command_3arg(tok0, tok1, tok2, tok3))
-                {
-                    return 1;
-                }
-            }
-        }
-    }
-    return 0;
-}
-
-
-
-static uint8_t parse_command_meta(char * tok0)
-{
-    if (!strcmp("QUIT", tok0))
-    {
-        return 2;
-    }
-    if (!strcmp("PING", tok0))
-    {
-        send_to_outfile("PONG\n", 1);
-        return 1;
-    }
-    if (!strcmp("THINGS_HERE", tok0))
-    {
-        char * tok1 = token_from_line(NULL);
-        char * tok2 = token_from_line(NULL);
-        if (tok1&&tok2 && !parsetest_int(tok1, '8')&&!parsetest_int(tok2, '8'))
-        {
-            if (!world.exists)
-            {
-                err_line(1, "Command only works on existing worlds.");
-                return 0;
-            }
-            send_to_outfile("THINGS_HERE START\n", 1);
-            struct Thing * player = get_player();
-            if (player->fov_map &&
-                'v' == player->fov_map[atoi(tok1)*world.map.length+atoi(tok2)])
-            {
-                struct Thing * t;
-                for (t = world.things; t; t = t->next)
-                {
-                    if (t->pos.y == atoi(tok1) && t->pos.x == atoi(tok2))
-                    {
-                        struct ThingType * tt = get_thing_type(t->type);
-                        send_to_outfile(tt->name, 0);
-                        send_to_outfile("\n", 1);
-                    }
-                }
-            }
-            else
-            {
-                struct ThingInMemory * t_mem;
-                for (t_mem = player->t_mem; t_mem; t_mem = t_mem->next)
-                {
-                    if (t_mem->pos.y == atoi(tok1) && t_mem->pos.x == atoi(tok2))
-                    {
-                        struct ThingType * tt = get_thing_type(t_mem->type);
-                        send_to_outfile(tt->name, 0);
-                        send_to_outfile("\n", 1);
-                    }
-                }
-            }
-            send_to_outfile("THINGS_HERE END\n", 1);
-            return 1;
-        }
-    }
-    return 0;
-}
-
-
-
-static void server_test()
-{
-    char test[10 + 1 + 10 + 1 + 1];
-    FILE * file = try_fopen(s[S_PATH_OUT], "r", __func__);
-    try_fgets(test, 10 + 10 + 1 + 1, file, __func__);
-    try_fclose(file, __func__);
-    if (strcmp(test, world.server_test))
-    {
-        unset_cleanup_flag(CLEANUP_WORLDSTATE);
-        unset_cleanup_flag(CLEANUP_OUT);
-        unset_cleanup_flag(CLEANUP_IN);
-        char * msg = "Server test string in server output file does not match. "
-                     "This indicates that the current server process has been "
-                     "superseded by another one.";
-        exit_err(1, msg);
-    }
-}
-
-
-
-static int16_t * build_whitelist()
-{
-    uint16_t i_things = NULL != world.things;
-    struct Thing * t = world.things;
-    for (; t; t = t->next, i_things++);
-    int16_t * whitelist = try_malloc(i_things * sizeof(int16_t), __func__);
-    for (i_things = 0, t = world.things; t;
-         whitelist[i_things] = t->id, t = t->next, i_things++);
-    whitelist[i_things] = -1;
-    return whitelist;
-}
-
-
-
-static uint8_t thing_in_whitelist(uint8_t id, int16_t * whitelist)
-{
-    uint16_t i;
-    for (i = 0; -1 < whitelist[i]; i++)
-    {
-        if ((int16_t) id == whitelist[i])
-        {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-
-
-static void turn_over()
-{
-    struct Thing * player = get_player();
-    struct Thing * thing = player;
-    int16_t * whitelist = build_whitelist();
-    while (0 < player->lifepoints)
-    {
-        if (!thing)
-        {
-            world.turn++;
-            thing = world.things;
-            free(whitelist);
-            whitelist = build_whitelist();/* The whitelist excludes things    */
-        }                                 /* that appear only during the turn.*/
-        if (thing_in_whitelist(thing->id, whitelist))
-        {
-            if (0 < thing->lifepoints)
-            {
-                if (0 == thing->command)
-                {
-                    update_map_memory(thing, 1);
-                    if (thing == player)
-                    {
-                        break;
-                    }
-                    ai(thing);
-                }
-                try_healing(thing);
-                thing->progress++;
-                struct ThingAction * ta = get_thing_action(thing->command);
-                if (thing->progress == ta->effort)
-                {
-                    ta->func(thing);
-                    thing->command = 0;
-                    thing->progress = 0;
-                }
-                hunger(thing);
-            }
-            try_thing_proliferation(thing);
-        }
-        thing = thing->next;
-    }
-    free(whitelist);
-}
-
-
-
-extern void send_to_outfile(char * answer, uint8_t flush)
-{
-    try_fwrite(answer, strlen(answer), 1, world.file_out, __func__);
-    if (flush)
-    {
-        fflush(world.file_out);
-    }
-}
-
-
-
-extern void record(char * msg, uint8_t force)
-{
-    static FILE * file_tmp = NULL;
-    static time_t save_wait = 0;
-    static char * path_tmp;
-    if (!file_tmp)
-    {
-        path_tmp = build_temp_path(s[S_PATH_RECORD]);
-        file_tmp = try_fopen(path_tmp, "w", __func__);
-        if (!access(s[S_PATH_RECORD], F_OK))
-        {
-            FILE * file_read = try_fopen(s[S_PATH_RECORD], "r", __func__);
-            uint32_t linemax = textfile_width(file_read);
-            char * line = try_malloc(linemax + 1, __func__);
-            while (try_fgets(line, linemax + 1, file_read, __func__))
-            {
-                try_fwrite(line, strlen(line), 1, file_tmp, __func__);
-            }
-            free(line);
-            try_fclose(file_read, __func__);
-        }
-    }
-    if (msg)
-    {
-        try_fwrite(msg, strlen(msg), 1, file_tmp, __func__);
-        try_fputc('\n', file_tmp, __func__);
-    }
-    if (force || time(NULL) > save_wait + 15)
-    {
-        save_wait = time(NULL);
-        save_world();
-        atomic_write_finish(file_tmp, s[S_PATH_RECORD], path_tmp);
-        file_tmp = NULL;
-    }
-}
-
-
-
-extern uint8_t obey_msg(char * msg, uint8_t obey_state)
-{
-    if (world.is_verbose)
-    {
-        exit_trouble(-1 == printf("Input: %s\n", msg), __func__, "printf");
-    }
-    set_err_line_options("Trouble with message: ", msg, 0);
-    char * msg_copy = strdup(msg);
-    char * tok0 = token_from_line(msg_copy);
-    uint8_t ret = 0;
-    if (tok0)
-    {
-        ret = parse_command_meta(tok0);
-        if (ret || (obey_state < 2 && parse_command_nonmeta(tok0)))
-        {
-            if (!ret)
-            {
-                if (world.exists)
-                {
-                    world.do_update = 1;
-                }
-                if (1 == obey_state)
-                {
-                   record(msg, 0);
-                }
-            }
-            char * tokplus = token_from_line(NULL);
-            err_line(!(!tokplus), "Too many arguments, ignoring overflow.");
-        }
-        else if (world.replay)
-        {
-            ret = 3;
-        }
-        else if (!world.replay)
-        {
-            err_line(1, "Invalid command/argument or bad number of tokens.");
-        }
-    }
-    free(msg_copy);
-    return ret;
-}
-
-
-
-extern uint8_t io_loop(uint8_t obey_state)
-{
-    while (1)
-    {
-        char * msg = io_round();
-        server_test();
-        if (msg)
-        {
-            uint8_t ret = obey_msg(msg, obey_state);
-            free(msg);
-            if (   (!world.replay && 2 == ret)
-                || ( world.replay && 2 <= ret))
-            {
-                return ret;
-            }
-        }
-    }
-}
diff --git a/src/server/run.h b/src/server/run.h
deleted file mode 100644
index 414df1b..0000000
--- a/src/server/run.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* src/server/run.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Process commands and act on them. Stuff that furthers the state of the game.
- */
-
-#ifndef RUN_H
-#define RUN_H
-
-#include <stdint.h> /* uint8_t */
-
-
-
-/* Append "answer" to server output file, with instant fflush() if "flush". */
-extern void send_to_outfile(char * answer, uint8_t flush);
-
-/* Record save and record file data. Both are only written if "force" is set, or
- * on the first run with unset "force", or if 15 seconds have passed since the
- * last file writing. "msg" is appended to the record file if it is set.
- */
-extern void record(char * msg, uint8_t force);
-
-/* Try parsing "msg" into a command to apply. Output "msg" if world.is_verbose.
- * If "obey_state" is > 1 and world.replay is set, any non-meta command message
- * is not executed, but merely returns 3. The QUIT meta command (if well-formed)
- * always returns 2. Other meta commands and (with "obey_state" < 2) non-meta
- * commands return 1 if well-formed. Malformed or empty command messages return
- * 0. If "obey_state" is 1, "msg" is recorded via a non-forced record(). If a
- * non-meta command is executed and world.exists, world.do_update is set.
- */
-extern uint8_t obey_msg(char * msg, uint8_t obey_state);
-
-/* Loop to read commands via io_round() and call obey_msg() with "obey_state"
- * set on them. If latter returns 2 and world.replay is not set, or returns > 1
- * and world.replay is set, abort loop to return that result. After io_round(),
- * compares 1st line of the server out file is compared with world.server_test
- * to ensure the server process hasn't been superseded by a new one.
- */
-extern uint8_t io_loop(uint8_t obey_state);
-
-
-
-#endif
diff --git a/src/server/thing_actions.c b/src/server/thing_actions.c
deleted file mode 100644
index 6a8803d..0000000
--- a/src/server/thing_actions.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/* src/server/thing_actions.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#include "thing_actions.h"
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, INT16_MIN, INT16_MAX */
-#include <stdio.h> /* sprintf() */
-#include <stdlib.h> /* free() */
-#include <string.h> /* strlen() */
-#include "../common/rexit.h" /* exit_err(), exit_trouble() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* yx_uint8 */
-#include "field_of_view.h" /* build_fov_map() */
-#include "hardcoded_strings.h" /* s */
-#include "things.h" /* Thing, ThingType, get_player(), free_things_in_memory(),
-                     * own_thing(), set_thing_position(), get_thing_type(),
-                     */
-#include "map.h" /* mv_yx_in_dir_legal() */
-#include "rrand.h" /* rrand() */
-#include "run.h" /* send_to_outfile() */
-#include "world.h" /* global world */
-
-
-
-/* Send "text" as log message to server out file. */
-static void update_log(char * text);
-
-/* Decrement "t"'s lifepoints, and if to zero, kill it with log update. */
-static void decrement_lifepoints(struct Thing * t);
-
-/* One actor "wounds" another actor, decrementing his lifepoints. */
-static void actor_hits_actor(struct Thing * hitter, struct Thing * hitted);
-
-/* Bonus stuff to actor_*() to happen if actor==player. Mostly writing of log
- * messages; _pick and _drop also decrement world.inventory_sel by 1 if >0.
- * (match_dir() is just a little helper to playerbonus_move().)
- */
-static void playerbonus_wait();
-static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match);
-static void playerbonus_move(char d, uint8_t passable);
-static void playerbonus_drop(uint8_t owns_none);
-static void playerbonus_pick(uint8_t picked);
-static void playerbonus_use(uint8_t no_thing, uint8_t wrong_thing);
-
-
-
-static void update_log(char * text)
-{
-    send_to_outfile("LOG ", 0);
-    send_to_outfile(text, 0);
-    send_to_outfile("\n", 1);
-}
-
-
-
-static void decrement_lifepoints(struct Thing * t)
-{
-    struct Thing * player = get_player();
-    t->lifepoints--;
-    if (0 == t->lifepoints)
-    {
-        t->type = get_thing_type(t->type)->corpse_id;
-        if (player == t)
-        {
-            update_log("You die.");
-            memset(t->fov_map, ' ', world.map.length * world.map.length);
-            return;
-        }
-        else
-        {
-            free(t->fov_map);
-            t->fov_map = NULL;
-            free(t->mem_map);
-            t->mem_map = NULL;
-            free(t->mem_depth_map);
-            t->mem_depth_map = NULL;
-            free_things_in_memory(t->t_mem);
-            t->t_mem = NULL;
-        }
-        update_log("It dies.");
-    }
-}
-
-
-
-static void actor_hits_actor(struct Thing * hitter, struct Thing * hitted)
-{
-    struct ThingType * tt_hitter = get_thing_type(hitter->type);
-    struct ThingType * tt_hitted = get_thing_type(hitted->type);
-    struct Thing * player = get_player();
-    char * msg1 = "You";
-    char * msg2 = "wound";
-    char * msg3 = "you";
-    if      (player != hitter)
-    {
-        msg1 = tt_hitter->name;
-        msg2 = "wounds";
-    }
-    if (player != hitted)
-    {
-        msg3 = tt_hitted->name;
-    }
-    uint8_t len = strlen(msg1) + 1 + strlen(msg2) + 1 + strlen(msg3) + 2;
-    char * msg = try_malloc(len, __func__);
-    int test = sprintf(msg, "%s %s %s.", msg1, msg2, msg3);
-    exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-    update_log(msg);
-    free(msg);
-    decrement_lifepoints(hitted);
-}
-
-
-
-static void playerbonus_wait()
-{
-        update_log("You wait.");
-}
-
-
-
-static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match)
-{
-    if (d == match)
-    {
-        * dsc_d = dsc_match;
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static void playerbonus_move(char d, uint8_t passable)
-{
-    char * dsc_dir = "north-east";
-    if (   match_dir(d, &dsc_dir, 'd', "east")
-        || match_dir(d, &dsc_dir, 'c', "south-east")
-        || match_dir(d, &dsc_dir, 'x', "south-west")
-        || match_dir(d, &dsc_dir, 's', "west")
-        || match_dir(d, &dsc_dir, 'w', "north-west"))
-    {
-        ;
-    }
-    char * dsc_move = "You move ";
-    if (0 == passable)
-    {
-        dsc_move = "You fail to move ";
-    }
-    char * msg = try_malloc(strlen(dsc_move) + strlen (dsc_dir) + 2, __func__);
-    int test = sprintf(msg, "%s%s.", dsc_move, dsc_dir);
-    exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-    update_log(msg);
-    free(msg);
-}
-
-
-
-static void playerbonus_drop(uint8_t owns_none)
-{
-    if (0 != owns_none)
-    {
-        update_log("You try to drop an object, but you own none.");
-        return;
-    }
-    update_log("You drop an object.");
-}
-
-
-
-static void playerbonus_pick(uint8_t picked)
-{
-    if (picked)
-    {
-        update_log("You pick up an object.");
-        return;
-    }
-    update_log("You try to pick up an object, but there is none.");
-}
-
-
-
-static void playerbonus_use(uint8_t no_thing, uint8_t wrong_thing)
-{
-    if      (no_thing)
-    {
-        update_log("You try to use an object, but you own none.");
-        return;
-    }
-    else if (wrong_thing)
-    {
-        update_log("You try to use this object, but fail.");
-        return;
-    }
-    update_log("You consume this object.");
-}
-
-
-
-extern void actor_wait(struct Thing * t)
-{
-    if (t == get_player())
-    {
-        playerbonus_wait();
-    }
-}
-
-
-
-extern void actor_move(struct Thing * t)
-{
-    char d = t->arg;
-    struct Thing * other_t;
-    struct yx_uint8 target = t->pos;
-    uint8_t legal_move = mv_yx_in_dir_legal(d, &target);
-    mv_yx_in_dir_legal(0, NULL);
-    uint8_t passable = 0;
-    if (legal_move)
-    {
-        passable = '.' == world.map.cells[target.y*world.map.length + target.x];
-        for (other_t = world.things; other_t != 0; other_t = other_t->next)
-        {
-            if (0 == other_t->lifepoints || other_t == t)
-            {
-                continue;
-            }
-            if (target.y == other_t->pos.y && target.x == other_t->pos.x)
-            {
-               actor_hits_actor(t, other_t);
-               return;
-            }
-        }
-    }
-    if (passable)
-    {
-        set_thing_position(t, target);
-        build_fov_map(t);
-    }
-    if (t == get_player())
-    {
-        playerbonus_move(d, passable);
-    }
-}
-
-
-
-extern void actor_drop(struct Thing * t)
-{
-    uint8_t owns_none = (!t->owns);
-    if (!owns_none)
-    {
-        uint8_t select = t->arg;
-        struct Thing * owned = t->owns;
-        uint8_t i = 0;
-        for (; i != select; i++, owned = owned->next);
-        own_thing(&world.things, &t->owns, owned->id);
-    }
-    if (t == get_player())
-    {
-        playerbonus_drop(owns_none);
-    }
-}
-
-
-
-extern void actor_pick(struct Thing * t)
-{
-    struct Thing * picked = NULL;
-    struct Thing * t_i;
-    uint8_t highest_id = 0;
-    for (t_i = world.things; t_i; t_i = t_i->next)
-    {
-        if (t_i != t && t_i->pos.y == t->pos.y && t_i->pos.x == t->pos.x)
-        {
-            if (t_i->id >= highest_id)   /* With several Things to pick,      */
-            {                            /* pick the one with the highest ID. */
-                highest_id = t_i->id;
-                picked = t_i;
-            }
-        }
-    }
-    if (picked)
-    {
-        own_thing(&t->owns, &world.things, picked->id);
-        set_thing_position(picked, t->pos);
-    }
-    if (t == get_player())
-    {
-        playerbonus_pick(!(!picked));
-    }
-}
-
-
-
-extern void actor_use(struct Thing * t)
-{
-    uint8_t wrong_thing = 1;
-    uint8_t no_thing = (!t->owns);
-    if (!no_thing)
-    {
-        uint8_t select = t->arg;
-        uint8_t i = 0;
-        struct Thing * selected = t->owns;
-        for (; i != select; i++, selected = selected->next);
-        struct ThingType * tt = get_thing_type(selected->type);
-        if (tt->consumable)
-        {
-            wrong_thing = 0;
-            struct Thing * next = selected->next;
-            free(selected);
-            if (0 < select)
-            {
-                select--;
-                selected = t->owns;
-                for (i = 0; i != select; i++, selected = selected->next);
-                selected->next = next;
-            }
-            else
-            {
-                t->owns = next;
-            }
-            t->satiation = t->satiation + tt->consumable > INT16_MAX ?
-                           INT16_MAX : t->satiation + tt->consumable;
-        }
-    }
-    if (t == get_player())
-    {
-        playerbonus_use(no_thing, wrong_thing);
-    }
-}
-
-
-
-extern void try_healing(struct Thing * t)
-{
-    struct ThingType * tt = get_thing_type(t->type);
-    if (   t->satiation > 0 && t->lifepoints < tt->lifepoints
-        && 0 == (rrand() % 31)
-        && get_thing_action_id_by_name(s[S_CMD_WAIT]) == t->command)
-    {
-        t->lifepoints++;
-        t->satiation = t->satiation - 32;
-        if (get_player() == t)
-        {
-            update_log("You heal.");
-        }
-        else
-        {
-            char * msg_part = " heals.";
-            uint8_t len = strlen(tt->name) + strlen(msg_part) + 1;
-            char * msg = try_malloc(len, __func__);
-            int test = sprintf(msg, "%s%s", tt->name, msg_part);
-            exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-            update_log(msg);
-            free(msg);
-        }
-    }
-}
-
-
-
-extern void hunger(struct Thing * t)
-{
-    if (t->satiation > INT16_MIN)
-    {
-        t->satiation--;
-    }
-    struct ThingType * tt = get_thing_type(t->type);
-    uint16_t testbase = t->satiation < 0 ? -(t->satiation) : t->satiation;
-    exit_err(!(tt->lifepoints), "A thing that should not hunger is hungering.");
-    uint16_t endurance = INT16_MAX / tt->lifepoints;
-    if ((testbase / endurance) / ((rrand() % endurance) + 1))
-    {
-        if (get_player() == t)
-        {
-            update_log("You suffer from hunger.");
-        }
-        else
-        {
-            char * msg_part = " suffers from hunger.";
-            uint8_t len = strlen(tt->name) + strlen(msg_part) + 1;
-            char * msg = try_malloc(len, __func__);
-            int test = sprintf(msg, "%s%s", tt->name, msg_part);
-            exit_trouble(test < 0, __func__, s[S_FCN_SPRINTF]);
-            update_log(msg);
-            free(msg);
-        }
-        decrement_lifepoints(t);
-    }
-}
diff --git a/src/server/thing_actions.h b/src/server/thing_actions.h
deleted file mode 100644
index 97ab3cc..0000000
--- a/src/server/thing_actions.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* src/server/thing_actions.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Actions that can be performed by living things / "actors". Note that apart
- * from the consequences described below, each action may also trigger log
- * messages and other minor stuff if the actor is equal to the player.
- */
-
-#ifndef THING_ACTIONS_H
-#define THING_ACTIONS_H
-
-struct Thing;
-
-
-
-/* Actor "t" does nothing. */
-extern void actor_wait(struct Thing * t);
-
-/* Actor "t" tries to move one step in direction described by char t->arg (where
- * north-east is 'e', east 'd' etc.) Move either succeeds, or another actor is
- * encountered and hit (which leads ot its lifepoint decreasing by one and
- * eventually death), or the move fails due to an impassable target square. On
- * success, update thing's field of view map.
- */
-extern void actor_move(struct Thing * t);
-
-/* Actor "t" tries to drop from inventory thing indexed by number t->args. */
-extern void actor_drop(struct Thing * t);
-
-/* Actor "t" tries to pick up topmost thing from ground into its inventory. */
-extern void actor_pick(struct Thing * t);
-
-/* Actor "t" tries to use thing in inventory indexed by number t->args.
- * (Currently the only valid use is consuming items defined as consumable.)
- */
-extern void actor_use(struct Thing * t);
-
-/* Increment "t"'s lifepoints to a 1/32 chance if its .satiation is positive,
- * its lifepoints are below "t"'s type's .lifepoints, and "t"'s .command is the
- * ID of the waiting action. On success, also decrement .satiation by by 32.
- */
-extern void try_healing(struct Thing * t);
-
-/* Decrement "t"'s satiation and trigger a chance (dependent on over-/under-
- * satiation value) of lifepoint decrement.
- */
-extern void hunger(struct Thing * t);
-
-
-
-#endif
diff --git a/src/server/things.c b/src/server/things.c
deleted file mode 100644
index f114ea4..0000000
--- a/src/server/things.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* src/server/things.c
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- */
-
-#define _POSIX_C_SOURCE 200809L /* strdup() */
-#include "things.h"
-#include <stddef.h> /* NULL, size_t */
-#include <stdint.h> /* uint8_t, uint16_t, int16_t, UINT8_MAX, UINT16_MAX */
-#include <stdlib.h> /* free() */
-#include <string.h> /* memset(), strcmp(), strdup(), strlen() */
-#include "../common/rexit.h" /* exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* yx_uint8 */
-#include "cleanup.h" /* set_cleanup_flag() */
-#include "hardcoded_strings.h" /* s */
-#include "field_of_view.h" /* build_fov_map() */
-#include "map.h" /* mv_yx_in_dir_legal() */
-#include "rrand.h" /* rrand() */
-#include "thing_actions.h" /* actor_wait */
-#include "world.h" /* world */
-
-
-
-/* Used to treat structs Thing, ThingType and ThingAction the same. */
-struct NextAndId
-{
-    struct NextAndId * next;
-    uint8_t id;
-};
-
-
-
-/* To linked list of NextAndId structs (or rather structs whose start region is
- * compatible to it) starting at "start", add newly allocated element of
- * "n_size" and an ID that is either "id" or, if "id" is <= UINT8_MAX and >=
- * "id_start", get lowest ID >= "start_id" and <= UINT8_MAX for new thing
- * ("struct_id"=0), thing type ("struct_id"=1) or thing action ("struct_id"=2).
- */
-static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
-                                             int16_t id, uint8_t struct_id,
-                                             struct NextAndId ** start);
-
-/* Return 1 if cell at "test_pos" is proliferable by "t", i.e. it is passable,
- * it is not inhabited by another thing of "t"'s type, and, if "t" is animate,
- * neither by any other animate thing; else return 0.
- */
-static uint8_t cell_is_proliferable(struct yx_uint8 test_pos, struct Thing * t);
-
-
-static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
-                                             int16_t id, uint8_t struct_id,
-                                             struct NextAndId ** start)
-{
-    struct NextAndId * nai  = try_malloc(n_size, __func__);
-    memset(nai, 0, n_size);
-    if (start_id <= id && id <= UINT8_MAX)
-    {
-        nai->id = id;
-    }
-    else
-    {
-        while (1)
-        {
-            if (   (0 == struct_id && !get_thing(world.things, start_id, 1))
-                || (1 == struct_id && !get_thing_type(start_id))
-                || (2 == struct_id && !get_thing_action(start_id)))
-            {
-                nai->id = start_id;
-                break;
-            }
-            char * err =  "No unused ID available to add to ID list.";
-            exit_err(start_id == UINT8_MAX, err);
-            start_id++;
-        }
-    }
-    struct NextAndId ** nai_ptr_ptr = start;
-    for (; * nai_ptr_ptr; nai_ptr_ptr = &(*nai_ptr_ptr)->next);
-    *nai_ptr_ptr = nai;
-    return nai;
-}
-
-
-
-static uint8_t cell_is_proliferable(struct yx_uint8 test_pos, struct Thing * t)
-{
-    if ('.' == world.map.cells[test_pos.y * world.map.length + test_pos.x])
-    {
-        struct Thing * t_test;
-        for (t_test = world.things; t_test; t_test = t_test->next)
-        {
-            if (t_test->pos.y == test_pos.y && t_test->pos.x == test_pos.x)
-            {
-                if (t_test->type == t->type)
-                {
-                    return 0;
-                }
-                if (t_test->lifepoints && t->lifepoints)
-                {
-                    return 0;
-                }
-            }
-        }
-        return 1;
-    }
-    return 0;
-}
-
-
-
-extern struct ThingAction * add_thing_action(uint8_t id)
-{
-    struct ThingAction * ta;
-    ta = (struct ThingAction *) add_to_struct_list(sizeof(struct ThingAction),
-                                                   1, (int16_t) id, 2,
-                                                   (struct NextAndId **)
-                                                   &world.thing_actions);
-    set_cleanup_flag(CLEANUP_THING_ACTIONS);
-    ta->name = strdup(s[S_CMD_WAIT]);
-    ta->effort = 1;
-    ta->func = actor_wait;
-    return ta;
-}
-
-
-
-extern struct ThingType * add_thing_type(int16_t id)
-{
-    struct ThingType * tt;
-    tt = (struct ThingType *) add_to_struct_list(sizeof(struct ThingType),
-                                                 0, id, 1,
-                                                 (struct NextAndId **)
-                                                 &world.thing_types);
-    set_cleanup_flag(CLEANUP_THING_TYPES);
-    tt->name = strdup("(none)");
-    tt->corpse_id = tt->id;
-    return tt;
-}
-
-
-
-extern struct Thing * add_thing(int16_t id, uint8_t type, uint8_t y, uint8_t x)
-{
-    struct Thing * t;
-    t = (struct Thing *) add_to_struct_list(sizeof(struct Thing), 0, id, 0,
-                                            (struct NextAndId **)&world.things);
-    struct ThingType * tt = get_thing_type(type);
-    set_cleanup_flag(CLEANUP_THINGS);
-    t->type       = tt->id;
-    t->lifepoints = tt->lifepoints;
-    t->pos.y      = y;
-    t->pos.x      = x;
-    if (t->lifepoints && world.exists)
-    {
-        build_fov_map(t);
-    }
-    return t;
-}
-
-
-
-extern void add_thing_to_memory_map(struct Thing * t, uint8_t type,
-                                    uint8_t y, uint8_t x)
-{
-    struct ThingInMemory * tm=try_malloc(sizeof(struct ThingInMemory),__func__);
-    tm->type = type;
-    tm->pos.y = y;
-    tm->pos.x = x;
-    tm->next = t->t_mem;
-    t->t_mem = tm;
-}
-
-
-
-extern void free_thing_actions(struct ThingAction * ta)
-{
-    if (!ta)
-    {
-        return;
-    }
-    free_thing_actions(ta->next);
-    free(ta->name);
-    free(ta);
-}
-
-
-
-extern void free_thing_types(struct ThingType * tt)
-{
-    if (!tt)
-    {
-        return;
-    }
-    free_thing_types(tt->next);
-    free(tt->name);
-    free(tt);
-}
-
-
-
-extern void free_things(struct Thing * t)
-{
-    if (!t)
-    {
-        return;
-    }
-    free_things(t->owns);
-    free_things(t->next);
-    free(t->fov_map);
-    free(t->mem_map);
-    free(t->mem_depth_map);
-    free_things_in_memory(t->t_mem);
-    free(t);
-    if (t == world.things)         /* So add_things()' NULL-delimited thing   */
-    {                              /* iteration loop does not iterate over    */
-        world.things = NULL;       /* freed memory when called the first time */
-    }                              /* after world re-seeding.                 */
-}
-
-
-
-extern void free_things_in_memory(struct ThingInMemory * tm)
-{
-    if (!tm)
-    {
-        return;
-    }
-    free_things_in_memory(tm->next);
-    free(tm);
-}
-
-
-
-extern struct ThingAction * get_thing_action(uint8_t id)
-{
-    struct ThingAction * ta = world.thing_actions;
-    for (; ta && id != ta->id; ta = ta->next);
-    return ta;
-}
-
-
-
-extern struct ThingType * get_thing_type(uint8_t id)
-{
-    struct ThingType * tt = world.thing_types;
-    for (; tt && id != tt->id; tt = tt->next);
-    return tt;
-}
-
-
-
-extern uint8_t get_thing_action_id_by_name(char * name)
-{
-    struct ThingAction * ta = world.thing_actions;
-    while (ta)
-    {
-        if (0 == strcmp(ta->name, name))
-        {
-            break;
-        }
-        ta = ta->next;
-    }
-    if (!ta)
-    {
-        return 0;
-    }
-    return ta->id;
-}
-
-
-
-extern struct Thing * get_thing(struct Thing * ptr, uint8_t id, uint8_t deep)
-{
-    while (1)
-    {
-        if (!ptr || id == ptr->id)
-        {
-            return ptr;
-        }
-        if (deep)
-        {
-            struct Thing * owned_thing = get_thing(ptr->owns, id, 1);
-            if (owned_thing)
-            {
-                return ptr;
-            }
-        }
-        ptr = ptr->next;
-    }
-}
-
-
-
-extern struct Thing * get_player()
-{
-    return get_thing(world.things, 0, 0);
-}
-
-
-
-extern void try_thing_proliferation(struct Thing * t)
-{
-    struct ThingType * tt = get_thing_type(t->type);
-    if (tt->proliferate)
-    {
-        if (1 == tt->proliferate || 1 == (rrand() % tt->proliferate))
-        {
-            struct yx_uint8 candidates[6];
-            uint8_t n_candidates = 0;
-            char dirs[7] = "cxswed";
-            struct yx_uint8 test = t->pos;
-            uint8_t i;
-            for (i = 0; i < strlen(dirs); i++)
-            {
-                if (   mv_yx_in_dir_legal(dirs[i], &test)
-                    && cell_is_proliferable(test, t))
-                {
-                        candidates[n_candidates] = test;
-                        n_candidates++;
-                }
-            }
-            if (!n_candidates)
-            {
-                return;
-            }
-            i = rrand() % n_candidates;
-            add_thing(-1, tt->id, candidates[i].y, candidates[i].x);
-        }
-    }
-}
-
-
-
-extern void add_things(uint8_t type, uint8_t n)
-{
-    uint8_t i;
-    for (i = 0; i < n; i++)
-    {
-        struct yx_uint8 pos;
-        while (1)
-        {
-            char * err="Space to put thing on too hard to find. Map too small?";
-            uint16_t i_pos = 0;
-            for (pos.y = pos.x = 0;
-                 '.' != world.map.cells[pos.y * world.map.length + pos.x];
-                 i_pos++)
-            {
-                exit_err(UINT16_MAX == i_pos, err);
-                pos.y = rrand() % world.map.length;
-                pos.x = rrand() % world.map.length;
-            }
-            struct Thing * t;
-            uint8_t clear = 1;
-            for (t = world.things; t; t = t->next)
-            {
-                if (0 != t->lifepoints && pos.y==t->pos.y && pos.x==t->pos.x)
-                {
-                    clear = 0;
-                    break;
-                }
-            }
-            if (1 == clear)
-            {
-                break;
-            }
-        }
-        add_thing(-1, type, pos.y, pos.x);
-    }
-}
-
-
-
-extern void own_thing(struct Thing ** target, struct Thing ** source,
-                      uint8_t id)
-{
-    struct Thing * t;
-    if (id == (*source)->id)
-    {
-        t = * source;
-        * source = t->next;
-    }
-    else
-    {
-        struct Thing * penult = * source;
-        while (1)
-        {
-            if (id == penult->next->id)
-            {
-                break;
-            }
-            penult = penult->next;
-        }
-        t = penult->next;
-        penult->next = t->next;
-    }
-    struct Thing ** t_ptr_ptr = target;
-    for (; * t_ptr_ptr; t_ptr_ptr = &(*t_ptr_ptr)->next);
-    * t_ptr_ptr = t;
-    t->next = NULL;
-}
-
-
-
-extern void set_thing_position(struct Thing * t, struct yx_uint8 pos)
-{
-    t->pos = pos;
-    struct Thing * owned = t->owns;
-    for (; owned; set_thing_position(owned, pos), owned = owned->next);
-}
diff --git a/src/server/things.h b/src/server/things.h
deleted file mode 100644
index 33a07db..0000000
--- a/src/server/things.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* src/server/things.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Structs for things and their type and action definitions, and routines to
- * initialize these.
- */
-
-#ifndef THINGS_H
-#define THINGS_H
-
-#include <stdint.h> /* uint8_t, int16_t, uint16_t */
-#include "../common/yx_uint8.h" /* yx_uint8 */
-
-
-
-struct Thing
-{
-    struct Thing * next;
-    uint8_t id;                   /* individual thing's unique identifier */
-    struct Thing * owns;          /* chain of things owned / in inventory */
-    struct ThingInMemory * t_mem; /* chain of things remembered */
-    struct yx_uint8 pos;          /* coordinate on map */
-    char * fov_map;               /* thing's FOV map; 'v':visible, 'H':hidden */
-    char * mem_map;               /* map knowledge of thing by FOV and memory */
-    char * mem_depth_map;         /* map of map memory up-to-dateness */
-    int16_t satiation;            /* negative: hungry; positive: over-fed */
-    uint8_t type;                 /* ID of appropriate thing definition */
-    uint8_t lifepoints;           /* 0: thing is inanimate; >0: hitpoints */
-    uint8_t command;              /* thing's current action; 0 if none */
-    uint8_t arg;                  /* optional field for .command argument */
-    uint8_t progress;             /* turns already passed to realize .command */
-};
-
-struct ThingInMemory
-{
-    struct ThingInMemory * next;
-    struct yx_uint8 pos;                             /* position on memorized */
-    uint8_t type;                                    /* thing type identifier */
-};
-
-struct ThingType
-{
-    struct ThingType * next;
-    uint8_t id;          /* thing type identifier / sets .type */
-    char char_on_map;    /* thing symbol to appear on map */
-    char * name;         /* string to describe thing in game log */
-    uint16_t consumable; /* can be eaten if !0, for so much .satiation win */
-    uint8_t corpse_id;   /* type to change thing into upon destruction */
-    uint8_t lifepoints;  /* default start value for thing's .lifepoints */
-    uint8_t start_n;     /* how many of these does the map start with? */
-    uint8_t proliferate; /* if >0: inverse of chance to proliferate */
-};
-
-struct ThingAction
-{
-    struct ThingAction * next;
-    uint8_t id;   /* identifies action in Thing.command; therefore must be >0 */
-    void (* func) (struct Thing *);    /* function called after .effort turns */
-    char * name;                       /* human-readable identifier */
-    uint8_t effort;                    /* how many turns the action takes */
-};
-
-
-
-/* Add thing action of "id" to world.thing_actions, with .name defaulting to
- * s[S_CMD_WAIT], .func to actor_wait() and .effort to 1. If "id" is not >= 1
- * and <= UINT8_MAX, use lowest unused id. Return thing action.
- */
-extern struct ThingAction * add_thing_action(uint8_t id);
-
-/* Add thing type of "id" to world.thing_types, with .corpse_id defaulting to
- * the new thing type's .id, .name to "(none)" and the remaining values to 0. If
- * "id" is not >= 0 and <= UINT8_MAX, use lowest unused id. Return thing type.
- */
-extern struct ThingType * add_thing_type(int16_t id);
-
-/* Add thing of "id" and "type" on position of "y"/x" to world.things. If "id"
- * is not >= 0 and <= UINT8_MAX, use lowest unused id. Build .fov_map if
- * world.exists is non-zero. Return thing.
- */
-extern struct Thing * add_thing(int16_t id, uint8_t type, uint8_t y, uint8_t x);
-
-/* Add to thing memory of "t" thing of type id "type" and position "y"/"x". */
-extern void add_thing_to_memory_map(struct Thing * t, uint8_t type,
-                                    uint8_t y, uint8_t x);
-
-/* Free ThingAction / ThingType / Thing / ThingInMemory chain starting at "ta" /
- * "tt" / "t" / "tm".
- */
-extern void free_thing_actions(struct ThingAction * ta);
-extern void free_thing_types(struct ThingType * tt);
-extern void free_things(struct Thing * t);
-extern void free_things_in_memory(struct ThingInMemory * tm);
-
-/* Return pointer to ThingAction/ThingType of "id", or NULL if none found. */
-extern struct ThingAction * get_thing_action(uint8_t id);
-extern struct ThingType * get_thing_type(uint8_t id);
-
-/* Return world.thing_actions ThingAction.id for "name" or 0 if none found. */
-extern uint8_t get_thing_action_id_by_name(char * name);
-
-/* Return thing of "id" in chain at "ptr", search inventories too if "deep".
- * Return NULL if nothing found.
- */
-extern struct Thing * get_thing(struct Thing * ptr, uint8_t id, uint8_t deep);
-
-/* Get pointer to the non-owend Thing struct that represents the player, or NULL
- * if none found.
- */
-extern struct Thing * get_player();
-
-/* Try to create "t" offspring on random passable neighbor cell if available
- * (and, if "t" is of animate thing type, not inhabited by animate thing) and
- * "t"'s type's .proliferation is >0, with a chance of 1/.proliferation.
- */
-extern void try_thing_proliferation(struct Thing * t);
-
-/* Add thing(s) ("n": how many?) of "type" to map on random passable
- * position(s). New animate things are never placed in the same square with
- * other animate ones.
- */
-extern void add_things(uint8_t type, uint8_t n);
-
-/* Move thing of "id" from "source" inventory to "target" inventory. */
-extern void own_thing(struct Thing ** target, struct Thing ** source,
-                      uint8_t id);
-
-/* Move not only "t" to "pos", but also all things owned by it. */
-extern void set_thing_position(struct Thing * t, struct yx_uint8 pos);
-
-
-
-#endif
diff --git a/src/server/world.h b/src/server/world.h
deleted file mode 100644
index f6deb10..0000000
--- a/src/server/world.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* src/server/world.h
- *
- * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
- * or any later version. For details on its copyright, license, and warranties,
- * see the file NOTICE in the root directory of the PlomRogue source package.
- *
- * Contains the World struct holding all game data together.
- */
-
-#ifndef MAIN_H
-#define MAIN_H
-
-#include <stdint.h> /* uint8_t, uint16_t, uint32_t */
-#include <stdio.h> /* define FILE */
-#include "../common/map.h" /* struct Map */
-struct ThingType;
-struct ThingAction;
-struct Thing;
-
-
-
-struct World
-{
-    FILE * file_in; /* Input stream on file at .path_in. */
-    FILE * file_out; /* Output stream on file at .path_out. */
-    struct Map map; /* Game map. */
-    struct ThingType * thing_types; /* Thing type definitions. */
-    struct ThingAction * thing_actions; /* Thing action definitions. */
-    struct Thing * things; /* All physical things of the game world. */
-    char * server_test; /* String uniquely identifying server process. */
-    char * queue; /* Stores un-processed messages read from the input file. */
-    uint32_t seed; /* Randomness seed. */
-    uint32_t seed_map; /* Map seed. */
-    uint16_t replay; /* Turn up to which to replay game. No replay if zero. */
-    uint16_t turn; /* Current game turn. */
-    uint8_t do_update; /* Update worldstate file if !0. */
-    uint8_t exists; /* If !0, remake_world() has been run successfully. */
-    uint8_t player_type; /* Thing type that player will start as. */
-    uint8_t is_verbose; /* Should server send debugging info to stdout? */
-};
-
-extern struct World world;
-
-
-
-#endif
diff --git a/start_server_client_union.sh b/start_server_client_union.sh
index 69c959d..54a3386 100755
--- a/start_server_client_union.sh
+++ b/start_server_client_union.sh
@@ -10,11 +10,6 @@ then
 fi
 
 # Give helpful message to players that want to start without compiling first.
-if [ ! -e ./roguelike-server ]
-then
-    echo 'No ./roguelike-server file found to execute. Try "./redo" first?'
-    false
-fi
 if [ ! -e ./roguelike-client ]
 then
     echo 'No ./roguelike-client file found to execute. Try "./redo" first?'
diff --git a/start_server_python_client_union.sh b/start_server_python_client_union.sh
deleted file mode 100755
index 5894947..0000000
--- a/start_server_python_client_union.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-# Abort the script on error.
-set -e
-
-# Don't let any log leftovers from before interfere.
-if [ -e ./log ]
-then
-    rm log
-fi
-
-# Give helpful message to players that want to start without compiling first.
-if [ ! -e ./roguelike-client ]
-then
-    echo 'No ./roguelike-client file found to execute. Try "./redo" first?'
-    false
-fi
-
-# Use shell script's arguments for server and pipe server output to log file.
-# This script's wrapper script will read it out on exit.
-python3 ./plomrogue-server.py "$@" > log 2>&1 &
-
-# Give server some time to start up and exit on error.
-sleep 0.01
-
-# The client should not start if the server is not running. (If the server was
-# running in the foreground, any error exit of it so far would be caught by "set
-# -e" above. But "set -e" is blind to error codes generated in the background.)
-kill -0 $! 2> /dev/null
-
-# Give server some time (max. 10 seconds) to generate its worldstate file.
-i=0
-while [ ! -e server/worldstate ] && [ $i -le 1000 ]
-do
-    sleep 0.01
-    i=`expr $i + 1`
-done
-if [ ! -e server/worldstate ]
-then
-    echo "Server failed generating worldstate file within given time limit."
-    false
-fi
-
-# Only start the interface when everything else went well.
-kill -0 $! 2> /dev/null
-./roguelike-client
-- 
2.30.2