client::launch started Ascension.exe directly, which cannot work on Linux, and
client::is_running found nothing (it reads the Windows process list). wine.rs is
the Linux counterpart, and both hand over to it on a Linux host.
It runs the command of the project's own launcher script: umu-run with a Proton
build (GAMEID=0, PROTONPATH, WINEPREFIX, started from the client folder), else
plain Wine, with WINEDLLOVERRIDES=divxtac=d (DivxTac.dll deadlocks the world
loading screen under wine-mono). The newest GE-Proton found for Steam is used, or
umu's own choice; COA_PROTONPATH, COA_WINEPREFIX and client-launch.json override
the detection; the prefix defaults to ~/Games/umu/coa-client. The game runs in its
own process group, so closing the Manager does not close it, and prints to
client.log. Whether it runs is read from /proc, where the command line holds the
Windows form of the client path. A clear message says what to install when neither
umu nor Wine is found.
Tests: detection (newest build, no build, Wine only, nothing, overrides), the
command, the /proc match, and a real spawn with a stand-in umu-run that records its
environment. Not run: the real client.
The Realm card showed "io: No such file or directory (os error 2)" on a Docker
server: the Wildcard check read Core/worldserver.exe. The card lets the owner
switch realm, so it is made to work rather than hidden.
What the repack's patched launcher did at each start is done by the Docker
backend: finish an interrupted switch (realms::before_start), name the realms in
the realm list, and give the containers the databases of the selected realm
(acore_world_wildcard, acore_characters_wildcard). The switch itself is the shared
code. prepare_launcher has nothing to patch on a Docker server, and Wildcard
support is read from Core/worldserver as it is from Core/worldserver.exe (the .exe
wins when both exist, so a repack is read as before).
Tests: the support check on both binary names, no launcher to adapt, and the
databases passed to the containers for each realm. Creating the Wildcard realm
itself needs a build and a database with the Wildcard migrations and was not run.
Found by installing a server through the new screen: the update check of a Docker
server read the Windows "stable" channel and offered "0.261003.17 (you have
0.261003.1)". Applying it would have put the repack's executables, MySQL and
launcher into a Linux server folder.
Refused in the core (update::preview, apply and rollback), so no caller can do it.
The Settings tab says that updates are not available for Docker servers yet; the
background check stays quiet, as for any failed check.
A test applies the same update package to the same folder with and without
Settings/docker.json: refused and untouched with it, committed without it.
The install commands ask coa_core::platform::flavor() once and hand a Docker
install to src-tauri/src/docker_install.rs; the repack arm of each command is
untouched (an early return and an extra optional parameter are all that changed
in lib.rs). New command install_environment tells the screen the kind of server,
the suggested folder (~/CoaServer) and why Docker cannot be used, if it cannot.
On Linux the install screen shows the game data folder (used in place, read-only)
and the server package (a folder or an address; there is no default address until
a signed Linux package is published), and disables Install until both are given
and Docker works. It shows Docker's own message with a "Check again" button when
Docker is missing, stopped or not allowed for the user. The Windows screen is
unchanged (checked side by side in the browser mock).
A debug build (tauri dev) accepts another package key named in
COA_DEV_TRUSTED_KEY, to try the installer on a package signed with a throwaway
key; a release build always uses the embedded key.
New text is English only for now (other languages fall back to it).
The signed base package holds the MySQL data directory of a Windows repack. On a
Linux computer extract-schema-base now turns it into a Docker server folder whose
database container opens that directory (mysqlData in docker.json), so the release
SQL, the schema contract and export-baseline run with the Docker installation code.
Windows is unchanged: it still bootstraps the repack's own database program.
docker::install is the Linux counterpart of install::install_base and shares none
of its code (the Windows installer and its folder checks are untouched). Same
order of events: signed manifest, folder / space / game data checks, verified
download, extraction into <dest>.installing, database, one rename. Docker must be
usable; a failure removes the containers, the volume and the staging folder.
The databases start from the package's own dumps, Database/baseline/<kind>.sql.zst,
in the format of the Manager's backups, taken in a state where every migration of
the package is applied. The installer imports them, records the migrations as
applied (baseline) in a few bulk statements, and creates the acore account, the
realm port and the console account. Rebuilding from the repository's SQL does not
work: pending migrations such as rev_20260903_01_live_class_baseline are guards
generated from the maintainers' live database and refuse to run on a database
built from the base scripts, whatever the order.
- coa-release export-baseline --server DIR --out DIR produces the dumps from a
prepared server (repack or Docker).
- The game data stays where the person has it (dataDir in docker.json, mounted
read-only), checked at install time.
- ensure_main_configs creates worldserver.conf / authserver.conf from their
.dist templates when missing, at install and at every start, never overwriting.
- Fix (affects the backend merged in 0.6.0): the database container's health check
is now a ping over TCP. On a new volume the image first runs a temporary server
that answers on its socket but takes no network connection, so the container was
healthy about four seconds (10 s against 14 s measured) before TCP worked.
- docs/ARCHITECTURE.md: D13 (installation, package contract) and D14 (how Windows
and Linux code are kept apart).
Tested: 12 new tests (folder rules, settings, package checks, bulk ledger SQL,
failure cleanup with an in-memory docker), and real runs of the whole chain
through examples/docker_install: baseline dumps exported from a prepared
server, package signed with a throwaway key, installed in 171 s, started by the
Manager (database healthy, world ready in 8 s, auth up), console reached with the
account the installer created, 1630 migrations recorded as applied.
Db runs mysql, mysqldump and mysqladmin inside the database container with
docker exec -i when the server folder is a Docker installation, connecting over
TCP on the container's loopback like the repack's commands do on the host. The
password still travels only in MYSQL_PWD. Every caller keeps using Db unchanged
(accounts, backups, population, migrations, the RA service account), and the
host needs no MySQL client. The repack path is untouched: one line before its
tools are looked up. A stopped container or a missing one is reported as a
database that is not running.
Tested: 4 new tests (commands built for the container, no password on a command
line, repack unchanged, error classification), and a real run against the
Docker folder: SQL queries, a quick backup (156 characters tables), restore with
the previous database kept, a damaged backup refused, the RA service account
created by SQL, the world server console reached through its published
loopback port, an account created through it and listed by the Manager.
A server folder with Settings/docker.json is a Docker installation: MySQL, the
auth server and the world server run in containers controlled through the
docker command line. Every other folder is a repack and goes through the
unchanged Windows code. driver::run, process::observe and layout::scan check
for the marker first and hand over to coa_core::docker.
- start: network, runtime image (libraries only, binaries are mounted from
Core/), database healthy, world listening, then auth. A container that stops
while starting reports the cause found in its log (DatabaseNotRunning,
PortInUse, ...). New error code DockerUnavailable (docker missing, stopped,
or not usable by this user).
- stop: world (180 s to save), auth, database; exit code 0 observed.
- observe: container state, health and port readiness mapped to the existing
ServiceState. Readiness is a connection that stays open, because Docker's
proxy accepts connections before the server inside listens.
- passwords go by environment, never on a command line; the remote console is
published on 127.0.0.1 only; the server's own database updater is turned off
(it needs a mysql client the image does not have and stops the server).
Tested: 18 new tests with an in-memory Docker, and a real run through
examples/drive: database, world (ready in 11 s) and auth started from a
package-shaped folder, stopped with exit code 0 and restarted.
Not included: installation, database setup, backups and SQL through the
container, updates, firewall/exposure, the client under Wine/Proton.
PLAY turns into UPDATE CLIENT when a tracked client is outdated; with no client linked
it offers choosing an existing folder or downloading from the community launcher servers
(resumable, hash-verified, free-space checked, progress and stop). Files the player changed
are kept on request or moved aside, never silently replaced. Existing clients can be adopted
from Settings. Fresh downloads get a realmlist for each installed locale.
Fixes zero-length files in the downloader (found by the live probe).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>