API contract
Use com.fyxe.ffdeathrules.api.DeathRulesApi, RulePatch and immutable DeathRules. API_VERSION is "1". Partial patches use the same keys/value syntax as operator commands. Access persistent state and resolve rules on the server thread. Register providers during initialization, then close their returned AutoCloseable handles when your integration unloads. Callbacks must not mutate provider registration during resolution.
Live team provider
A team mod can return a patch based on its own membership system. Returning null/empty inherits existing rules. Providers apply after permission and scoreboard-team profiles, ordered by ascending priority then ID; explicit player overrides apply last. Exceptions are logged and that provider is skipped. Validate your team's combinations so XP drop plus keep stays at most 100.
AutoCloseable registration = DeathRulesApi.registerProvider(
"myteams:death_rules", 100, player -> {
// Replace this condition with your team's membership lookup.
if (player.getTeam() == null || !player.getTeam().getName().equals("Builders")) {
return RulePatch.empty();
}
return new RulePatch(Map.of(
"inventory", "HOTBAR",
"keepArmor", "true",
"xpDropPercent", "25",
"xpKeepPercent", "-1",
"messageAudience", "TEAM"));
});
Persistent overrides
// These calls replace the partial patch and save immediately.
DeathRulesApi.setPlayerRules(server, playerUuid,
new RulePatch(Map.of("inventory", "ALL", "xpDropPercent", "0")));
DeathRulesApi.setTeamRules(server, "Builders",
RulePatch.of("keepArmor", "true"));
RulePatch current = DeathRulesApi.playerRules(server, playerUuid);
DeathRulesApi.setPlayerRules(server, playerUuid,
current.with("messageAudience", "SELF"));
// Empty removes the player override so lower-priority rules apply.
DeathRulesApi.setPlayerRules(server, playerUuid, RulePatch.empty());
DeathRules effective = DeathRulesApi.resolve(serverPlayer);
Team profiles keyed by vanilla scoreboard team names follow live membership. A separate team mod should use a provider or maintain player UUID overrides itself. Providers/resolvers are runtime registrations and must be registered each startup; persisted setter changes survive restarts. Persistence failures throw and roll back the change.
Permission bridge
// Replace permissionsService.hasPermission with your permission system.
AutoCloseable resolver = DeathRulesApi.registerPermissionResolver(
"mypermissions:death_rules",
(player, node) -> permissionsService.hasPermission(player.getUUID(), node));
Create permission profiles through OP commands, or the world rule file. A positive resolver, exact built-in grant or matching op.0–op.4 threshold grants the profile. False from a resolver does not revoke a positive grant from another source. No permission-mod dependency is bundled or automatically detected.
Death lifecycle and compatibility
Rules snapshot once at death, after loader death-cancellation hooks. Item selection runs in vanilla Player.dropEquipment; restoration runs after ServerPlayer.restoreFrom. Ordinary dropped items still use loader capture/drop callbacks. Custom XP amounts and bottles replace vanilla XP emission; consumed XP flags are honored. The public API configures vanilla inventory only, not third-party accessory slots or grave contents. Avoid replacing the same death drops independently; test integrations in game.
Build against the appropriate per-target artifact com.fyxe.ffdeathrules:ffdeathrules-<minecraft>-<loader>:0.2.0 after publication. Until then, use the local Maven publication from this project. API examples require imports for java.util.Map and the three FFDeathRules API classes.