Streamlined Multiplayer
ELI's multiplayer setup was built correctly before it was tested correctly. The architecture - PocketBase for the server, Tailscale for the encrypted tunnel, and an invite code that bundles the connection details - is sound. What fell apart was the path to get there.
The first real testers hit a cascade of failures that had nothing to do with their technical skill. They invented new email addresses on every retry because the "player account already exists" error was not recognized as a success condition. They were told to "enable Funnel" by opening a Tailscale link that was already live. The error Could not create child process: tailscale version appeared even with Tailscale installed, because Godot's subprocess handling does not search PATH the same way a shell does. One machine ended up with two PocketBase processes sharing one database folder, which PocketBase does not support.
These are my failures, not theirs. This update fixes them.
The Root Causes (Documented)
Funnel status detection: The wizard read the Tailscale CLI output and looked for a URL. But Tailscale prints the live serve URL on success and a different authorization URL when it actually needs action - and both look like URLs. The wizard grabbed whichever URL appeared first and treated a working Funnel as broken. Now it classifies URLs by domain: login.tailscale.com/f/ is an authorization request, *.ts.net is the live address. Success is confirmed by parsing the serve status JSON directly, not the human-readable banner.
Binary discovery: ELI was looking for the Tailscale executable in one hardcoded location, then trying a bare process name that relied on PATH being populated at the moment Godot launched. Tailscale's Windows installer does not guarantee PATH injection, and PATH is a per-process snapshot. Now the discovery tries a chain: the remembered path from a previous session, the standard installation directories, a Windows registry lookup, and finally an explicit file picker if everything else fails.
Player account creation: The "check if this account already exists before creating it" logic matched on a substring that does not appear in PocketBase's actual error message. Every retry created a new account attempt that failed, instead of treating the duplicate as a signal to try signing in with the existing account instead.
Duplicate server processes: The server start routine did not check whether a server was already answering before spawning another one. Now it probes the health endpoint first. If something is already running on that port from the same install folder, ELI adopts it rather than forking a duplicate.
The public URL was not persisted: After a successful Funnel setup, the address your friends use to connect to your server was stored transiently in the wizard's local variables and only reached permanent storage if you manually saved Sync Settings at the right moment. This meant autostart never worked for Funnel hosts, because the saved URL was the loopback address, not the Funnel address. Now the wizard writes the public URL when Funnel is verified and that is what everything else reads.
The UX Overhaul
Beyond fixing the specific failures, the flow has been rethought.
The setup wizard now runs through a pre-flight checklist automatically before asking you to make any decisions. Tailscale found, Tailscale logged in, HTTPS certificates present, and Funnel permission granted - each step shows as a live check with a single next-action button visible at any given time. You do not navigate a series of information screens; the wizard tells you what to do next.
The admin account for your PocketBase server is now auto-generated (email admin@eli.local, strong random password, stored locally and device-encrypted). This eliminates an entire screen of the setup process and the "which of my two accounts is this" confusion that appeared when users tried to remember credentials they had entered during a previous setup attempt.
The multiplayer-related settings - sync status, server management, and your player identity - now live in a single dialog instead of three separate windows. Account settings are global (they apply across all your worlds), while world settings (which server, sync enabled or not) are per-world. The dialog has two clearly labeled zones for these two different scopes.
The documentation and help text have been updated to remove all references to Tailscale's 100.x mesh addresses, which are your device's private network addresses - not what your friends use to connect when you are running Funnel. Every example, placeholder, and help file now shows *.ts.net URLs for Funnel setups.
What Has Not Changed
The underlying architecture is the same: PocketBase, self-hosted, Tailscale Funnel for public access, and invite codes. The data ownership model does not change: your world lives on your hardware, synced through a server you run, over a network you control. I am not adding a hosted tier or changing the privacy stance.
The changes here are about the gap between "it works if you understand exactly what is happening" and "it works."
Get ELI
ELI
Build your world. Own your data.
| Status | In development |
| Category | Tool |
| Author | Special_Cog |
| Tags | campaign-manager, dnd, gm-tools, notetaking, offline, Tabletop, Tabletop role-playing game, wiki, worldbuilding, writing |
| Languages | English |
More posts
- Introducing Lite Mode6 days ago
- Gamifying the Manuscript (Writing Sprints and Lipograms in Godot)7 days ago
- Local-First Model Adapters (Implementing Groq, NVIDIA, and Ollama in Godot)8 days ago
- No File Size Limits (The Benefit of Local Storage)9 days ago
- ELI vs The Industry Standard (articy:draft)10 days ago
- Rebuilding a Keyboard-First Freeform Board in Godot11 days ago
- Exporting Without a Server (The Architecture of Single-File HTML Worlds)12 days ago
- The Power of Spatially Unconstrained Brainstorming (The Freeform Board)13 days ago
- ELI Update - 2026.07.1314 days ago
Leave a comment
Log in with itch.io to leave a comment.