Skip to content

API Reference

OneGunLifetimeAPI exposes static methods for other mods to use the soul-binding capability programmatically, without relying on commands. Methods are grouped by function.

Common conventions: mutating methods require a ServerPlayer (server-authoritative) and return result objects instead of throwing business exceptions; query methods accept a Player. Plugin changes go through the ModularShoot install/uninstall pipeline — soul data write-back, server-wide broadcast and attribute refresh happen automatically.

Queries

SignatureParametersReturnsDescription
getSoulData(Player player)player — target playerOptional<SoulData>The player's soul data (template gun, stat overrides, traits, plugins, gun state, ...); empty when unbound
isBound(Player player)player — target playerbooleanWhether the player has a soul binding
getOwnerOf(ItemStack gunStack)gunStack — any item stackOptional<UUID>If the stack is a player's projection gun, returns its owner UUID; empty otherwise
getPlugins(Player player)player — target playerList<PluginInstance>The current ordered plugin list; empty when unbound
getGunState(Player player)player — target playerOptional<CompoundTag>Runtime gun state NBT; empty when unbound
getEffectiveValues(ServerPlayer player)player — target playerMap<ResourceLocation, Double>Final values of every player-applicable logical attribute (base + overrides + traits + plugin bonuses); empty when unbound. The map iterates in attribute_meta registry order. Pure computation with no entity access — cache the result for frequent calls

Lifecycle

SignatureParametersReturnsDescription
bindAndGive(ServerPlayer player, ResourceLocation templateGunId)player — target player; templateGunId — registered template gun idBindResultOne-step bind: validate the template registration → bind the soul → give a fresh projection gun (dropped at the player's feet when the inventory is full) → refresh attributes
unbindAll(ServerPlayer player)player — target playerbooleanFull unbind: unbind + clear every attribute modifier mounted by this mod + remove the owner's projection guns from main inventory, armor and offhand. Returns false when unbound (idempotent)
rescan(ServerPlayer player)player — target playervoidForces one full inventory scan now (dedup, foreign-gun assimilation, projection recovery, plugin backfill); no effect for unbound players

Stats & Traits

Validation included: attribute ids must exist in the modularshoot:attribute_meta registry, trait ids in modularshoot:traits, and values must be finite doubles.

SignatureParametersReturnsDescription
setStatOverride(ServerPlayer player, ResourceLocation key, double value)key — logical attribute id; value — new valueMutationResultWrites one stat override and refreshes
removeStatOverride(ServerPlayer player, ResourceLocation key)key — logical attribute idMutationResultRemoves one stat override and refreshes
clearStatOverrides(ServerPlayer player)MutationResultClears all stat overrides and refreshes
addTrait(ServerPlayer player, ResourceLocation traitId)traitId — trait idMutationResultAdds a trait and refreshes
removeTrait(ServerPlayer player, ResourceLocation traitId)traitId — trait idMutationResultRemoves a trait and refreshes

Plugins & Gun State

SignatureParametersReturnsDescription
addPlugin(ServerPlayer player, ResourceLocation pluginId)pluginId — plugin definition idPluginChangeResultInstalls a plugin by id onto the player's projection gun, reusing the full ModularShoot install validation (slot type, capacity, lock). The installed copy is written back to its slot; rejection details in rejectionReason(). Returns NO_PROJECTION instead of silently creating a gun when the player has no projection gun
removePlugin(ServerPlayer player, UUID pluginInstanceUuid)pluginInstanceUuid — plugin instance UUIDPluginChangeResultRemoves one installed plugin by instance UUID (no force); the removed plugin item is returned to the player's inventory (dropped at their feet when full). Rejections carry the structured uninstallReason() (locked / UUID not found / ...)
setGunState(ServerPlayer player, CompoundTag state)state — new gun state NBTMutationResultReplaces the runtime gun state. Returns NOT_BOUND when unbound

Result Types

BindResult (enum)

ValueMeaning
SUCCESSBound; the player has received a projection gun
ALREADY_BOUNDThe player already has a soul binding
NOT_REGISTEREDThe template gun id is not registered in ModularShoot

MutationResult (enum)

ValueMeaning
SUCCESSOperation succeeded
NOT_BOUNDThe player is not bound
INVALID_ATTRIBUTEThe attribute id is not registered
INVALID_VALUEThe value is not a finite double
INVALID_TRAITThe trait id is not registered

PluginChangeResult (record)

MemberDescription
status()SUCCESS / NOT_BOUND / NO_PROJECTION (no projection gun in inventory) / UNKNOWN_PLUGIN (plugin id not registered) / NOT_INSTALLED (rejected by the framework)
uninstallReason()Structured uninstall rejection reason (UninstallResult.Reason enum: locked, UUID not found, ...); non-null only when an uninstall was rejected by the framework
rejectionReason()Localizable install rejection reason (framework install error message); non-null only when an install was rejected by the framework
success()Convenience check: status == SUCCESS

Usage Example

java
// One-step bind: bind + give gun + refresh attributes
BindResult result = OneGunLifetimeAPI.bindAndGive(
        player, ResourceLocation.fromNamespaceAndPath("modularshoot", "demo_pistol"));
if (result != BindResult.SUCCESS) {
    player.sendSystemMessage(Component.literal("bind failed: " + result));
}

// Read the player's effective value panel
Map<ResourceLocation, Double> values = OneGunLifetimeAPI.getEffectiveValues(player);
double damage = values.getOrDefault(
        ResourceLocation.fromNamespaceAndPath("modularshoot", "bullet_damage"), 0.0);

// Programmatic plugin install/remove
PluginChangeResult added = OneGunLifetimeAPI.addPlugin(
        player, ResourceLocation.fromNamespaceAndPath("modularshoot", "scope_basic"));
if (!added.success()) {
    player.sendSystemMessage(added.rejectionReason());
}

Released under the MIT License