Skip to content

Desktop

For: building and shipping the Windows desktop shell.

What the desktop app is

The desktop app is an Electron shell. Its main process serves the repository's built dist/ directory over a custom app:// protocol and opens the game in a window.

The shell ships the built client rather than loading a remote site, which is the opposite of how the mobile shells work. A change to the game therefore reaches desktop users through a new build, not through a web deploy.

The project lives under platforms/desktop and carries its own manifest and its own dependency tree.

Once per machine

Install the desktop project's own dependencies, which are separate from the repository root's:

bash
npm ci --prefix platforms/desktop

Node 22 or above is the declared floor for this project. The repository's own floor of Node 24 satisfies it.

Run it

Build the client first, since the shell serves what the build produced:

bash
npm run build
npm start --prefix platforms/desktop

Starting without a build leaves the shell with nothing to serve.

Package it

Produce a distributable:

bash
npm run package --prefix platforms/desktop

Then check the packaged artifact rather than trusting that packaging succeeded:

bash
npm run package:smoke --prefix platforms/desktop

Prove it

Three checks cover three different things, and they are not interchangeable.

CommandProves
npm run test:desktopthe shell's own unit suite, from the repository root
npm run desktop:smoke:livethe shell boots and renders against a live dev loop
npm run desktop:smoke:shippedthe packaged artifact boots and renders as shipped

The shipped smoke is the one that matters before a release. A shell that works against a dev loop can still fail once packaged, because the packaged tree resolves paths differently.

The suite covers the security posture explicitly: the renderer's settings, the network origins the shell will talk to, and the integrity of the packaged tree each have their own spec.

What the suite guards

Several specs exist because the failure they catch is invisible until a user hits it.

GuardCatches
blank-window reporta shell that opens a window and renders nothing
package and dist paritya packaged tree that has drifted from the build it claims to carry
renderer securitya renderer given more privilege than it needs
network originsthe shell reaching an origin it should not
chromium argumentsa smoke run that passes only because it disabled a protection

Credentials

None. Packaging produces an unsigned artifact, and nothing in this project reaches an external service.

Code signing for Windows is not set up in this repository. Shipping a signed build means obtaining a code-signing certificate and adding a signing step, which is work that does not exist yet rather than a switch to turn on. Say so plainly to yourself before promising a signed installer to anyone.

Sharp edges

The shell serves a build rather than a live site, so a desktop user stays on the version they installed until they install another. Desktop and mobile therefore diverge after any web deploy.

The icon is generated from a source image by a script in the project's build directory rather than committed by hand at every size.