Skip to main content
Two of the three plugins Cordial ships have never worked on any machine. Both do now. The packages also stopped being ten times larger than they needed to be.

FPS Flex never worked, on any machine, ever

The built-in plugin Settings advertises by name has done nothing since it shipped. It made two calls and both were refused: it asked for settings.read, which is a permission name and not a method, and it sent flags.set the wrong shape. It never checked either reply, so nothing said so — not in the log, not in Settings, nowhere. CordialPresentMode was never written. It works now, and it has a preferences page: Settings → Plugins → FPS Flex → the gear. Uncapped, mailbox, immediate, locked to your display, or leave it alone. Previously the mode was read from a file no interface could write, so even a repaired version would have been stuck on its default for ever. Still switched off by default, for the same reason as before: uncapping presentation makes the GPU draw frames nobody asked for, and on a laptop that is heat and battery.

Discord Presence was correct and heard nothing

The plugin was fine. The client was not sending it anything. Cordial has a core event bus — cordial/client.launch, client.shutdown and the rest — and it was wired into a plugin host the client does not run. There are two in the source tree, and everything was tested against the wrong one. So Discord Presence subscribed, was told yes, and waited for an event nothing ever published. The client publishes now. Discord Presence shows what you are playing. If you write plugins, this is the general warning: lifecycle.read delivers cordial/client.launch, cordial/engine.version and cordial/client.shutdown. cordial/client.ready and cordial/window.resized are named in the API and published by nothing — that is documented rather than quietly left for you to discover.

Packages are a tenth of the size

The .deb was 59 MB and is now 6 MB. The AppImage was 175 MB and is now 111 MB. Neither was shipping anything useful in the difference: it was debug symbols, about 350 MB of them across the two binaries, which the .rpm and Arch packaging had been stripping all along and the other two had not. Nothing about what you run changes.

The update window tells you what happened

Pressing Check for updates used to do nothing you could see. It worked — it asked, it got an answer — and then put the answer in a tooltip, so the button flickered and nothing else moved. Press it twice and you could not tell it had run. It now says what it found, every time. It still will not tell you that you are up to date, and that is deliberate: Cordial only knows which Roblox version you have if it fetched the build itself, so for an APK you obtained elsewhere there is no second number to compare and “up to date” would be a guess. It says what it did and what Roblox has published, which are facts. When Roblox has not yet published the changelog page for its newest engine, the window says so instead of silently showing nothing. That was going to a terminal nobody reads. Opening the update window twice no longer gives you two of it.

Documentation for people writing plugins

docs/plugin-api.md — the fourteen permissions, the protocol, the manifest, the sandbox, both event buses, FastFlags, settings, preferences and asset overlays. Every signature and every error message in it was read out of the code that implements it, and where something does not work it says so at the point you would meet it. flags.write.dynamic is one: it is a permission a plugin can be granted and it is permanently a refusal, because changing a flag inside the running engine needs the in-process access Cordial will never have.

A cursor that could not reach a dialog

When an experience opens a verification window — the kind that gates joining a group — the cursor was stuck in the game and could not get to it. Unfocusing did not help, because focus was not what held it: the engine had the pointer locked and a locked pointer has no position to move. Cordial now hands the cursor back whenever it has drawn something in front of the engine. This one is reasoned rather than observed — it has not been run against a live verification dialog, and it is the first thing to doubt if you still cannot reach one.

Pointer acceleration reaches the cursor over Roblox’s interface

Your desktop’s pointer speed applies to the cursor while it is over Roblox’s own menus. It did not: the unlocked cursor’s movement was derived by subtracting successive positions, and the compositor’s accelerated figures were thrown away. Cordial now uses the accelerated pair the compositor already sends. Camera movement while the pointer is locked — first person, shift lock, a right-drag — is unchanged and still raw by default, which is what a camera wants. Settings → General offers “Cursor and camera” if you would rather it followed your pointer profile there too. This one has not been judged by a person yet. No automated run can reach it: Cordial’s own test input calls the engine’s mouse entry point directly and never touches the Wayland listeners this changed. If the cursor feels wrong over the Roblox interface, that is worth reporting.

Release notes stopped being about the wrong release

The update window asked Roblox for the release notes belonging to the engine it had just been told about — a page Roblox writes days later, so the window showed the announcement for an engine above a line saying that engine’s notes were not published. It now reads the entry Roblox’s own navigation labels “Current release”, which needs no version arithmetic and cannot go looking for a page that does not exist. There is a “Pending release” beside it, which is close to what the old code was reaching for.

Smaller things, all of them reported

cordial is the command. A symlink beside cordial-shell in every format; nobody wanted to type the second word. cordial-run deliberately gets none — it is the loader, not the launcher. cordial --diagnostics, and a Copy button in Settings → Report a Problem. One block with the Cordial and Roblox builds, how Cordial was installed, your distribution and session. It exists because reports kept arriving without any of it, and the five package formats fail differently enough that “it doesn’t work on Linux” is not diagnosable. It carries no account, no token and no profile name. --help said nothing at all. It exited zero having printed not one line. The .rpm would not install on anything but rawhide. One std::log10 on a float in the audio code bound log10f@GLIBC_2.43, the only symbol in either binary above 2.39, and dnf refused with nothing provides libm.so.6(GLIBC_2.43). The AppImage had it too, which would have made the portable format run on one distribution. A check now refuses any binary above the floor and names the symbol. The window title reads Cordial 0.11.0 again. It had started showing a commit hash on releases, which is for development builds. Three package messages were false and said Cordial could not download a Roblox build, which stopped being true in 0.9.0. Two more claimed text fields do not draw what you type, and that the pointer is not captured in first person.

What is still broken

The startup freeze, when signed in. Not fixed. The client reaches the home screen, draws one frame and stops. Reopening usually works, and it happens less on mains power than on battery. A black canvas inside an experience. Joining works; what you see once there often does not. Pointer acceleration does not reach the Roblox interface. Reported during this release and not fixed. Your desktop’s pointer speed should apply to the cursor while it is over Roblox’s own menus, and it does not. Four candidates are written down in docs/NEXT.md; the leading one is a pointer lock being held while the cursor looks free, which is the same gap the dialog fix above addresses from the other side. Voice chat does not work. The microphone stays shut and there is no downlink. Whether OSS actually plays is unproven. The backend is reachable, but every machine it has been tested on had PipeWire. The AppImage’s embedded browser needs WebKitGTK 6.0 on the host. Ordinary sign-in does not use it — it appears for two-factor prompts and email recovery — so most people will never meet it. If you use 2FA, prefer the Flatpak, .deb or .rpm. Ubuntu 24.04 LTS cannot run the .deb: Cordial needs GTK 4.20 and the LTS ships 4.14. Use the AppImage or the Flatpak, both of which carry their own. The Flatpak remote and the APT repository are not signed. The four downloads on this page are — each has a .cosign.bundle beside it, signed keylessly by the workflow that built it, and the README says how to verify one and why you must not drop the two --certificate-* flags when you do. The two repositories you can add to your system are a different matter: they need an OpenPGP key, which Sigstore cannot supply and which does not exist yet.

Nothing that was proposed and measured away

Parallel and aria2 downloads were asked for, built as an experiment and rejected on the numbers: four connections were within noise of one and eight were about 19% slower, because the link saturates on a single connection. The existing downloader moves the 221 MiB build in about thirteen seconds. The measurement is in docs/NEXT.md, including a retraction of a wrong reading taken on the way.