Suite 19 — Closed¶
Highlights¶
- Ability trigger system (
rpg-api 0.4.2,rpg-core 1.2.0) —~on_hit,~on_hurt,~on_jump,~passive, plus~on_attack,~on_kill,~on_block(rpg-core 1.5.0). Mob triggers extended with~onAttack,~onKill,~onJump. - 10 new built-in ability effects (
rpg-core 1.3.0) —knockback,blink,chain,zone,shield,drain,mark,launch,freeze,restore_mana. 5 showcase mobs added. - Ability DSL
chance{}gate (rpg-core 1.5.1,rpg-api 0.5.1) — inline probability gate; blocked flag propagated through pipeline; stacking = AND logic. - Loot pool system (
rpg-core 1.4.0,rpg-api 0.4.3) — named reusable loot pools; mobs reference by ID; vanilla XP + combat XP per pool. - Enchanting: vanilla XP cost (
rpg-enchanting 0.5.0) —XpCost:field wired; levels shown in GUI and deducted on apply. - NPC command overhaul (
rpg-npcs 0.6.0) — per-NPC entity types, in-game dialogue/shop editing, look-at-player,/npc info. - Timed cooking + brewing (
rpg-cooking 0.4.0,rpg-alchemy 0.4.0) —CookTicks/BrewTicksnow drive a progress bar + DataStore-persisted mid-craft state. - New addon plugins —
rpg-homes 0.1.0(player homes + server warps) andrpg-kits 0.1.0(starter/reward kits). - Damage indicators polish (
rpg-core 1.5.2) — sin-arc position + linear scale shrink 1→0. - Resource pack auto-delivery (
rpg-core 1.5.2) —resource-pack:config block; sends pack on join.
Granular dev log (archived)¶
Archived format
The entries below are the granular per-change development log maintained during Suite 19. New entries are no longer added here.
rpg-core 1.2.0 + rpg-api 0.4.2¶
- Ability trigger system: item
Abilities:entries now support a~triggerprefix. Supported player triggers:right_click(default, backwards-compatible),left_click,shift_right_click,shift_left_click,on_hit,on_hurt,on_jump,passive. Active triggers (right_clicketc.) gate on mana cost if the sequence includesmana_cost{}. Passive/proc triggers (on_hit,on_hurt,on_jump,passive) fire freely with no mana gate unless explicitly added. - Passive ability infrastructure:
PassiveAbilityFirercollects trigger-matched bindings from all equipped items + active set bonuses and fires them. New event listeners:PlayerHitAbilityListener(on_hit),PlayerHurtAbilityListener(on_hurt),PlayerJumpAbilityListener(on_jump). New task:PlayerPassiveAbilityTaskfirespassivebindings on a configurable interval (abilities.passive-interval-ticksinconfig.yml, default 20). - Left-click + shift variants:
ItemAbilityListenerextended to handleLEFT_CLICK_AIR,LEFT_CLICK_BLOCK, and sneaking variants of both click types. - Armor set system: sets defined in
plugins/rpg-core/sets/*.yml. Each set names piece IDs and threshold tiers.ArmorSetListenerdetects piece count changes on armor events and writes toCoreRpgPlayer.setSetBonusStats()— a new Layer 2.5 in the stat pipeline (after equipment, before accessories). Set passive ability bindings are tracked per-player and queried by proc listeners. - Scale: support on set bonuses:
Scale: 0.5on aSetBonusmultiplies all numeric ability params at load time, deriving weaker tiers automatically without duplicating effect strings. - Set lore on items:
CoreRpgItem.toItemStack()renders a set membership block showing set name + each tier's stat bonuses and trigger hints, above the rarity line. - New
RpgServicesentry:armorSets()/setArmorSets(ArmorSetRegistry). - New API types:
PlayerAbilityTrigger,ItemAbilityBinding,ArmorSetDef,ArmorSetRegistry,SetBonus. RpgItemadditions:triggeredAbilities()(new canonical method),setId().abilities()kept as backwards-compat alias returning right-click invocations.
rpg-core 1.1.6¶
- GUI nav bar standard on all GUIs: BankerGui, NPC shop expanded to 54 slots with a close button at slot 49.
rpg-npcs 0.6.1¶
- GUI nav bar added to BankerGui and NPC shop GUIs.
rpg-enchanting 0.4.1, rpg-cooking 0.3.1, rpg-alchemy 0.3.2¶
- GUI pagination + redesign: enchanting station paginated (14 enchants/page, prev/close/next nav bar). Cooking and brewing stations redesigned to 54-slot layout — ingredient slots at row 1 center (12, 13, 14), recipe tiles in rows 2–4, paginated nav bar in row 5.
rpg-api 0.4.1, rpg-core 1.1.5, rpg-npcs 0.6.0, rpg-trade 0.1.1¶
- GUI nav bar standard:
GuiConfig.placeNavBar(inv)/placeNavBarNested(inv)API. Close button (BARRIER, slot 49) on all top-level GUIs; back button (ARROW, slot 45) + close button (slot 53) on nested GUIs. PDC-tagged viarpg:nav_actionkey.TradeGuicancel button moved to slot 49.
rpg-npcs 0.6.0¶
- NPC command overhaul: new subcommands
/npc setentitytype,/npc setstyle,/npc setskin,/npc dialogue,/npc shop,/npc setlook,/npc info. Full tab-complete including quest IDs (soft-dep reflection).saveOnly()for dialogue/shop edits avoids entity respawn flicker. - Per-NPC entity type:
EntityType:field in npc.yml.setentitytypevalidates againstLivingEntitysubtypes (excludes PLAYER). - Look-at-player task: NPCs with
LookAtPlayers: true(default via config) tick everylook-at-players.interval-ticksticks and rotate toward the nearest player withinLookRadiusblocks. Entity-style NPCs use Paper'ssetRotation(yaw, pitch). Fake-player NPCs sendClientboundMoveEntityPacket.Rot+ClientboundRotateHeadPacketvia reflection.
rpg-dungeons 0.0.3¶
- Dungeon enter now teleports the player:
TemplatePaster.run()was missing exception handling arounddst.setBlockData(). In Paper 1.21.4, block writes to freshly-generated void-world chunks can throw; the exception escaped thewhileloop, got swallowed by Bukkit's repeating-task runner, and the task retried the same coordinate forever —onDonewas never called and the player was stuck at "Preparing dungeon...". Fix: wrapped per-block operations intry/finally { advance(); }so a failed block is always skipped and the paste completes. Also wrappedonDone.accept()in a try-catch so callback exceptions are logged at SEVERE rather than silently dropped.
rpg-alchemy 0.3.1¶
- Potions fixed — effects now apply on drink:
PotionDrinkListenerwas incorrectly interceptingPlayerInteractEvent. In Paper 1.21.4 theServerboundUseItemPacketis processed before that event fires, so cancelling there did not reliably suppress the vanilla drink path — the animation played, the item was consumed, and no RPG effects fired. Handler rewritten to interceptPlayerItemConsumeEventinstead: vanilla drives the 1.6-second animation; on completion we cancel the event (suppresses item removal + glass-bottle replacement + vanilla effects) and apply RPG status effects + manually reduce item count. - Example potion IDs corrected:
strength_buff→strength_boost,heal_over_time→regen, matching the status effect IDs actually defined inrpg-core'sstatus-effects/example.yml. PreviouslyCoreStatusEffectService.apply()silently no-oped because the IDs were not in the registry.
rpg-core 1.1.0¶
speedstat wired:EquipmentListenernow setsgeneric.movement_speedon every equipment recalc. Formula:0.1 × (1 + speed × speedPerPoint / 100), wherespeedPerPointcomes fromstats.speed-per-pointinconfig.yml(default 1.0). Applied on join and all gear changes.swing_rangestat wired:EquipmentListenersetsentity_interaction_range(melee reach) on every recalc. Formula:3.0 + swingRange × blocksPerPoint(config:stats.swing-range-per-point, default 1.0).swing_range: 2= 5.0-block reach.ferocitystat wired:DamagePipelineListenernow fires extra melee swings after each hit. Each 100 ferocity = 1 guaranteed extra hit; the remainder is a fractional % chance. Extra hits deal the samefinalDamage(crit already factored), firePostDamageEventfor indicators, but skip knockback and lifesteal. Cap:ferocity.max-extra-hits(default 10).- Three new config sections:
stats.speed-per-point,stats.swing-range-per-point, andferocity.max-extra-hitsadded toconfig.yml.
rpg-core 1.0.7¶
projectile_speedstat is now a % bonus (was a direct multiplier).projectile_speed: 25now means 25% faster than vanilla, not 25×. Formula:speedMult = 1.0 + stat / 100.0. Zero/absent stat = vanilla arrow speed unchanged.
rpg-core 1.0.6¶
- Player melee damage fix:
DamagePipelineListenernow reads the player's RPGDAMAGEstat as the melee base, the same way mob attackers already did. Previously,event.getFinalDamage()was used — but since all vanilla attack-damage attributes are removed from custom items, that returned1.0, causing swords to deal ~1 damage regardless of stats. - Wand ability damage fix:
beam_wandandglacial_staffnow have adamagestat (30and50respectively). Without it,carriedDamage = 0while holding the wand, making alldamage_multiplier-based ability effects deal zero. - Damage indicators for ability hits:
DamageEffectandExplodeEffectnow firePostDamageEventafter each damage application, so floating damage numbers appear for wand abilities and mob AoE explosions.
rpg-core 1.0.5¶
- Hurt animation fix:
CoreHealthService.damage()now callsentity.playHurtAnimation(0f)after reducing HP. Previously, bypassingEntityDamageEventmeant vanilla never sent the red-flash status packet — arrows and mob abilities dealt damage silently with no visual feedback. - Mob ability exception logging:
MobAbilityRuntime.cast()now logs a warning when an ability chain throws instead of silently swallowing the error. - Example items — knockback added:
aspect_of_test,iron_shortsword,voidblade,hunters_bow,beam_wand, andglacial_staffnow include aknockbackstat so the mechanic is demonstrated out of the box.
rpg-core 1.0.4¶
- AbilityLoader unknown-field warning: loading an ability YAML that contains an unrecognized top-level field (e.g.
ManaCost: 50,CombatXpMultiplier: 1.0) now logs a console warning naming the field and pointing to the correct pattern (mana_cost{amount=N}inAbilitySequence). Previously these fields were silently ignored — abilities appeared to have a mana cost in config but never deducted any mana at runtime.
rpg-npcs 0.5.1¶
- NPC click fix — orphan sweep:
NpcManager.loadAll()now callssweepOrphanedEntities()beforedespawnAll(), scanning every loaded world for entities carrying therpg_npc_idPDC key and removing them. Previously, NPCs withsetPersistent(true)survived server restarts and plugin reloads; each reload stacked a new copy on top, causing visual overlap and unreliable interaction resolution. - NPC click fix — entity type default: changed default
display.body-entityfromVILLAGERtoZOMBIE. Paper's villager trade GUI can interfere with right-click handling even whenPlayerInteractEntityEventis cancelled. - NPC click fix — handler priority:
NpcInteractListener.onInteractchanged fromLOW / ignoreCancelled = truetoNORMAL / ignoreCancelled = false. NPC interactions now fire even if a third-party plugin pre-cancelled the event.
rpg-core 1.0.3¶
- Attack cooldown fix:
CoreRpgItem.toItemStack()now explicitly removes vanilla attribute modifiers (ATTACK_DAMAGE,ATTACK_SPEED,ARMOR,ARMOR_TOUGHNESS,KNOCKBACK_RESISTANCE) from every custom item'sItemMeta. PreviouslyHIDE_ATTRIBUTEShid them from the tooltip but they still applied — holding an iron-based sword applied a-2.4ADDITION togeneric.attack_speed, making oursetBaseValue()resolve to a negative value and the attack bar never fill. - Currency drops from mob loot tables:
CoreLootTablenow supports acurrency-rolls:section ({ chance, min, max }entries).MobLootListenercallsrollCurrency()after item rolls and deposits the result viaRpgServices.economy()directly to the player's balance. Requiresrpg-economy; silently skipped if not loaded. Update mob YAMLs to usecurrency-rolls:for coin drops instead of spawning coin item entities.
rpg-mining 0.2.1¶
- Mining fatigue suppression fix: default amplifier changed from
1(Fatigue II — slows but doesn't prevent mining) to255(effectively infinite break time). Vanilla blocks can no longer be mined at all while holding an RPG gathering tool. Configurable inplugins/rpg-mining/config.ymlundermining-fatigue.amplifier.
rpg-trade 0.1.0 (new plugin)¶
/trade <player>— sends a trade invite (30s expiry, configurable). Target accepts with/trade accept, declines with/trade deny. Either party can cancel at any time with/trade cancel.- Trade GUI (54-slot): your 3×3 item offer on the left, the other player's items on the right (read-only). Coin amount set by clicking the sunflower button and typing in chat. Both players must click Confirm Trade; a configurable countdown (default 5s) then fires before items and coins swap atomically. Either player can click the button again during countdown to cancel.
- Bait-and-switch prevention: modifying your offer after clicking Confirm resets your confirmation state.
- Coin safety: balances are checked and deducted atomically at swap time; if either player can't afford their offer, all items are returned and the trade fails.
- Item return on cancel: all items in the GUI are returned to their owners on close, disconnect, or
/trade cancel. - Permission:
rpg.trade.use(default: true). - Config:
trade.countdown-seconds,trade.invite-expiry-seconds,trade.max-coins.
rpg-api 0.3.0¶
RpgItem.tradeable(): new default interface method returningtrue. Items withTradeable: falsein their YAML returnfalse; the trade GUI rejects them with a message.
rpg-core 1.0.1¶
Tradeable: falseitem flag:CoreRpgItemandItemLoadersupport the newTradeablefield. Non-tradeable items show&c✘ Not Tradeableat the bottom of their lore.
rpg-cooking 0.3.0¶
- GUI formatting pass: title is now bold (
&6&l). Background panes read fromrpg-coregui.background-materialconfig viaGuiConfiginstead of being hardcoded orange. Recipe tiles now suppress italic on all lore lines and show a&8▶ &7Left-click to cookaction hint when the recipe is satisfiable.
rpg-alchemy 0.3.0¶
- GUI formatting pass: title is now bold (
&d&l). Background panes read fromGuiConfiginstead of hardcoded purple. Recipe tiles now suppress italic on all lore lines and show a&8▶ &7Left-click to brewaction hint when satisfied.
rpg-enchanting 0.3.0¶
- GUI formatting pass: titles are now bold (
&5&l). Background panes read fromGuiConfig. The enchant result button, reforge options, and upgrade options each show a&8▶ &7Left-click to …action hint in lore.simple()cleaned up to use the sharedLEGACYfield; newsimpleWithHint()helper added for the hint pattern.
rpg-npcs 0.4.0¶
- BankerGui formatting pass: title is now bold (
&6&l). HardcodedCYAN/GRAYfillGlasscalls replaced withRpgServices.guiConfig().fillBackground(inv)— background pane material is now admin-configurable. Deposit and withdraw buttons suppress italic on their display names and show&8▶ &7Left-click to deposit / withdrawaction hints in lore. Removed unusedfillGlasshelper.
rpg-core 1.0.0¶
- Block holograms: custom block definitions now support an optional
Hologram: "&6Text"field (andHologramYOffset: 1.2). ATextDisplayentity is spawned above every placed instance of that block type, centered over the block, at the configured Y offset above its top surface. Holograms despawn when the block is broken and re-spawn after respawn cycles. On plugin enable, stale entities from the previous session are swept before fresh ones are created. Add to any block YAML:Hologram: "&6⚗ Brewing Station". - Per-player GUI isolation confirmed:
CookingGui,BrewingGui, andStationGuieach create a brand-newInventoryobject peropen()call. Two players clicking the same station block simultaneously receive independent inventories — no shared state, no interference. Added clarifying Javadoc to all three GUIs.
rpg-regions 0.5.0¶
- Global region in
/regioncommands:/region listnow shows[global]as the first entry (with its current flag count)./region flag __global__ <flag> <value|clear>is a new alias for/region global flag— admins can manage the world-wide region using the same flag command they use for named regions. Tab-complete on/region flagnow suggests__global__as the first option.
rpg-alchemy 0.2.0¶
- Brewing shift-click fix: shift-clicking an ingredient from the player's inventory into the Brewing Station GUI now routes it to the first free input slot (same pattern as CookingGui). Previously the click was silently ignored.
rpg-enchanting 0.2.0¶
- Enchanting/Anvil station shift-click fix: shift-clicking an item from the player's inventory into the Enchanting Table or Custom Anvil GUI now places it directly into the input slot if it's empty. Previously the click passed through without being routed.
All plugins (config docs)¶
- Config examples everywhere: added inline YAML comments with descriptions, valid ranges, and examples to every configurable field across all 20
config.ymlfiles (rpg-core, rpg-combat, rpg-regions, rpg-economy, rpg-npcs, rpg-cooking, rpg-alchemy, rpg-enchanting, rpg-mining, rpg-foraging, rpg-fishing, rpg-farming, rpg-hud, rpg-chat, rpg-parties, rpg-guilds, rpg-accessories, rpg-holograms, rpg-quests, rpg-dungeons, rpg-admin). No behavior changes — docs only.
rpg-core 0.9.0¶
- Potions fix:
VanillaSuppressionListenernow defaultsvanilla-suppression.potionstofalse— vanilla potions work correctly (effects apply, items consumed as expected). Previously the defaulttruesilently swallowed every potion effect while still consuming the item. Set totruein config to re-enable suppression when a proper RPG potion→status-effect converter is added. - Custom block auto-registration on place:
/rpg block giveitems now carry arpg_block_idPDC tag. NewBlockPlaceListenerfires onBlockPlaceEvent(admin+creative only) and automatically callstagLocation()+ saves persistence — no more needing/rpg block convertafter placing. Action bar confirmation shown on successful registration. - Tab completions —
/rpg: now completes all 10 subcommands (was only 5);/rpg wand modenow completes mode names;/rpg particle delete/movecompletes existing particle IDs;/rpg loot-chest definecompletes loot table IDs;/rpg effectscompletes online player names.
rpg-regions 0.4.0¶
- Tab completions:
/region globalnow completesinfo/flag;/region global flagcompletes known flag names andtrue/false/clear;/region infono longer incorrectly suggests region IDs (it uses player location, not an ID argument);/region flagvalue arg now also suggestsclear.
rpg-quests 0.0.3¶
- Tab completions:
/quest complete <player>now completes online player names;/quest complete <player> <questId>completes quest IDs.
rpg-core 0.8.0¶
- Damage NPE fix:
DamageMath.statOf()now null-guards the entity argument — fall damage, campfire, and other non-attacker damage sources no longer throwNullPointerException. - Damage pipeline priority:
DamagePipelineListener.onDamagemoved fromLOWESTtoNORMAL(ignoreCancelled = trueunchanged). This lets lower-priority listeners (e.g. NPC protection) cancel the event before the pipeline runs, eliminating damage indicators on protected entities. - Custom block break permission: creative-mode bypass now requires
rpg.adminin addition toGameMode.CREATIVE. Non-admin creative players can no longer break custom blocks; onlyrpg.adminadmins can.
rpg-npcs 0.3.0¶
- NPC damage indicators fixed:
NpcProtectionListenerdamage/targeting handlers moved fromHIGHESTtoLOWESTpriority — they now cancel the event beforeDamagePipelineListener(atNORMAL) runs, preventing hit-indicator animations on NPC entities. - Double name tag fixed: entity-style NPCs no longer have
customNameset on their body entity when the TextDisplay overlay is active. Hovering over the entity no longer shows a second name tooltip.
rpg-cooking 0.2.0¶
- Slot layout redesign: ingredient slots moved to row 0 center (slots 4, 5, 6); recipe tiles now start at slot 9 (row 1) and fill forward across the grid.
- Shift-click fix: shift-clicking an ingredient from the player's inventory now correctly routes it into the first free input slot instead of silently failing or landing on a pane tile.
rpg-npcs 0.2.0¶
- Damage bug fix:
NpcProtectionListenercancels all damage and mob-targeting events for NPC entities atHIGHESTpriority, and respawns the NPC after one tick if it somehow dies. Belt-and-suspenders on top ofsetInvulnerable(true). - Fake player NPCs:
EntityStyle: playerspawns a packet-only fake player with a customGameProfile. Skins configured via raw textureValue/Signatureor byName(fetched async from Mojang API, cached). Not shown in tab list — brief ADD packet sent for skin load, removed after 2 ticks. New players on join receive the skin packet for all active fake player NPCs. - Banker behavior:
Behavior.Type: bankeropens a deposit/withdraw GUI backed byDataStore. Bank balance persisted per-player per-NPC. Daily interest accrues atDailyInterestPercenton a configurable real-time interval. Requiresrpg-economy. /npc setbehaviornow acceptsbanker [bankName]and updates tab-complete to include it.
rpg-api 0.2.0¶
- Added
StationServiceinterface (api/station/) withregister(stationType, handler)andopen(stationType, player, block). Accessible viaRpgServices.stations().
rpg-core 0.7.0¶
- Station dispatch: new
CoreStationServiceimplementation +BlockInteractListener. Right-clicking any custom block withInteractable: trueand a non-emptyStationTypenow routes throughRpgServices.stations(). Addons register their GUI handler once inonEnable; rpg-core handles event cancellation.
rpg-cooking 0.1.0¶
- Station interaction now wired through
RpgServices.stations().register("cooking", ...)— no longer needs a per-block-id config key. Removedcooking-blockconfig key andCookingStationInteractListener.
rpg-alchemy 0.1.0¶
- Station interaction now wired through
RpgServices.stations().register("brewing", ...). Removedbrewing-blockconfig key andBrewingStationInteractListener.