Non-intrusive multiplayer for Skyrim. Each player keeps their own world and sees other players as remote actors: movement, animations, combat, appearance, and equipment are shared, while loot, quests, and enemies stay local. Players can trade items and chat.
src/— SKSE plugin (C++23, built with XMake:xmake)server/— Go server (server/README.md)proto/— wire schemaspecs/— how each system works (specs/README.md)
Dockerfile builds the server and the admin panel into one image.
compose.yaml runs it with host networking, so listen,
admin_listen, and trusted_proxies mean what they do without Docker. Copy
server/config.example.toml to server/config.toml, add
admin_ui_directory = "/app/admin-ui", then run the published image:
mkdir -p data
docker compose pull
docker compose up -dRun docker compose up -d --build instead to build the image from this
checkout. Compose tags a local build with the service's image name, so a later
docker compose pull replaces it with the published one. PLAYERHUB_IMAGE
overrides that name (default ghcr.io/b4lex/playerhub-server:latest): set it
to another tag, such as ghcr.io/b4lex/playerhub-server:main, to run that
published image, or to a local name, such as playerhub-server:local, to keep
local builds apart from published ones.
The session database and recordings are kept in data/ next to
compose.yaml (/data in the container). The server runs as user and group
1000, so that directory must be writable by them; set PLAYERHUB_UID and
PLAYERHUB_GID to run it as another host user, such as the one that owns
data/. The container restarts unless stopped.
The server image workflow publishes the
image for linux/amd64 and linux/arm64 as
ghcr.io/b4lex/playerhub-server: main and sha-<commit> from each push
to main that changes the server, the admin panel, or the image, and
<version>, <major>.<minor>, and latest from each release tag such as
1.0.1. Pull requests build it without publishing.
The plugin's text is English, and it reads translations at startup from
gettext PO files in Data/SKSE/Plugins/PlayerHub/locale/. To add a language,
make <code>.po (such as uk.po) from playerhub.pot in that folder with a
PO editor or msginit, set its Language and Plural-Forms headers, and
translate it. If the game has that language, also set X-Skyrim-Language to
its sLanguage value, such as FRENCH. Restart the game, and the language
appears in the settings by the name given in its LanguageName entry. The
log names any entry the plugin could not use. The translations shipped with
the plugin are in locale, and
specs/ui-overlay.md has the details.
Copyright (C) 2026 B4lex
The plugin and server are licensed under GPL-3.0-or-later WITH Modding Exception AND GPL-3.0 Linking Exception (with Corresponding Source): you can redistribute and modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version, with those exceptions. They are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
EXCEPTIONS also holds additional terms under section 7 of the license: a page that offers this program or a work based on it for download must credit it as based on PlayerHub by B4lex with a link to this repository, and a modified version must use another name and not the PlayerHub logo.
The plugin includes third-party libraries, among them CommonLibSSE NG under the same license and exceptions. Each library and its license are listed in THIRD_PARTY_NOTICES.txt, which goes with every copy of the plugin together with LICENSE and EXCEPTIONS.
The settings window is set in Sovngarde by mjorka, shipped unmodified in assets/fonts under the SIL Open Font License 1.1 (Sovngarde OFL License.txt). The font files are not covered by the plugin's license, and the license text goes with them wherever they are distributed.
The frame around the settings window and the chat,
assets/frame/menu-frame.shape, is exported from
the message box art in Skyrim's Interface/messagebox.swf. That art belongs to
Bethesda Softworks and is not covered by the plugin's license; it is included
only so the overlay matches the game's own menus, for use with a copy of
Skyrim. It is kept in its own file rather than built into the plugin for this
reason, and the plugin works without it.
The game's mouse cursor,
assets/cursor/cursor.svg and its glyphs (U+E005
to U+E007) in assets/fonts/PlayerHub.ttf, is exported from Skyrim's
Interface/cursormenu.swf, with a ring in place of its tail, and belongs to
Bethesda Softworks on the same terms:
it is not covered by the plugin's license, is included only for use with a copy
of Skyrim, and is kept out of the plugin's binary, which draws its own cursor
without the font.
The Discord symbol beside the community invitation,
assets/logo/discord.svg and its glyph in
assets/fonts/PlayerHub.ttf, is a trademark of Discord Inc., used unmodified
in Discord's color under its brand guidelines
to link to the mod's Discord server. It is not covered by the plugin's license,
and PlayerHub is not affiliated with or endorsed by Discord.