Skip to content

feat(bfeserver): add Battlefront Eternal server - #5116

Merged
dgibbs64 merged 11 commits into
developfrom
feature/bfeserver
Oct 31, 2026
Merged

dgibbs64 merged 11 commits into
developfrom
feature/bfeserver

Conversation

@dgibbs64

@dgibbs64 dgibbs64 commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Description

Adds Battlefront Eternal as a new server: bfeserver, shortname bfe. Battlefront Eternal is a GPL-3.0 engine for STAR WARS Battlefront (Classic, 2004), with a native headless Linux dedicated server that runs on Node.js. It is a new project and still in development preview, so expect its releases to change often.

Fixes #5112

Affected servers: bfe

Needs GameServerManagers/Game-Server-Configs#164 (the default config.json) merged first. Install downloads that file, and the Details Check job fetches it.

How it works

  • Retail game (SteamCMD): every server prepares its game data from an owned copy of the 2004 game. appid is 1058020 with steamcmdforcewindows="yes" (the app only has a Windows depot), and steamuser must own the game, as with Running With Rifles. The ~2.8 GB game lands in serverfiles (GameData/). Nothing from the game is redistributed.
  • Install and update (update_bfe.sh):
    • Reads SHA256SUMS from https://get.battlefronteternal.com/downloads/latest, the project's release feed, and picks the server-only archive for the machine (battlefront-eternal-server_<version>_linux-<amd64|arm64>.tar.xz, published since preview 327 at our request). The version comes from the file name (0.1.0~preview.327 today) and is stored in lgsm/data/<instance>-bfe-version for check-update and update. force-update works because appid is set.
    • Downloads the archive (about 117 MB), verifies its SHA256, and extracts it into serverfiles/bfe with fn_dl_extract: host-runtime/ (engine and server), tools/, toolchain/ (a bundled Python), bfe-tree.json and legal/. The desktop client is not downloaded.
    • Installs Node.js 24 into serverfiles/node from nodejs.org, checked against its published SHA256. The server needs Node 22.13 or later, which no supported distro ships (Debian 13 has 20). update and check-update check for a newer 24.x on every run, not only when a new release is out, so Node fixes land without waiting for a release. A Node-only update stops and starts the server like any update and sends the update alert. The new Node is extracted into node.new and only replaces node once it extracts, so a failed download or extract leaves the old one in place.
    • Prepares the game data with the release's own tools/prepare.py --core-only into serverfiles/bfe-data (about 2.2 GB, a few minutes). It is only prepared again when the release's tools or toolchain change: the key is a hash of their entries in bfe-tree.json, the same inputs the project's own updater uses. Preparation runs into bfe-data.new and replaces the old data only on success, and its log is log/script/<instance>-prepare.log.
    • update and check-update follow Battlefront Eternal releases. validate checks the retail game and leaves the server files alone.
  • Config: config.json comes from Game-Server-Configs#164 and lives in serverfiles/bfe-state, the server's state directory (BFE_STATE_DIR), which also holds its identity key, operator token and stats database. New servers do not accept the project's online notice, so they are LAN or direct-connect only until the operator sets "onlineNoticeAccepted": true to list publicly. details reads the server name, max players, game port and LAN discovery port from it.
  • Start: executabledir is serverfiles/node/bin and executable is ./node. preexecutable sets BFE_STATE_DIR, BFE_ENGINE_DIR, BFE_DATA_DIR and PORT with env, then node runs bfe/host-runtime/server/src/main.js --serve. A new healthport setting (default 18450) is the server's loopback health and admin port, so more than one instance can run on a machine.
  • Ports and query: game port 18451 UDP, with the server's HTTP /info on TCP 18451, and LAN discovery on UDP 18452. gamedig has no protocol for this game, so monitor uses querymode 5 (TCP) on the game port. The port diagnostic command greps for MainThread, the name Node's main thread shows in ss.
  • Stop: stopmode 2 (CTRL+c). The server shuts down on SIGINT.
  • steamclient.so fix (shared, fix_steamcmd.sh): the sdk32 and sdk64 link steps now create the link only when SteamCMD's steamclient.so exists, and otherwise skip quietly. Battlefront Eternal updates from its own feed, so on a fresh install it reaches start before SteamCMD has ever run, and the old code printed "Could not copy any steamclient.so" twice. Steam games are unchanged: their SteamCMD files exist by the time they start, and the link is created as before.
  • Dependencies: none beyond the base list. Minimum RAM 2 GB, the project's own production budget for one server.

Type of change

  • Bug fix (a change which fixes an issue).
  • New feature (a change which adds functionality).
  • New Server (new server added).
  • Refactor (restructures existing code).
  • Chore (CI, workflows, tooling or other maintenance).
  • Comment update (typo, spelling, explanation, examples, etc).

Testing

  • Commands/tests run:
    • ./linuxgsm.sh bfeserver and auto-install from this branch, with a Steam account that owns the game. SteamCMD installed app 1058020, Node v24.22.2 and release 0.1.0~preview.323 were downloaded and passed their SHA256 checks, and the game data was prepared with no failed steps. The config.json download returns 404 until Game-Server-Configs#164 merges, so for the test that file was put in place by hand.
    • start: the server came up with /healthz reporting running and multiplayerReady: true, and /info answering on TCP 18451. ss shows UDP 18451 and 18452 on IPv4 and IPv6, TCP 18451, and TCP 18450 on loopback.
    • details: server name, max players and all three ports read from config.json, each listed as listening.
    • monitor: TCP query on 18451 OK.
    • check-update: "No update available" (0.1.0~preview.323 on both sides).
    • force-update while running: stopped the server (graceful CTRL+c in 2 s), downloaded and extracted the release, kept Node and the prepared game data, and started the server again.
    • Node update with no new release: with Node v24.0.0 in place and the latest release installed, check-update reported the release current and Node v24.0.0 to v24.22.2 available. update downloaded v24.22.2, passed its SHA256 check, replaced node, cleared tmp and sent the update alert. Running update again reported no Node.js update.
    • force-update with the stored data key changed: prepared the game data again and wrote the new key.
    • After switching to the server archive: update from 0.1.0~preview.326 to preview.327 on a running server stopped it gracefully, downloaded and verified the archive, extracted it, kept the prepared game data (the data key is unchanged, as the archive carries the same bfe-tree.json), and started the server again. /info answered from outside the host afterwards.
    • steamclient.so fix: with SteamCMD's steamclient.so absent, restart printed no steamclient lines and no FAIL. With it present, restart created both links (hardlink count 2). A further restart with the links in place did nothing.
    • validate: Steam validated app 1058020, and the bfe, bfe-data, bfe-state and node folders were untouched.
    • stop: graceful CTRL+c, no server process left.
    • serverlist-validate.sh and serverlist-validate-game-icons.sh pass. shellcheck is clean on the new and changed modules.
  • Result: all of the above pass. Not tested: joining from the game client, an ARM64 host, and listing on the public master server (needs onlineNoticeAccepted).
  • Environment used (distro/version): a clean gameservermanagers/linuxgsm:ubuntu-26.04 container on a test server.

Risk and rollback

  • Risk level: low. All changes are new or limited to bfe branches in shared modules, apart from the steamclient.so step in fix_steamcmd.sh, which now skips instead of printing a failure when there is nothing to link.
  • Rollback plan: revert this PR.

Breaking changes

  • No breaking changes.
  • Breaking changes included (describe below).

Documentation

A Battlefront Eternal game server page (game ownership, game data preparation, the online notice) is still to be written.

Checklist

PR will not be merged until all steps are complete.

  • This pull request links to an issue ("Fixes", or "Related to" for a partial fix).
  • This pull request uses the develop branch as its base.
  • This pull request subject follows the Conventional Commits standard.
  • This code follows the style guidelines of this project.
  • I have performed a self-review of my code.
  • I have provided a detailed enough description of this PR.

Thank you for your Pull Request!

Battlefront Eternal is a GPL-3.0 engine for STAR WARS Battlefront (Classic,
2004) with a native headless Linux server that runs on Node.js.

- SteamCMD downloads the retail game (appid 1058020, Windows depot) with an
  owning steamuser. The server prepares its game data from that copy.
- update_bfe.sh downloads the signed release .deb from
  get.battlefronteternal.com, checks its SHA256, and extracts only the
  server runtime, preparation tools and Python toolchain from it with ar
  and tar, so it works on every distro.
- Node.js 24 is installed into serverfiles/node from nodejs.org with its
  published SHA256, as no supported distro ships Node 22.13 or later.
- Game data is prepared with the release's own tools/prepare.py
  --core-only into serverfiles/bfe-data, and only prepared again when the
  release's tools or toolchain change.
- config.json lives in serverfiles/bfe-state (BFE_STATE_DIR), together
  with the server identity, operator token and stats database.
- update and check-update follow Battlefront Eternal releases. validate
  re-downloads the retail game.
- stopmode 2 (the server shuts down on SIGINT), querymode 5 (TCP, the
  HTTP /info listener on the game port).
check_executable.sh looks for the executable directly in executabledir, so
executabledir is node/bin and the server script path is absolute.
Node names its main thread MainThread, which is what ss shows.
@dgibbs64 dgibbs64 added this to the v26.5.0 milestone Oct 30, 2026
@github-actions github-actions Bot added type: feature New feature or request engine: rwr Issues related to rwr engine game: Running With Rifles Issues related to Running With Rifles labels Oct 30, 2026
Battlefront Eternal now publishes battlefront-eternal-server_<version>_linux-<arch>.tar.xz
beside the .deb, listed in SHA256SUMS. It holds host-runtime, tools, toolchain and
bfe-tree.json at its root, so it extracts with the standard fn_dl_extract and no
longer needs ar or the package's internal paths. About half the download size.
The Battlefront Eternal server runs on Node.js and never loads steamclient.so;
SteamCMD only downloads the retail game data. On a fresh container SteamCMD is
not installed yet at start, so both links failed with Could not copy any
steamclient.so. The libtinfo fix for SteamCMD still runs.
The sdk32 and sdk64 steps now look for SteamCMD's steamclient.so first and
create the link only when one exists. Before SteamCMD has ever run there is
nothing to link, and the next start after it runs creates the link. This
replaces the bfe shortname check: servers updated outside SteamCMD, such as
Battlefront Eternal, reach start on a fresh install before SteamCMD exists and
printed Could not copy any steamclient.so.
@dgibbs64 dgibbs64 removed game: Running With Rifles Issues related to Running With Rifles engine: rwr Issues related to rwr engine labels Oct 31, 2026
Node was only checked when a new Battlefront Eternal release was applied, so Node fixes waited for the next release. update and check-update now check Node on every run and apply a Node-only update through fn_update_apply. The new Node is extracted into node.new and swapped in only after it extracts, so a failed download or extract keeps the old runtime.
@dgibbs64
dgibbs64 merged commit 71f16e5 into develop Oct 31, 2026
56 checks passed
@dgibbs64
dgibbs64 deleted the feature/bfeserver branch October 31, 2026 22:53
@dgibbs64 dgibbs64 mentioned this pull request Oct 31, 2026
3 tasks done
@dgibbs64 dgibbs64 linked an issue Nov 1, 2026 that may be closed by this pull request
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Server Request]: Battlefront Eternal

1 participant