- Elixir 99.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| config | ||
| lib | ||
| priv | ||
| rel | ||
| scripts | ||
| test | ||
| .credo.exs | ||
| .dialyzer_ignore.exs | ||
| .dockerignore | ||
| .envrc | ||
| .gitignore | ||
| devenv.nix | ||
| docker-compose.yml | ||
| Dockerfile | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| mix.exs | ||
| mix.lock | ||
| README.md | ||
About
High-Level Alchemy is a game server emulator compatible with the 377 game client. It makes some attempt to emulate the popular MMORPG RuneScape around 2005. The project is a heavy work in progress. Many features are not even considered with the current design(s) and I would classify this as experimental at best.
It is written in Elixir/OTP, leaning on the BEAM for concurrency — a process per player and per NPC, ETS for hot-path data, and a 600ms world tick. A broad slice of gameplay already works: tri-style combat with prayer and special attacks, most gathering and production skills, banking, shops, trading, the quest framework (including Tutorial Island), and a goal-driven bot system used for load testing at thousands of concurrent entities. See the documentation for the full feature list and architecture.
Note
Canonical source: The upstream repository is the authoritative source of truth. Every other copy you may find (Codeberg, etc.) is a mirror.
Issues are disabled. There is no public issue tracker. If you care enough to report a bug or contribute a fix, email a patch to sickday@sickday.sh.
📖 Documentation
Full documentation is available at docs.dunk.works/HighLevelAlchemy/Server.
Requirements
elixir>=1.16Erlang/OTP>=28
bzip2- A database — one of:
postgresql>=14(default)- SQLite — set
HLA_DATABASE_ADAPTER=sqlitefor a single-binary, no-separate-instance setup (recompile required when changing adapters)
- A game cache — you must supply your own (see Game Cache below). None is bundled.
Client
For 377, I use refactored-377 fork
Game Cache
This repository ships no game cache — it contains copyrighted assets that are not ours to distribute. You must source your own 377 cache and place it where the server expects it. By default that is ./cache/<revision>/ (e.g. ./cache/377/); override the location with HLA_CACHE_PATH. For the Docker image the cache is bind-mounted at /cache (see below).
Usage
Nix/devenv
Use devenv to bring up a shell that can service both the game server application and a postgresql database:
$ devenv up # Bring up the Game Server, a PostgreSQL database and run migrations against it.
Docker
The provided docker-compose.yml runs a prebuilt distroless release image. The release is baked with the SQLite adapter, so there is no separate database service — game data lives in the hla_data volume.
Two environment variables are required (compose errors out without them), and the game cache must be bind-mounted at ./cache:
$ export HLA_ADMIN_PASSWORD=... # web admin password
$ export HLA_RSA_ENABLED=false # true to require RSA login encryption (see below)
$ docker compose up
This exposes the game (43594), JAGGRAB (43595), and web admin (4000) ports.
Manual
- Create a
config/.env.dev.exsfile. Fill it in with elixir environment variables.
System.put_env("HLA_DATABASE", "hla-dev")
System.put_env("HLA_DATABASE_USER", "hla")
System.put_env("HLA_DATABASE_PASSWORD","hla")
System.put_env("HLA_DATABASE_HOST","localhost")
System.put_env("HLA_DATABASE_PORT", "5432")
System.put_env("HLA_GAME_HOST", "localhost")
System.put_env("HLA_GAME_PORT", "43594")
System.put_env("HLA_JAGGRAB_PORT", "43595")
System.put_env("HLA_HTTP_PORT", "8080")
- Use
ectoto create the database and run migrations.
$ mix ecto.create
$ mix ecto.migrate
- Run the game server application
$ mix run --no-halt
or (with iex)
$ iex -S mix
RSA Login Encryption (Optional)
RSA encrypts the login block between client and server. Disabled by default — both sides must match.
- Generate a keypair:
mix rsa.keygen - Enable on the server:
export HLA_RSA_ENABLED=true - Paste the printed
rsa.*lines into the client'sconfig/server.properties(rsa.rsaEnabled=true,rsa.rsaModulus=…) - Restart both server and client
For Docker, the distroless image has no Mix — generate on a host with Elixir, then drop private.pem into ./priv/rsa (bind-mounted read-only into the container) and set HLA_RSA_ENABLED=true before docker-compose up.
Core Values
This is a labor of love, built for learning and game preservation — nothing more.
- No money, ever. I do not accept donations or monetary contributions of any kind for this project. If you want to support it, contribute your time and your skill — that is worth far more.
- Not for profit — yours or anyone's. I do not endorse, condone, or permit this software being used in any capacity that results in monetary exchange for any party: no paid memberships, no microtransactions, no selling of in-game items or services, no ad-supported or otherwise monetized hosting. If you run a server with it, keep it free.
- Preservation over everything. The goal is to understand and preserve what made these games special, in the open, for free.
These values are not just sentiment — they are encoded in the license.
License
Released under the PolyForm Noncommercial License 1.0.0. You may use, modify, and share this software freely for any noncommercial purpose. Commercial use is not permitted.
Patches submitted (by email — see above) are accepted under the same license.
Disclaimer
This is an independent, noncommercial project for educational and game-preservation purposes. It is not affiliated with, endorsed by, or sponsored by the original rightsholders of RuneScape, and it ships no copyrighted game assets — you must supply your own client and cache.