Verox' RPG Progression
A difficulty and world progression mod inspired by games like Terraria.
Verox' RPG Progression
Terraria-style world progression - bosses gate items, blocks, ores, dimensions, and mob difficulty as the world advances through stages. Formerly known as Unbound World, now part of the Verox' RPG series.
Overview
RPG Progression locks the world into a starting state called Sealed World. Defeating a stage's designated boss advances the world's stage order by one, which can unlock:
- Items and tools/armor sets
- Blocks (functional blocks like Enchanting Tables, or ore blocks)
- Dimensions
- Additional optional ("preparation") bosses
- Increased mob health, damage, knockback resistance, armor, and any other attribute
- Custom equipment on humanoid mobs
- Territories - structures that punish early visitors and stay protected until their boss falls
Bosses also drop individually rolled loot bags for every nearby player instead of ground loot (can be turned off), and every player receives the Progression Journal, an in-world book that tracks the whole journey.
Progression is world-wide, not per player. Every player on the server shares the same unlocked stage.
RPG Progression does not generate its own bosses or dimensions - new biomes, structures and bosses come from the companion mod Verox' RPG Journey. RPG Progression reads stage definitions from data-driven JSON files and reacts to vanilla (or modded) entity kills, block breaks, and dimension travel.
Supported environment
- Minecraft
1.21.1, 26.1.2 - NeoForge
- Optional soft dependencies: Jade (tooltip integration)
- Mod ID:
verox_rpg_prog
Core concept: World Stage
The world's progress is tracked as a single integer, the unlocked order, stored persistently per-world.
| Value | Meaning |
|---|---|
-1 | Sealed World - nothing unlocked yet |
0 | First stage cleared |
1, 2, 3... | Subsequent stages cleared, in order |
An item, block, ore, dimension, or boss is locked if the stage that owns it has an order greater than the current unlocked order. Defeating that stage's main boss advances the world to that stage's order, unlocking everything registered to it at once.
Stage data files
Stages are defined as JSON files at:
data/<namespace>/stages/<stage_name>.jsonThe reload listener scans every namespace for a stages folder - the file's own namespace does not need to match the mod ID, and the filename itself has no meaning to the game (it is not read as part of the stage's identity).
Complete field reference
{
"order": 2,
"stage_translation_key": "stage.verox_rpg_prog.hellfire",
"mob_attribute_scaling": {
"health_multiplier": 1.5,
"damage_multiplier": 1.35,
"knockback_resistance_multiplier": 1.05,
"armor_multiplier": 1.15,
"attributes": [
{ "attribute": "unbound_lib:crit_chance", "amount": 0.05 }
]
},
"territories": [
{
"structures": ["minecraft:fortress", "minecraft:bastion_remnant"],
"damage_per_second": 1.0,
"max_health_percent_per_second": 0.05,
"tint": "#5A0A0A",
"protect_structures": true,
"mob_scaling": { "health_multiplier": 1.3 }
}
],
"mob_equipment": [
{
"entity_ids": ["minecraft:piglin", "minecraft:piglin_brute"],
"equipment": [
{
"slot": "mainhand",
"item": "minecraft:golden_sword",
"enchantments": [
{ "id": "minecraft:sharpness", "level": 1 }
],
"drop_chance": 0.02
}
]
}
],
"locked_ores": [
{ "ore_block": "minecraft:ancient_debris", "disguise_block": "minecraft:netherrack" }
],
"main_boss": {
"entity_id": "minecraft:wither",
"display_item": "minecraft:nether_star",
"location_translation_key": "boss.verox_rpg_prog.wither.location",
"guaranteed_drops": ["minecraft:nether_star"],
"player_scaling": {
"radius": 48.0,
"health_per_extra_player": 0.5,
"damage_per_extra_player": 0.2,
"knockback_resistance_per_extra_player": 0.0,
"armor_per_extra_player": 0.0
},
"drops": {
"mode": "additional",
"drops": [
{ "item": "minecraft:netherite_scrap", "count_min": 2, "count_max": 4, "chance": 1.0 }
]
}
},
"optional_bosses": [
{
"entity_id": "minecraft:blaze",
"display_item": "minecraft:blaze_rod",
"location_translation_key": "boss.verox_rpg_prog.blaze.location",
"guaranteed_drops": [],
"player_scaling": { "radius": 32.0, "health_per_extra_player": 0.0, "damage_per_extra_player": 0.0, "knockback_resistance_per_extra_player": 0.0, "armor_per_extra_player": 0.0 },
"drops": { "mode": "additional", "drops": [] }
}
],
"locked_items": ["minecraft:netherite_sword"],
"locked_blocks_to_mine": ["minecraft:brewing_stand"],
"locked_dimensions": ["minecraft:the_end"]
}order
Type: integer, required
The stage's position in progression. Determines when its unlocks become available and what a boss defeat advances the world to.
stage_translation_key
Type: string, required
The translation key for the stage's display name in the Progression Journal. A matching <key>.summary key is also expected for the description shown on the stage's first page.
mob_attribute_scaling
Type: object, optional. Default: all multipliers 1.0 (no change).
Applies to every hostile mob (anything extending Monster - Zombie, Skeleton, Spider, etc.) while this stage is the currently active one. Passive and neutral mobs (cows, villagers, etc.) are never affected.
| Field | Default | Effect |
|---|---|---|
health_multiplier | 1.0 | Extra max health, e.g. 1.5 = +50% |
damage_multiplier | 1.0 | Extra attack damage |
knockback_resistance_multiplier | 1.0 | Extra knockback resistance |
armor_multiplier | 1.0 | Extra armor value |
Only applies to newly spawned mobs - a mob already in the world does not retroactively gain the bonus when the stage changes. Mobs loaded back in from saved chunks are not scaled again.
Values of 1.0 or less have no effect. This field cannot currently reduce a mob below its vanilla baseline.
attributes
Optional list of additional attribute modifiers, for any attribute - vanilla or modded:
"attributes": [
{ "attribute": "unbound_lib:crit_chance", "amount": 0.05 },
{ "attribute": "unbound_lib:armor_penetration", "amount": 0.1 },
{ "attribute": "minecraft:generic.movement_speed", "amount": 0.1, "operation": "add_multiplied_base" }
]| Field | Default | Purpose |
|---|---|---|
attribute | required | Attribute ID |
amount | required | Modifier value |
operation | add_value | add_value, add_multiplied_base or add_multiplied_total |
Unknown attributes are skipped silently, so a stage file can reference attributes from optional mods such as Unbound Lib without requiring them.
Not inherited: like the multipliers above, only the current stage's values apply. If mobs should keep a bonus in later stages, repeat it (ideally increased) in every following stage file.
territories
Type: list, optional.
Structures that belong to this stage. A territory works in two steps, depending on how far the world has progressed:
| Stage state | Entering | Building / mining inside the structure |
|---|---|---|
| Locked (two or more stages away) | Sealed land - constant damage and a screen tint | Forbidden |
| Current goal (the next stage to clear) | Allowed, no penalty | Forbidden until the boss is defeated |
| Cleared | Free | Free |
This lets players reach a boss's lair as soon as that boss is their next goal, but not plunder the structure before it falls.
{
"structures": ["minecraft:fortress", "#minecraft:village"],
"damage_per_second": 1.0,
"max_health_percent_per_second": 0.05,
"tint": "#5A0A0A",
"protect_structures": true,
"mob_scaling": {
"health_multiplier": 1.3,
"attributes": [{ "attribute": "unbound_lib:crit_chance", "amount": 0.1 }]
}
}| Field | Default | Purpose |
|---|---|---|
structures | [] | Structure IDs or structure tags (prefixed with #) |
damage_per_second | 1.0 | Flat damage per second while inside a locked territory |
max_health_percent_per_second | 0.0 | Additional damage per second as a fraction of the player's max health (0.05 = 5%) - keeps the threat meaningful for players with a lot of modded health |
tint | #5A0A0A | Screen tint color while inside a locked territory |
protect_structures | true | Prevents building and mining inside the structure until the stage is cleared |
mob_scaling | no-op | Extra scaling for hostile mobs spawning inside the territory, same format as mob_attribute_scaling, applied on top of the stage scaling |
Structures are checked per structure piece, not by one large box - for jigsaw structures like bastions or villages, only the actual buildings count. biomes exists in the schema for future use but is not recommended yet.
mob_equipment
Type: list, optional.
Equips specific weapons/armor onto matching mob types while this stage (or any earlier one, see below) is active. Grouped by entity_ids so many mobs can share one loadout.
{
"entity_ids": ["minecraft:zombie", "minecraft:husk", "minecraft:drowned"],
"equipment": [
{
"slot": "mainhand",
"item": "minecraft:iron_sword",
"enchantments": [{ "id": "minecraft:sharpness", "level": 1 }],
"drop_chance": 0.02
}
]
}slot accepts mainhand, offhand, head, chest, legs, feet. drop_chance defaults to 0.0 (the item never drops on death) unless set otherwise.
Inheritance: if a later stage does not redefine equipment for a given entity, the highest earlier stage that does define it is used automatically. To explicitly stop a mob's equipment at some stage, give that entity an empty "equipment": [] in that stage.
Works with any registered item or enchantment, vanilla or modded - resolution is purely by ID, not by hardcoded type.
locked_ores
Type: list, optional.
Ore blocks that remain fully minable while locked, but are visually disguised as another block and yield that block's item instead of the real ore.
{ "ore_block": "minecraft:diamond_ore", "disguise_block": "minecraft:stone" }This is distinct from locked_blocks_to_mine: an ore in this list can always be broken (it is never fully inaccessible), only its appearance and drop change while sealed.
main_boss / optional_bosses
main_boss is the boss whose death advances the world to this stage's order. optional_bosses are additional bosses tied to the stage for guide/flavor purposes and drop configuration, but killing one does not advance progression.
Both use the same structure:
| Field | Default | Purpose |
|---|---|---|
entity_id | required | The boss's entity type |
display_item | minecraft:barrier | Icon shown in the Guide UI |
location_translation_key | "" | Optional spawn/location hint text, shown in the Guide UI. Leave empty to hide the section entirely |
guaranteed_drops | [] | Items always included in the drop preview and (for the actual drop logic, see below) - needed for bosses whose real drop is hardcoded in Java rather than their loot table (e.g. the Wither's Nether Star) |
player_scaling | no-op | Per-boss attribute scaling based on how many players are near the boss when it spawns (see below) |
drops | { "mode": "none", "drops": [] } | Custom drop table, see below |
player_scaling
{
"radius": 48.0,
"health_per_extra_player": 0.5,
"damage_per_extra_player": 0.2,
"knockback_resistance_per_extra_player": 0.0,
"armor_per_extra_player": 0.0
}At spawn, the boss counts alive players within radius blocks. For every player beyond the first, the listed fractions are added (e.g. health_per_extra_player: 0.5 with 3 nearby players adds +100% health). A solo player triggers no bonus. This does not update dynamically if players join or leave mid-fight - it is evaluated once, at spawn.
drops
{
"mode": "additional",
"drops": [
{ "item": "minecraft:netherite_scrap", "count_min": 2, "count_max": 4, "chance": 1.0 }
]
}| Mode | Effect |
|---|---|
none | Vanilla drops only, unmodified. Custom drops list is ignored |
additional | Vanilla drops plus the custom drops list |
replace | Only the custom drops list - vanilla loot table is skipped entirely |
guaranteed_drops is separate from this table: it exists because some vanilla bosses spawn their signature item directly in Java code rather than through their loot table (the Wither's Nether Star is the primary example). Without listing it here, the Guide UI's drop preview and any future guaranteed-drop logic would not know about it - the loot table itself genuinely does not contain it.
locked_items
Type: list of item IDs, optional.
Fully inaccessible while locked - cannot be picked up meaningfully, equipped, used, or crafted with while the owning stage is not yet reached. Shown with a "Sealed" tooltip everywhere the item appears.
locked_blocks_to_mine
Type: list of block IDs, optional.
Fully inaccessible while locked - cannot be broken or placed at all. Intended for functional blocks (Enchanting Table, Anvil, Beacon, redstone components) rather than naturally-generated ore, which should use locked_ores instead.
locked_dimensions
Type: list of dimension IDs, optional.
Blocks travel into the listed dimension via any portal while the owning stage has not been reached. The player is stopped before the actual dimension change happens; nothing else about the portal is altered.
Mod-dependent stages
Stage files can react to which mods are installed, so one progression can adapt itself - for example a different stage when Iron's Spells 'n Spellbooks is present.
required_mods / excluded_mods
Any stage file can list mod IDs on its top level:
{
"required_mods": ["irons_spellbooks"],
"order": 2,
"stage_translation_key": "stage.verox_rpg_prog.frostbound"
}| Field | Effect |
|---|---|
required_mods | The file is only loaded if all listed mods are installed |
excluded_mods | The file is skipped if any listed mod is installed |
To swap a stage, give the original file "excluded_mods": ["irons_spellbooks"] and add a replacement with "required_mods": ["irons_spellbooks"] and the same order. Only one of them is ever loaded.
Stage additions
To extend an existing stage without copying the whole file, place an addition file at:
data/<namespace>/stage_additions/<name>.json{
"required_mods": ["irons_spellbooks"],
"order": 3,
"optional_bosses": [
{ "entity_id": "irons_spellbooks:fire_boss", "display_item": "irons_spellbooks:cinder_essence" }
],
"locked_items": ["irons_spellbooks:netherite_spell_book"]
}The addition is merged into the loaded stage with the same order. Supported fields: optional_bosses, locked_items, locked_blocks_to_mine, locked_ores, locked_dimensions, territories, mob_equipment - all are appended to the stage's own lists. required_mods and excluded_mods work here as well. An addition whose order matches no loaded stage is skipped with a warning in the log.
Built-in Iron's Spells 'n Spellbooks support
With Iron's Spells 'n Spellbooks installed, the default progression automatically grows from 5 to 7 stages: Sculk Dread is replaced by Frostbound (Ice Spider), and Catacombs (Dead King) and Ashen Citadel (Tyros) are added. Iron's spellbooks, gear and structures are sealed alongside the matching tiers. The full layout is visible in-game in the Progression Journal.
The ISS stages are regular stage files using required_mods / excluded_mods and stage additions, so they can be overridden or removed by a datapack like any other stage.
How locking actually works
Items and blocks
Every relevant interaction is intercepted: right-click use, left-click attack, block breaking/placing, shift-click auto-equip, drag-and-drop into armor slots, crafting result pickup, and attribute modifiers (a locked weapon's damage bonus is stripped while sealed). Creative-mode players bypass all of this.
Ores
Unlike a fully locked block, a locked ore can always be mined. Breaking it yields the configured disguise_block's item instead of the real ore, and - while the world is rendered - the block visually appears as the disguise block (mesh, breaking particles, and block-break sound all use the disguise), not the true block. The true block state is never altered; only the client's rendering and the resulting drop are affected. When the owning stage is reached, all loaded chunks are refreshed immediately so previously-disguised ore reveals its true appearance without needing to reload the world.
Bosses
A boss (main or optional) cannot be damaged at all until the stage before its own has been cleared. Attacking one that is still locked is silently canceled and the attacker sees a message naming the stage that must be cleared first. Creative-mode players bypass this.
Dimensions
Attempting to travel into a locked dimension through a portal is canceled before the actual dimension change occurs. This only intercepts genuine portal travel - a command-based teleport (/execute in ...) or a different mod's custom teleport mechanism is not affected.
Territories
- Sealed land: inside a territory of a locked stage, players take damage every second and their screen fades into the territory's tint. The damage ignores armor, enchantments, resistance and potion effects, so effect-blocking items cannot negate it. Players killed this way get their own death message.
- Protection: while a territory's stage is not cleared, blocks inside its structures cannot be broken or placed, and explosions leave them untouched. A denied attempt shows smoke, plays a dull sound and names the stage that has to be cleared.
- Border: protected structures are surrounded by a forcefield wall in the style of the vanilla world border - red for locked stages, gold for the current goal. It fades in within about 12 blocks and flashes when someone tries to break a protected block. The wall is visual only and can be walked through; the border disappears once the stage is cleared.
- Mob scaling: hostile mobs spawning inside a territory receive the territory's
mob_scalingin addition to the stage scaling. - Creative-mode players bypass damage and protection.
The damage type used for sealed land is verox_rpg_prog:sealed_land.
Commands
All commands require operator permission level 2 and live under /rpg_prog stage.
| Command | Effect |
|---|---|
/rpg_prog stage get | Shows the current stage's name, or "Sealed World" |
/rpg_prog stage set <order> | Manually sets the world's unlocked order and re-evaluates locked equipment/attributes |
/rpg_prog stage reset | Resets the world back to Sealed World (-1) |
The Progression Journal
Every player receives the Progression Journal the first time they join a world. It can be opened by right-clicking it or with the keybind (default: K, which also closes it again). If it gets lost, a new one is crafted from a Book + Iron Ingot (shapeless).
- Landing page: the current stage, how many stages have been cleared, and a list of every stage with a marker - green for cleared, orange for the current goal, red for locked
- Stage pages: name, status, description, sealed dimensions and territories, then the main boss and optional bosses, then every sealed item, block and ore. Use the arrows to turn pages - content that doesn't fit continues on the next page
- Boss pages: location hint and the full drop preview, including vanilla drops resolved via loot table simulation, with chance and amount in the tooltip
The book is built entirely from the loaded stage files, so it adapts automatically to any modpack's progression. It works on dedicated servers - stage definitions are synced to every client on join and after /reload.
Loot Bags
Every registered boss (main or optional) drops loot bags instead of ground loot. Each player within the boss's player_scaling.radius receives their own bag, rolled independently - no more racing for drops.
- Bags roll the boss's existing drop configuration from its stage file:
guaranteed_dropsare always included, anddrops.modedecides the rest:
mode | Bag contents |
|---|---|
additional | Vanilla loot table + custom drops |
none | Vanilla loot table only |
replace | Custom drops only |
- Vanilla loot is rolled with each player as the attacker, so "killed by player" drops work for everyone who gets a bag.
- Each bag shows which boss it came from. Right-click to open - items go straight into the inventory, or drop at your feet if it's full. Bags don't stack.
- Bags are only given for player kills. A boss killed by lava, fall damage or a farm drops its normal loot.
- Experience orbs are not affected and drop normally.
Excluding mobs
Add an entity type to the tag verox_rpg_prog:no_loot_bag to make it drop normal loot instead:
data/verox_rpg_prog/tags/entity_type/no_loot_bag.json
{
"replace": false,
"values": [
"minecraft:blaze"
]
}By default, common farmable mobs used as optional bosses (Pillager, Vindicator, Vex, Guardian, Blaze, Ghast, Magma Cube, Wither Skeleton, Hoglin, Zoglin, Shulker) are excluded. Use "replace": true with an empty list to let every boss drop bags.
Turning loot bags off
See the config below. With loot bags disabled, all bosses drop their loot on the ground as configured in their stage files.
Config
config/verox_rpg_prog-common.toml
[loot_bags]
enabled = true
[book]
give_on_first_join = true| Option | Default | Effect |
|---|---|---|
loot_bags.enabled | true | Bosses drop per-player loot bags instead of ground loot |
book.give_on_first_join | true | Every player receives the Progression Journal on their first join |
Examples
A stage with no restrictions beyond its boss
{
"order": 0,
"stage_translation_key": "stage.verox_rpg_prog.raiders_dawn",
"main_boss": {
"entity_id": "minecraft:evoker",
"display_item": "minecraft:totem_of_undying",
"drops": { "mode": "additional", "drops": [
{ "item": "minecraft:totem_of_undying", "count_min": 1, "count_max": 1, "chance": 1.0 }
] }
},
"locked_items": ["minecraft:totem_of_undying"]
}Locking an entire ore tier plus its tools and armor
{
"order": 1,
"stage_translation_key": "stage.verox_rpg_prog.echoes",
"locked_ores": [
{ "ore_block": "minecraft:diamond_ore", "disguise_block": "minecraft:stone" },
{ "ore_block": "minecraft:deepslate_diamond_ore", "disguise_block": "minecraft:deepslate" }
],
"locked_items": [
"minecraft:diamond",
"minecraft:diamond_sword", "minecraft:diamond_pickaxe", "minecraft:diamond_axe",
"minecraft:diamond_shovel", "minecraft:diamond_hoe",
"minecraft:diamond_helmet", "minecraft:diamond_chestplate",
"minecraft:diamond_leggings", "minecraft:diamond_boots"
]
}A boss whose signature drop is hardcoded (not in its loot table)
{
"entity_id": "minecraft:wither",
"display_item": "minecraft:nether_star",
"guaranteed_drops": ["minecraft:nether_star"],
"drops": { "mode": "additional", "drops": [] }
}Gating the Nether behind a stage
{
"order": 2,
"stage_translation_key": "stage.verox_rpg_prog.sculk_dread",
"locked_dimensions": ["minecraft:the_nether"],
"main_boss": { "entity_id": "minecraft:warden", "display_item": "minecraft:echo_shard" }
}Troubleshooting
A stage doesn't load / doesn't appear in the Journal
Check that order and stage_translation_key are both present - they are the only two required fields. Check the server log for a JSON parsing error; a required field with no default (only order and stage_translation_key) will fail the whole file silently otherwise.
Two stages have the same order
Both will be treated as unlocked/locked together, and the Guide will list both. This is usually a mistake - give each stage a unique order.
An item/block still works after being listed in locked_items / locked_blocks_to_mine
Confirm the player is not in Creative mode (Creative always bypasses locks by design). Confirm the ID is spelled correctly and namespaced (minecraft: prefix for vanilla items).
A boss can be damaged before its "unlock stage" is reached
The lock only applies to the stage immediately before the boss's own stage. A boss at order: 2 is only locked while the world is below order: 1 - it becomes damageable the moment order: 1 is cleared, even before order: 2 itself is reached. This is intentional (you must be able to fight the boss to reach its stage).
A player can still enter a locked dimension
Only genuine portal travel is intercepted. Command-based teleports and third-party mod teleport mechanisms are not covered.
An ore's optical disguise doesn't update immediately after unlocking
Confirm the client actually received the updated stage order - a fresh chunk render is triggered automatically on stage change, but a very laggy connection could delay this by a moment.
A boss drops normal loot instead of loot bags
Check that it was killed by a player, that it isn't listed in the verox_rpg_prog:no_loot_bag tag, and that loot bags are enabled in the config.
A territory doesn't punish me
Territories only punish while their stage is locked, i.e. at least two stages away. If the stage is the current goal, entering is allowed - only building and mining are blocked. Use /rpg_prog stage get to check the world's stage.
I can't place torches inside a structure
Protection blocks every block placement inside the structure until its stage is cleared, including torches. Set "protect_structures": false on the territory if this is too strict for your pack.
The border doesn't show up
The border appears within about 12 blocks of a protected structure and only for structures in already loaded chunks near the player. It is never shown for cleared stages or for structures without protection on the current goal.
Frequently asked questions
Is progression per-player or world-wide?
World-wide. Every player shares the same unlocked stage.
Can a locked ore never be mined at all?
No - locked ores are always minable. Only their appearance and drop are affected while sealed. Use locked_blocks_to_mine instead if a block should be completely inaccessible.
Do Creative players bypass locks?
Yes, on every lock type (items, blocks, bosses, dimensions).
What happens to a stage's optional bosses if their stage is never reached?
They remain locked the same way the main boss does - damage is canceled until the previous stage is cleared.
Can I get a new Journal if I lose it?
Yes - craft it from a Book and an Iron Ingot.
Can items that block potion effects protect me from sealed land?
No. Sealed land deals damage directly instead of applying effects, and that damage ignores armor, enchantments, resistance and effects.
Can I turn loot bags off?
Yes - set enabled = false under [loot_bags] in config/verox_rpg_prog-common.toml, or exclude single mobs via the verox_rpg_prog:no_loot_bag entity type tag.
Can I use modded items, blocks, entities, or enchantments anywhere in a stage file?
Yes. Every reference is resolved purely by registry ID (namespace:path) - there is no hardcoded vanilla-only list anywhere in the lock, drop, equipment, or ore-disguise systems.
For developers: building an addon
RPG Progression exposes a small, stable API surface intended for addon mods (such as the other Verox' RPG mods or third-party content packs). Depend on verox_rpg_prog as a normal mod dependency, but only reference the classes below - internal classes such as StageManager may change between versions without notice.
Reading progression state
import net.veroxuniverse.verox_rpg_prog.api.ProgressionApi;
int order = ProgressionApi.getUnlockedOrder();
boolean locked = ProgressionApi.isItemLocked(ResourceLocation.parse("minecraft:diamond_sword"));
Optional<StageDefinition> current = ProgressionApi.getCurrentStage();Available methods: getUnlockedOrder(), getAllStages(), getStageByOrder(int), getCurrentStage(), isItemLocked(ResourceLocation), isBlockLocked(ResourceLocation), isOreLocked(ResourceLocation), isDimensionLocked(ResourceLocation), isBossLocked(ResourceLocation), getOwningStageForBoss(ResourceLocation), getBossInfo(ResourceLocation), isRegisteredBoss(ResourceLocation).
Reacting to progression events
Two events are posted on NeoForge.EVENT_BUS, both in net.veroxuniverse.verox_rpg_prog.api.event:
StageUnlockedEvent - fired whenever the world's stage order changes, including manual changes via /rpg_prog stage set or reset. Not cancellable; the change has already happened.
@SubscribeEvent
public static void onStageUnlocked(StageUnlockedEvent event) {
event.getNewStage().ifPresent(stage -> {
// e.g. spawn addon-specific content for this stage
});
}BossDefeatedEvent - fired when a registered boss (main or optional, from any loaded stage) is killed by a player, after RPG Progression has advanced the world stage (if it was the next main boss) and before the boss's drops are spawned. Intended for addons that want to react to a boss kill independently, for example granting achievements or spawning follow-up content.
@SubscribeEvent
public static void onBossDefeated(BossDefeatedEvent event) {
if (event.wasMainBoss()) {
// react to the main boss of event.getOwningStage() being defeated
}
}What addons should not do
- Do not write to
StageManager's internal maps directly, even though the class is technically public - always go through the events above to react, and never assume its internal structure will stay the same between versions. - Do not assume a stage's
ordervalues are contiguous or start at0- always compare relatively (>=,>), never hardcode an expected sequence. - Do not rely on
player_scaling,mob_attribute_scalingor territorymob_scalingupdating dynamically after a mob has already spawned - all of them are spawn-time only.
