Installing a dedicated server

"It booted. That is not the same as it working." — Systems Technician Ovan Bree

A StoryForce server is a Jedi Academy dedicated server running the StoryForce game module.

You supply the server executable. The StoryForce download ships the game module and its assets. It does not include an OpenJK dedicated server binary, and the build pipeline never makes one.


What it does

The server download gives you 3 things: the game module the server runs, a sealed asset pack it reads from, and a config file. That config file sets permissions, identity labels and roleplay rules. A server started without it is missing 7 admin commands, including kick and ban.

If you would rather not manage any of this by hand, the published container image does most of it for you. See Docker hosting.


What you need

Gather these before you start:

  • assets0.pk3, assets1.pk3, assets2.pk3 and assets3.pk3 from a copy of Jedi Academy
  • an OpenJK dedicated server binary for your platform, named openjkded followed by its architecture
  • the StoryForce server download for that same platform

Installing

  1. Download the file named StoryForce - Server for your platform from the StoryForce releases.
  2. Make a GameData folder for the server, with a base folder inside it.
  3. Copy the 4 assets pk3 files from your Jedi Academy install into GameData/base/.
  4. Extract the server zip into GameData, which gives you a GameData/StoryForce/ folder.
  5. Put the OpenJK dedicated server binary in GameData, alongside base and StoryForce.

You should end up with this, using the Linux 64-bit file names:

GameData/
    openjkded.x86_64
    base/
        assets0.pk3
        assets1.pk3
        assets2.pk3
        assets3.pk3
    StoryForce/
        jampgamex86_64.so
        storyforce.pk3
        storyforce_server.cfg
        llm/

On Windows the 2 binaries are openjkded.x86_64.exe and jampgamex86_64.dll. On macOS the game module ends .dylib. Everything else is the same on all 3 platforms.


Starting the server

Run the dedicated binary from inside GameData:

./openjkded.x86_64 +set dedicated 2 +set fs_game StoryForce +exec storyforce_server.cfg

On Windows, drop the leading ./ and add .exe:

openjkded.x86_64.exe +set dedicated 2 +set fs_game StoryForce +exec storyforce_server.cfg

dedicated 2 sends a heartbeat to the Jedi Academy master servers, so your server appears in the in-game list. dedicated 1 keeps it to your local network. The shipped config ends by loading mp/ffa3, so that is the map the server comes up on until you change it.

Why the config file is required

+exec storyforce_server.cfg is not optional, and leaving it off causes lasting damage.

The permission values compiled into the game module are older than the commands they need to cover. They grant nothing at all for /sfkick, /sfban, /changemap, /teleport, /telemark, /centersay or /playcinematic. That is 7 commands across 6 permission bits, because /teleport and /telemark share one bit, and /cs is an alias for /centersay. Not even leadership can run them. Only the config file grants them.

Those permission settings are archived, so the engine writes their current values into its own saved config. Boot once without the config file and the narrow values get saved. Every restart from then on loads them back, whether you meant it or not. Putting +exec storyforce_server.cfg on the command line is the only thing that corrects them.

In all, 5 settings differ between the compiled defaults and the shipped config: the 3 permission masks, sf_storytoolsblock and sf_forcemarkduration. The config file values are the intended behaviour. See server configuration.

The first boot

The first time the server starts against an empty database it creates one account. That account holds leadership over everything, and it uses a published default password until you change it.

Changing it is the first job on a new server, before anyone else connects. Set sf_seedaccountpass in your config file before that first boot, or log in straight away and run /account changepassword. The built-in fallback values live in the mod source at codemp/game/sf_db.h.

The server console repeats a warning on every boot until the password is changed. This is the full line, with the default account name:

SF_DB_CreateTables: WARNING - root account 'storyforce' still uses the default password; change it (/account changepassword) and remove sf_seedaccountpass from your server.cfg

What the server writes

Everything the server creates lands under fs_homepath in a folder named after the mod, which is GameData/StoryForce/ on a default install:

  • db/storyforce.db and its storyforce.db-wal sidecar, holding every account and character
  • db/backups/, rolling snapshots named storyforce-<epoch>.db
  • logs/admintrail.log, one line for every staff action
  • bannedips.cfg, the persistent ban list
  • games.log, the base-game match log
  • scenes/, saved scene files

The db folder is created for you on first boot, so you do not need to make it yourself.

Treat the database and its backups as sensitive, and keep them off shared drives and out of public backups. The database explains what they hold and why.


Things to note

  • No config file means no kick and no ban. This is the single most common way to end up with a server nobody can moderate. Always launch with +exec storyforce_server.cfg.
  • Set an rcon password. The shipped config leaves rconpassword commented out. Console commands reachable over rcon include a full reset of the leadership account.
  • Do not rename the StoryForce folder. fs_game, the launcher and the config all expect that exact name.
  • The release contains no server executable. The build pipeline only produces the game module and the assets, so an OpenJK dedicated binary has to come from somewhere else.
  • Kicks do not survive a restart. /sfkick reconnect blocks are held in memory only. Only /sfban writes to disk. See kick and ban.
  • The ban list stops at 512 entries. A ban past that point still applies until the next restart, but its record is dropped, so it does not survive one. The admin is told, and the console adds sf_bans: ban list full.
  • There is no database migration system. A newer build that expects a new column will not add it to a database that already exists.

Next