StageLock
Stage-based progression gating for NeoForge 1.21.1
A modern take on GameStages: one mod, datapack- and KubeJS-driven.
What it does
StageLock lets modpack makers lock content behind stages. Stages are named milestones such as iron_age or nether. Players unlock them through advancements, quests, commands or scripts. Until then, locked content can't be used. It can also be hidden entirely.
Features
- Player, team and global stages
- Teams come from FTB Teams or vanilla
/team. - Global stages apply to the whole server.
- Teams come from FTB Teams or vanilla
- Item restrictions
- You choose which actions to block: pickup, use, place, attack, mine, equip, holding, crafting, and showing in recipe viewers.
- Locked items can show a hidden name such as "Unfamiliar Item".
- Recipe gating
- Works in the crafting table, the inventory grid, the smithing table, the stonecutter, campfires and the crafter.
- Furnaces and other machines use the stages of the player who placed them, even while that player is offline.
- Blocks: stop players breaking, using or placing them, or disguise ores as stone until they're unlocked.
- Fluids, enchantments, dimensions and mobs: lock buckets of lava, Mending gear, the Nether, or a mob's spawns.
- Stage definitions: display names, prerequisites, unlocking from advancements, and unlock messages or functions.
- Live recipe viewers: JEI, REI and EMI hide locked items and recipes, and bring them back the moment a stage unlocks.
- Vanilla hooks: a loot condition, an advancement trigger and an entity predicate, all for checking stages.
- Fast: rules are indexed ahead of time, and inventories are only rechecked when something actually changes.
Easy to set up
Drop JSON files into a datapack. /reload applies changes instantly.
{
"type": "stagelock:item",
"requires": "iron_age",
"items": ["#c:gems/diamond", "@mekanism"],
"hidden_name": "Shiny Rock"
}
Prefer scripts? The KubeJS API builds the same rules:
StageLockEvents.restrictions(event => {
event.item('minecraft:diamond').requires('iron_age').hideName('Shiny Rock')
event.recipe('minecraft:iron_pickaxe').requires('stone_age')
event.dimension('minecraft:the_nether').requires('nether')
})
Existing KubeJS player.stages scripts and FTB Quests stage tasks keep working. StageLock stores the stages behind them.
Integrations
All of these are optional:
- KubeJS: rules, stage definitions, grant and revoke events, and a
StageLockscripting helper. - JEI, REI and EMI: live hiding of locked items, fluids and recipes.
- FTB Teams: team-scoped stages for parties.
- FTB Quests: stage tasks and rewards, via KubeJS stages.
- Curios: locked items can't be equipped in curio slots.
- Jade: shows what a locked block requires, and shows disguised blocks as their disguise.
- Quest Queen: works with Quest Queen
Commands
Every command also works as /stage.
/stagelock grant | revoke <players> <stage>: works on offline players too./stagelock globaland/stagelock team: manage server-wide and team stages./stagelock why <player>: explains exactly which rules lock the held item./stagelock dump: exports every rule and stage for review./stagelock import gamestages: migrates existing GameStages player data.
Try it out
A small example progression ships inside the mod: Stone Age, then Iron Age, then the Nether. Enable it with:
/datapack enable "mod/stagelock:datapacks/examples"
Requires NeoForge 21.1+ on Minecraft 1.21.1. Install it on both client and server.