Ultimate Character
Characters saved on the server: the server is the official source of every character, restores it on join, keeps verified backups and lets admins restore versions.Ultimate Character
Characters saved on the server: the server is the official source of every character, restores it on join, keeps verified backups and lets admins restore versions.
⌨️ PRESS F3 IN THE GAME TO OPEN THE SETTINGS PANEL ⌨️
Every feature of this mod is turned on and tuned in the in-game panel.
Can't use F3? Open the console with F5 and type ultimateqol_config.
⌨️ How to use
- Install and start the game.
- Press F3 to open the settings panel.
- Find the Character options in the sidebar (or type in the search box at the top) and turn on what you want.
Everything is off by default, so the game stays vanilla until you turn something on.
🔑 To change settings you need admin access with devcommands: be listed in the server's
adminlist.txt(on a dedicated server) or be the host of the world. Changes are synchronized to all players in real time.
Features
Characters on the server (CharacterData)
A Characters on the server page (changed by admins only; everything is off by default). When it is on, the server is the official source of every character, not just a backup: the host and the administrators follow the same rules as everybody else.
How it works:
- On the first connection the character is registered on the server (see the first-access policy).
- On every later connection the server restores exactly its last confirmed version of the character before the player enters the world. The client introduces its character right before the game's own join message; the server holds back only that join message until the character has been sent, applied and confirmed by the client, then lets the game admit the player as usual (password, bans, capacity). A banned or non-whitelisted player is refused by the game before any character is sent. If the restore fails, the player is refused with a message and the local character is left untouched. If the server never answers, the client returns to the menu with a message instead of waiting on a black screen.
- While playing, the server saves the characters automatically, one at a time (there is no setting to tune): the player's game reports when something worth saving changed (inventory, equipment, skills, recipes and other knowledge, food, trophies, powers); a changed character is saved about 3 minutes after the change, an unchanged one (idle, only walking) every 10 minutes, and the server waits at least 10 s between two characters, so the work is small and spread evenly. A character is also saved at once on leaving, death, world save, kick and server stop. Each save is verified and written before the next one starts.
- Anything done with the same character on another server or offline is never imported: back on this server you get exactly what this server stored. Items are not merged and nothing is added "by comparison".
- The character stored here is exactly what the game itself saves in the character file: inventory and equipment (quality, durability, variant, crafter and the extra data other mods keep in items), skills, known recipes, stations, materials and texts, trophies, defeated bosses, appearance, Forsaken power and its cooldown, active food and its time, health and stamina, bed/spawn point and logout position, the explored map and pins of every world, and the data other mods keep inside the character. Nothing is rebuilt by hand and unknown data is not dropped. Temporary effects (meads, rested, poison) are not kept, just like when you log out in vanilla.
Settings (all server-side, synchronized from the admin panel):
- Save characters on the server – default off. Players already online are controlled from their next connection (ask them to reconnect once). On a server that is already being played, turn on the import option below together with it, so the existing characters are imported on their next connection. Needs Ultimate QOL on the server and on every PC client; clients without it are refused with a message. Consoles cannot join while it is on.
- First access: allow importing an existing character – default off. Off = only a brand new character (never played in any world) can register; the decision is taken from the real data of the profile, not from what the client says. On = an existing character is imported once, on its first connection, and the server version becomes the official one. The original local character is never deleted in either case. After an archive, only new characters may register until you change this setting.
- Characters per account – default 1, range 1 to 20. The account is the platform account authenticated by the server (Steam or PlayFab), never a name sent by the client. Lowering it later never deletes registered characters.
- Archive characters and start from zero – shown only while the feature is on, with a two-click confirmation. It blocks new saves, disconnects every player (administrator included), moves the whole stored generation to
archives/old_data_<date>_UTCand starts a new empty generation. Nothing is deleted and the world is not touched. A player on a local host session is returned to the menu and the archive is completed when the world is opened again. - Resume the stored characters – when the feature was off for a while, the stored characters may be out of date. They are never matched with local profiles automatically: before players are admitted again an administrator chooses between resuming them or archiving them. Administrators can still join (without their character being controlled or saved) to take that decision.
Where the data is: BepInEx/config/UltimateQOL/CharacterData/world_<WorldUID>/ with state.json, active/characters/<account>/<character>/current.fch (plus metadata.json and backups/) and archives/. Folder names come from the account id and the permanent character id, never from player names. Every version is written to a temporary file, read back and verified before it replaces the previous one; the 5 previous valid versions are kept (one is made at the first save of each play session and then at most every 30 minutes, so they span hours rather than minutes); old, repeated or skipped revisions are refused; a damaged character is never silently replaced or recreated (it is blocked and reported in the server log). On the player's computer, a copy of the local character is kept in BepInEx/config/UltimateQOL/CharacterData/LocalOriginals/ before a restore whenever the local file holds something the server never saw (the 5 newest copies per account are kept).
Leaving and stopping the server. When a player logs out or closes the game (menu, Alt+F4, window), the game waits a few seconds ("Saving the character on the server...", at most 20 s) while the newest version is sent and confirmed by the server; the player cannot act, pick up items or take damage during that wait. Then the game leaves as usual. When the server stops (quit, or the console being closed) it first asks every connected player for their newest version and writes it (at most 15 s). A kicked or banned player's newest version is written before the kick (at most 8 s). Steam connections are closed with linger, so nothing queued is dropped.
Restore a previous version (admins only, on the Characters page). For a character that is stuck (black screen, corrupted inventory, a bad trade) the page lists every stored character (name, when it was last saved, version number, how many older versions exist, and whether the player is online). Pick one, then pick one of its saved versions (date, number, size) and click Restore this version twice (the second click confirms).
- The player, if online, is told why and disconnected. The server first writes their newest version, so nothing is lost; a frozen player that does not answer is cut after a few seconds and the last confirmed version is used.
- While the restore runs the character cannot join ("an administrator is restoring this character"). The server waits for any save of that character to end.
- The content of the chosen version is written as the next revision, with the usual write, read back and verify. The history only grows, no safety rule is relaxed, and the version that was current stays as a backup, so a restore can be undone by restoring that one.
- The player joins again and receives exactly that version. The action is written to
moderation_log.txt. A player who hosts the world cannot be restored while hosting. Only the character goes back, not the world: items moved to or from chests after that version are not undone, and the explored map and position go back too, so prefer a version made before the problem started.
Known limitations (please read):
- A crash is not a logout. If the game or the server crashes (or the internet drops), the changes since the last save are lost (at most about 3 minutes of activity). The world and the character can then be a little apart (for example an item that is both in a chest and in the inventory). Backups are kept, but an old backup is never loaded automatically over a newer world.
- If the server does not confirm the leaving save within 20 s (very slow line), the game leaves anyway and the last confirmed version is used next time.
- While a joining player's character is being restored, the Kick players without the mod timer waits.
- Data other mods keep outside the character file is not saved or restored. A restored character that contains an item this installation cannot create is sent back to the menu and the server version is not overwritten.
- A restore replaces the whole local character in memory, including the data of other worlds stored in it; the local original is kept in
LocalOriginals/. - Console (Xbox) players cannot join a server that controls characters.
- A very small new version (less than a fifth of the stored one) is refused instead of replacing a real character.
⚠️ Experimental
This mod is still experimental and may contain bugs. Back up your world and your character, and turn features on a few at a time.
💬 Bugs and suggestions
Join the Discord: discord.gg/aMkN89Cuas
Powered by Ultimate QOL, installed automatically as a dependency. The F3 panel also shows its other options, all off by default.
