Skip to content
ndoucettePublic

About

A multi front-end launcher for Gemstone IV

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Character workspace usability

Use Open character in the shared header to inspect a character from any view. Inside a profile, Character to inspect switches characters while keeping the current section and skill filters. Compare with shows aligned Overview, Stats, Skills or History values for two explicit character/realm identities. Stats comparison offers base, normal and enhanced values with bonuses; unknown values remain distinct from zero. Select No comparison for the full profile, including live status, effects, training and other detailed observations.

Views and profile/comparison links now survive refresh and browser Back/Forward. View filters are remembered within the browser tab. Progress drilldowns retain the selected period, including custom dates. The roster keeps exact weekly/stored balances visible and puts the complete cycle/resource summary in an expandable section. All five navigation destinations remain visible on phones.

See the UX audit, redesign proposal and validation results and screenshots. New isolated checks: .venv/bin/python examples/ux_browser_check.py and .venv/bin/python examples/ux_resilience_check.py (Playwright Chromium required). Restart the Gempy web process for the new asset routes, then reload the browser.

Persistent web service

Live shows two character cards per row on wide desktops and one per row on smaller screens. Each card has Character and Vitals columns, which stack on phones. Open client and Disconnect icons sit beside the name and realm; clicking the level opens the profile. The desktop sidebar can collapse to an icon strip using its top arrow; the browser remembers your choice. Current location and Lich room ID appear below the character name, above their level. Weekly and Stored resource counts appear beneath each character's status, and XP bonuses sit beneath Vitals in both layouts. Fresh critical health/spirit states stand out; reporting timestamps stay in tooltips, and experience metrics are available in the character profile. Refresh the browser to load these UI changes.

Rotation is a weekly hunting view for configured main characters and enchanting wizards. Wizard completion requires current-cycle Lumnis spent and weekly essence earnings at the reported cap (or the configured weekly target). Exact earned and stored balances, Pacific AM/PM renewal dates, upcoming deadlines and account occupancy are visible. Filter by account or completion, or group by account. Main character Lumnis summaries are separate; their section folds away on phones.

Configure membership and account roles in weekly_rotation (see config-sample.yaml). The view uses stored game observations and never imports old note balances as live progress. Missing reports and passed renewals require an update. For cycle attribution, it conservatively checks observations against the calendar week preceding the reported next renewal in Eastern time, with a minute of rounding tolerance. Offline completion remains visible only while its observations belong to that cycle. A new launch is disabled in this view when another character on that account is already running.

Character names in Characters now open a persistent profile, including while offline. Profiles use four tabs: Overview, Stats, Skills, and History. Overview keeps exact weekly and stored resource balances alongside Lumnis and donations; live status and experience/training remain available in expandable sections. Stats separates base, normal and enhanced values and bonuses. Prime and Test retain separate profiles. Unreported fields show a dash; each profile section includes its observation time. Profile data is included in the existing SQLite backup.

Live and roster summaries show exact profession resource numbers, for example Essence · Weekly: 32,450 · Total: 118,750. The detailed profile separates Earned this cycle (weekly) from Total stored, and shows caps read from the game's RESOURCE response. Weekly earnings are not the spendable balance. Temple donations prepaid for future cycles appear separately from the observed Lumnis phase. Passing a reported refresh time does not automatically reset counters or mark a new cycle active; Gempy waits for a game observation.

Live cards use the installed Saga client's Lumnis and Tutelage artwork. Lumnis shows its multiplier over the colored icon while active; expired bonuses use grayscale artwork. Tutelage is colored when eligible and has a steady gold glow while active. Hover or focus either icon for status, prepaid cycles, and remaining Tutelage days; clicking opens the character profile. A countdown in whole days and hours appears beside the icons. Asset provenance is recorded in static/images/saga/SOURCE.txt.

Install the updated scripts/gempy_reporter.lic in Lich's scripts/custom/ (or download it from Settings) and restart the reporter on each running character with ;kill gempy_reporter then ;gempy_reporter. Existing character-specific URL/token settings are retained. The reporter quietly requests INFO FULL, SKILL, LUMNIS INFO, RESOURCE and EXPERIENCE in a bounded startup sequence, then rotates them at its configured command interval. It also observes manually requested reports. Stats and skills refresh less often than vitals. Old reporters remain compatible but cannot populate the new stats and skills sections.

After installing backend changes, restart the Gempy web process and reload the browser. Restarting Gempy leaves game and frontend sessions connected.

Additional checks: ruby test_reporter_profiles.rb and .venv/bin/python examples/profile_browser_check.py (requires Playwright Chromium).

The web workspace has Live, Progress, Characters, and Settings views. Live combines session/client controls with reported character vitals, location, injuries, effects and experience. Progress retains XP history for offline characters, with today/week/month/year totals and custom date ranges. Settings manages reporter tokens, Saga history imports, SQLite backups, timezone/day rollover and display defaults. See MIGRATION.md for reporter installation, pilot and KoboldMonitor cutover.

Use Add a character to enter a character name already saved in Lich and choose an existing account label or create a new one. Account labels organize the roster; Lich uses its saved login for authentication. Additions are saved to config.yaml and are available immediately, including after restarting Gempy. Edit moves or corrects a roster entry; Rename changes an account label. These labels organize the roster, while Lich continues to own saved game credentials.

The terminal launcher remains available with ./run.sh. For a Linux web daemon, configure your existing Lich saved logins and set paths.vellum_bin to the installed Vellum executable. The web interface has its own client selector. No desktop environment is required.

Set the single Gempy administrator password interactively, then start the server:

./run.sh --set-password
./run.sh --web

Open http://127.0.0.1:8080 and sign in. Gempy stores a salted password hash in private application state under ${XDG_STATE_HOME:-$HOME/.local/state}/gempy; it does not store the password itself. Login sessions expire, login attempts are throttled, and state-changing requests require a CSRF token. Use Log out on shared browsers. This login is separate from your Lich saved game logins. After changing the password with --set-password, restart the daemon to apply it and revoke existing Gempy login sessions.

The Characters tab lists configured accounts and lets you choose Prime or Test before launching. A launch reuses a matching running Lich session. The Live view also discovers local sessions started outside Gempy and shows Attached, Headless, or Unknown client status. Open/Attach client opens Despana in a new tab; allow pop-ups for Gempy if your browser blocks it. Status refreshes every three seconds by default, configurable in Settings. Attachment is checked passively and is not a measure of open browser tabs.

Disconnect asks for confirmation and requests an orderly Lich exit. Allow up to 70 seconds for cleanup. If orderly exit fails, a separately confirmed Force Disconnect can terminate the revalidated process. Successful disconnect also removes managed frontend processes. Closing a browser tab, logging out of Gempy, or stopping/restarting the daemon leaves game and Vellum sessions running; the next daemon start rediscovers them.

For LAN or Tailscale access, bind Gempy to all interfaces:

./run.sh --web --host 0.0.0.0 --port 8080

Visit http://<server-LAN-or-Tailscale-hostname>:8080. Despana links use the hostname you used to access Gempy and Vellum's actual web port. Gempy and Vellum use separate ports: both must be reachable from your browser, including through any host firewall. Vellum keeps its pairing authentication; treat pairing URLs as secrets. Gempy returns them only after login and excludes them from logs.

This mode is intended for a trusted LAN or Tailscale network with one administrator, not deployment directly on the public internet. Plain HTTP does not encrypt LAN traffic. Use Tailscale for access over untrusted networks. Run one daemon worker so operation locks and port allocation remain coordinated.

Use examples/gempy.service to run the dashboard as a systemd user service. Replace both checkout paths before installation. The unit runs run.sh, which selects the project Python environment and the local Ruby 4.0.3 runtime. Set the password only for a new installation; when migrating an existing dashboard, keep its configuration, credentials, and state directory.

mkdir -p ~/.config/systemd/user
cp examples/gempy.service ~/.config/systemd/user/gempy.service
# Edit ~/.config/systemd/user/gempy.service before starting it.
systemctl --user daemon-reload
systemctl --user enable gempy.service
loginctl enable-linger "$USER"
# Stop only the old standalone dashboard PID before starting the service.
systemctl --user start gempy.service

Lingering keeps the user manager running after logout and starts it when WSL boots. If enabling lingering requires administrator privileges, run sudo loginctl enable-linger "$USER". WSL must have systemd enabled in /etc/wsl.conf. The service runs independently of the launching terminal while the WSL distribution is running.

The unit uses Restart=on-failure, a five-second restart delay, and KillMode=process. Preserve KillMode=process: stopping or restarting the dashboard must leave Lich and Vellum processes running. Do not use a broad process-kill command when replacing a standalone dashboard. If it used GEMPY_STATE_DIR or XDG_STATE_HOME, configure the same state location in the unit before starting it.

For the /home/nick/gs4/gempy WSL installation, the installed unit is /home/nick/.config/systemd/user/gempy.service, with the existing bind address 0.0.0.0:8080 and state at /home/nick/.local/state/gempy. Its environment includes DISPLAY=:0, the WSLg Wayland and PulseAudio sockets, and WSL_INTEROP=/run/WSL/1_interop, verified from a systemd user unit. This avoids depending on the original terminal's interop socket. Recheck these WSL-specific paths if moving the unit to another distribution.

To reproduce this installation, use these values in the unit's [Service] section in addition to the settings in the example:

WorkingDirectory=/home/nick/gs4/gempy
ExecStart=/home/nick/gs4/gempy/run.sh --web --host 0.0.0.0 --port 8080
Environment=GEMPY_STATE_DIR=/home/nick/.local/state/gempy
Environment=DISPLAY=:0
Environment=WAYLAND_DISPLAY=/mnt/wslg/runtime-dir/wayland-0
Environment=PULSE_SERVER=unix:/mnt/wslg/PulseServer
Environment=WSL_INTEROP=/run/WSL/1_interop
Environment=WSL_DISTRO_NAME=Ubuntu-26.04

Replace the example's WorkingDirectory and ExecStart lines with these values, then add the environment entries. After editing an installed unit, run systemctl --user daemon-reload before restarting it.

Verified on 2026-10-18: the service was enabled and active, Linger=yes, and the dashboard returned HTTP 200 on port 8080. A dashboard-only service restart preserved all four running Lich processes, their listening sockets, and all 22 Vellum processes, including clients launched by the service. Ruby 4.0.3, the SQLite/GTK/OpenSSL gems, Python dependencies, and Windows interoperability were checked in the service environment. The transition preserved configuration and credential file hashes and retained the existing telemetry database.

Manage the installed service with:

systemctl --user status gempy.service
journalctl --user -u gempy.service -f
systemctl --user restart gempy.service
systemctl --user stop gempy.service
loginctl show-user nick -p Linger

An explicit stop stays stopped despite Restart=on-failure. Use systemctl --user disable --now gempy.service to stop it and disable automatic startup. Gempy itself does not install or enable a service.

Other clients

Choose Client above the roster; the choice applies to launches and existing session attachments. Vellum Despana remains the default. Vellum Web / mobile opens the /play layout using the same authenticated Vellum engine, so switching browser layouts does not create another game login.

Vellum desktop and Vellum terminal open on the computer running Gempy. The desktop needs a graphical display. The terminal choice opens a terminal emulator; configure clients.terminal_command as an argument list if needed (for example ['xterm', '-e']). A browser on another device does not cause these windows to open on that device. Connection details provides desktop, terminal, and SSH tunnel commands for connecting from another computer without exposing Lich's unauthenticated listener to the network. Replace USER@SERVER in the tunnel command with your SSH login. Vellum mobile apps can also pair with the existing web session; use Vellum's pairing workflow.

Saga (experimental) opens a new window in the installed Saga, including when other Saga windows are already running. Set paths.saga_bin to its executable or Linux AppImage. On Windows/WSL, Gempy also discovers C:\Program Files\Saga\Saga.exe.

Gempy displays the selected character, realm, host, and port. In the new Saga window, select Via Lich, expand Advanced: attach to a running Lich, choose GemStone IV, enter the displayed host and port, and select Attach to Lich. No account sign-in is needed: the port selects the existing character session, including its Prime or Test realm. Each Saga launch uses this step; existing windows stay open. The terminal launcher also displays these details and waits for Enter before returning to its roster.

Saga 0.10.4 forwards new-window requests to a shared process but does not forward the external Lich host and port. Gempy uses Saga's per-window attach form to avoid connecting a new window to the first character's port. A launch is shown as awaiting manual attachment, rather than reported as connected.

Gempy clears inherited automatic-login targets and passes the normal-window environment to Windows through WSLENV. Windows Saga must be able to reach WSL at 127.0.0.1; the tested installation uses the existing WSL localhost networking. On older Lich versions accepting a single client, close the attached frontend before opening another one.

Native client windows remain under your control. Closing a native client leaves Lich running; Disconnect ends the game session. Gempy does not force-close Windows Saga or a terminal emulator. A missing display/client or startup timeout returns an error; if a window opened despite a timeout, check it before retrying.

The terminal launcher can select frontend: vellum_gui, vellum_tui, vellum_web, or saga in config.yaml. Vellum TUI uses the current terminal. Restart Gempy after changing its configuration or installing these changes.

Vellum Despana setup

Run ./run.sh from this directory. The ignored config.yaml selects frontend: vellum_despana, the shared /home/nick/gs4/Lich5/lich.rbw, and /home/nick/gs4/vellum-fe. Python requirements are installed in .venv. Prime is the default; press t to switch to Test, then Enter to launch. The menu stays available for additional characters while Vellum runs in the background. Startup failures are recorded in gempy.log; frontend output containing authenticated browser URLs is never copied into that log.

Each character has gempy-<Character>-prime and gempy-<Character>-test profiles in ~/.vellum-fe/launcher.toml. They use Lich mode, web_client = "despana", web_port = 0 for automatic allocation, and all-interface web binding (0.0.0.0) for LAN access. Gempy allocates an available loopback web port and passes it explicitly to Vellum, so installed builds that open port-zero browser URLs still open the correct session. Existing per-character Vellum settings are reused. Vellum opens the authenticated browser URL itself. Gempy starts Lich, waits passively for its detachable listener, and supplies the actual port when launching the matching saved profile. Existing Lich sessions are reused only when their character and realm match.

The shared configurations were backed up beside the originals as entry.yaml.gempy-20260930-backup and launcher.toml.gempy-20260930-backup. Saved passwords remain in Lich.

Ruby runtime: Ruby 4.0.3 is installed at ~/.local/ruby-4.0.3 with Lich's runtime gems, GTK, and curses. User executables in ~/.local/bin select this version. ./run.sh also selects this runtime when present; the system Ruby remains available as /usr/bin/ruby.

For existing Profanity configurations, omit frontend or set it to profanity and retain paths.profanity_bin and any profanity_template.

Install test dependencies with .venv/bin/python -m pip install -r requirements-dev.txt, then run launcher, service, and web checks with .venv/bin/python -m unittest -q.

Gemstone Launcher Script

This script provides a terminal-based interface for launching characters in GemstonIV using Lich and the Profanity Front End. It allows you to select characters from your accounts and handles the login process then launches Profanity. It also displays the online status of characters currently logged in on the same computer.

Table of Contents


Prerequisites

Before you begin, ensure you have the following installed on your system:

  • Python 3.10 or higher
  • Ruby interpreter
  • Lich 5 (Lich5) installed and configured
  • Profanity Frontend for the terminal default, or Vellum for Despana/web clients
  • Git (optional, for cloning the repository)

Ensure that the ruby command is available in your system's PATH.

Installation

Clone the Repository

Clone the repository or download the script files into a directory of your choice:

git clone https://github.com/ndoucette/gempy.git
cd gempy

Set Up the Configuration File

The script uses a YAML configuration file named config.yaml. You'll need to create and customize this file based on your setup.

  1. Create the config.yaml File:

    You can create the file manually or copy the sample provided:

    cp config-sample.yaml config.yaml
  2. Edit the config.yaml File:

    Open config.yaml in your preferred text editor and configure the following sections:

    • Paths to Lich and Profanity
    • Accounts and Characters

    Example config.yaml:

    # config.yaml
    
    # Paths to the Lich and Profanity binaries
    paths:
      lich_bin: '/path/to/your/lich.rbw'
      profanity_bin: '/path/to/your/profanity.rb'
    
    # Character accounts and their characters
    accounts:
      AccountName1:
        - CharacterName1
        - CharacterName2
      AccountName2:
        - CharacterName3
        - CharacterName4

Install Dependencies

Install the required Python packages using pip and the provided requirements.txt file:

pip install -r requirements.txt

If you're using Python 3 and pip refers to Python 2, use:

pip3 install -r requirements.txt

Dependencies:

  • PyYAML: For parsing the YAML configuration file.
  • FastAPI and Uvicorn: For the web daemon and authenticated APIs.
  • websocket-client: For authenticated local Vellum connections.

Configuration

Paths to Lich and Profanity Binaries

In the config.yaml file, specify the full paths to your lich.rbw and profanity.rb binaries:

paths:
  lich_bin: '/full/path/to/your/lich.rbw'
  profanity_bin: '/full/path/to/your/profanity.rb'

Notes:

  • Ensure that the paths are absolute (full paths), not relative.
  • Verify that the files exist at the specified locations.
  • The paths should point to the executable Ruby scripts (.rbw and .rb files).

Accounts and Characters

Define your accounts and associated character names under the accounts section:

accounts:
  AccountName1:
    - CharacterName1
    - CharacterName2
  AccountName2:
    - CharacterName3
    - CharacterName4

Important:

  • Character names are case-sensitive. Ensure they match exactly as required for login.
  • You can add as many accounts and characters as you need.
  • Account names are used as headers in the terminal interface.

Usage

Running the Script

To launch the script, navigate to the directory containing launcher.py and run:

./launcher.py

If the script is not executable, you can make it executable:

chmod +x launcher.py

Alternatively, run the script using Python:

python launcher.py

Navigating the Interface

Once the script is running, you'll see a terminal-based interface displaying your accounts and characters.

Key Action
Arrow keys Move between accounts and characters
Enter Log the selected character in
t Toggle between the prime and test servers
r Refresh online status
Esc Quit

Prime vs. test server

The right-hand side of the bottom status bar always shows which server you're about to log into — green for prime, magenta for test. Press t to toggle; the [Online] markers refresh to show who is logged in on that server, since a character can be on prime and test at the same time and each gets its own Profanity port.

Test logins pass --gemstone --test to Lich, which resolves to game code GST. Lich falls back to your existing prime (GS3) saved entry for that character, so you do not need to add separate saved logins for the test server.

To start the launcher on the test server by default, set default_realm: test in config.yaml.

Important Notes

  • Terminal Size: Ensure your terminal window is large enough to display the interface. If it's too small, you'll be prompted to resize.
  • Case Sensitivity: Character names in the configuration file are case-sensitive. Enter them exactly as required.
  • Dependencies: All required dependencies must be installed. Use the provided requirements.txt file.
  • Environment Variables:
    • The script sets TERM to screen-256color.
    • If DISPLAY is not set, it defaults to :0.

Troubleshooting

  • "Unsupported Operating System" Error:
    • Ensure you're running the script on a supported system (Linux, macOS, or WSL).
  • "Configuration File Not Found" Error:
    • Verify that config.yaml exists in the same directory as launcher.py.
  • "LICH_BIN path does not exist" Error:
    • Check that the path to lich.rbw is correct and the file exists.
  • "PROFANITY_BIN path does not exist" Error:
    • Check that the path to profanity.rb is correct and the file exists.
  • Terminal Rendering Issues:
    • If the interface doesn't display correctly, try running the script in a different terminal emulator.
  • Permission Denied Errors:
    • Ensure that launcher.py is executable.
    • Verify permissions on the Lich and Profanity binaries.
  • Ruby Not Found:
    • Ensure that Ruby is installed and the ruby command is available in your PATH.

License

This script is provided under the MIT License. You are free to use, modify, and distribute it as per the terms of the license.


Enjoy your gaming experience! If you encounter any issues or have suggestions for improvements, feel free to contribute or open an issue.


About

A multi front-end launcher for Gemstone IV

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages