User report: Twilight Forest 'Charm of Keeping' + ReviveMe interaction loses
inventory over multiple deaths. Analysis concludes this is a Twilight/ReviveMe
event-priority interaction, not a PlayerSync bug — but two dead config options
hid admin-facing levers that help mitigate the case.
(1) save_on_death was declared in JdbcConfig but NEVER read in code. The death
snapshot ran unconditionally. Now gated: setting save_on_death=false
disables the LivingDeathEvent-driven pre-drop snapshot. The normal
onPlayerLogout save still fires on disconnect, so nothing is lost — but
admins diagnosing a keeping-charm interaction can quickly turn off the
aggressive death snapshot to rule PlayerSync in or out.
(2) save_on_respawn was also declared but never read. Added a new
@SubscribeEvent PlayerEvent.PlayerRespawnEvent handler that calls
snapshotAndQueueSave(player, 'RESPAWN') after the respawn completes.
This captures the post-death state AFTER keeping-charms / Corail
Tombstone / similar mods have restored their preserved items, so
PlayerSync's DB row reflects the actual post-respawn inventory rather
than the pre-drop snapshot from onPlayerDeath.
Excludes end-portal exit (isEndConquered) since that's not a death
respawn — no need to overwrite.
Combined effect: if a player dies, charm-keeps items, respawns, the DB
ends up with:
t=0 death snapshot (pre-drop, full inventory)
t=X respawn snapshot (post-drop, kept items + whatever charm restored)
The respawn snapshot overwrites the death one by virtue of running later.
A disconnect between t=0 and t=X still saves via onPlayerLogout anyway,
so no loss window opens.
No change to the duplication-safety guarantees from Phases 15-18:
onPlayerDeath still checks event.isCanceled() for ReviveMe, the RESPAWN
snapshot goes through the normal snapshotAndQueueSave pipeline with all
the P0-a/b/c guards and the 2-phase-commit logout_started_at tracking.
Answer to the user's question: the keep-charm inventory loss is
overwhelmingly likely to be a ReviveMe x Twilight Forest event-priority
bug outside PlayerSync's control, but this commit exposes two levers
(save_on_death, save_on_respawn) that let admins test whether PlayerSync
is contributing — setting save_on_death=false should make the symptom
unchanged if the root cause is external.
|
||
|---|---|---|
| .github | ||
| compat-mods | ||
| gradle/wrapper | ||
| src/main | ||
| .gitattributes | ||
| .gitignore | ||
| build.gradle | ||
| CHANGELOG.md | ||
| docker-compose.yml | ||
| ERROR_LOG.md | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| LICENSE | ||
| README.md | ||
| settings.gradle | ||
| TEST_PROCEDURE_v2.1.5.html | ||
PlayerSync
PlayerSync is a Minecraft Forge mod that synchronizes player data across multiple servers using a MySQL backend. It allows players to maintain their inventory, equipment, experience, advancements, and more when moving between servers in a network.
Mod Support
Any other mods support is also possible.
Development Setup
Database Setup (Docker)
A docker-compose.yml file is provided for easily setting up a MariaDB database instance for development testing.
- Make sure Docker is installed.
- Inside your work directory run:
This will download the MariaDB image (if not already present) and start a database container in the background.docker compose up -d - Stoppinng the Database
docker compose down
Data Persistence: The database uses a Docker volume, ensuring your data persists even if you stop and restart the containers.
Database Management Tool
The docker-compose.yml also includes an Adminer service, a lightweight database management tool.
- Access Adminer in your web browser at http://localhost:8080.
- Log in using the server with
- username:
playersync - database:
playersync - password: see docker-compose.yml
- username:
For debugging purposes, you can enable use_legacy_serialization to have readable database fields. This can cause crashes and unintended side-effects. Do not enable this on a production server if not absolutely necessary!
Running the Mod
The project uses Gradle for building and running. Use the provided Gradle wrapper (gradlew for Linux/macOS, gradlew.bat for Windows).
- Make sure that the MySQL database you configured is running.
- Run the Server
or on Windows:./gradlew runServer
This task compiles the mod and starts a dedicated Minecraft server instance with the mod loaded in the.\gradlew.bat runServerrundirectory. - Run the Client
or on Windows:./gradlew runClient.\gradlew.bat runClient