Skip to main content
Version: 6.1.x

Logic Blocks

New in 6.1.0

Dependencies say "A has to come before B". Logic blocks cover what dependencies cannot: a stage that becomes unavailable, invisible, cheaper or lost because of what happened to other stages.

The classic case is two paths that exclude each other. A mage picks fire or ice; starting one shuts the other until the first is mastered.

A logic block is one rule: a type (what happens) plus a condition (when). A stage can carry several.

TypeWhat it does
Blocked while ...the stage cannot be unlocked while the condition holds
Hidden while ...the stage is out of sight while the condition holds
Cheaper/costlier while ...research time, item and XP costs change while the condition holds
Revoke when ...the stage is taken away the moment the condition becomes true

Conditions​

A condition looks at other stages: is unlocked or is locked, grouped as All or One of. The editor builds up to five groups, and all groups must hold at once:

(Fire I is unlocked and Fire III is locked)

In the file it is a small tree of all, any, not and unlocked:

"logic": [
{
"type": "blocked_while",
"condition": {
"all": [
{ "unlocked": "fire_1" },
{ "not": { "unlocked": "fire_3" } }
]
}
}
]

Any tree is read and evaluated, also nestings the editor cannot draw. The editor then shows the block read-only and keeps it as it is.

Who the condition is checked for. An individual stage's condition is checked for that player and may look at global and individual stages. A global stage's condition may look at global stages only; an individual stage in it counts as locked and the load report says so. When an individual and a global stage share an id, "scope": "global" or "scope": "individual" next to "unlocked" says which one is meant.

A stage that does not exist counts as locked. The editor marks it red.

Blocked while​

The stage cannot be unlocked while the condition holds. An already unlocked stage stays unlocked when its condition becomes true; taking it away is what Revoke when is for.

The two mage paths, each three stages long. Only the entry stages need a block:

StageBlocked while
Fire IIce I is unlocked and Ice III is locked
Ice IFire I is unlocked and Fire III is locked

At the start both are open. Research Fire I and Ice I is blocked. Unlock Fire III and Ice I opens again.

Which unlock paths respect it:

PathWhen the stage is blocked
Research pedestalrefuses to start, and asks again when research finishes
Auto-triggers, While stagesdo not fire; they try again the next time
KubeJS, CraftTweaker, FTB Quests rewardsrefused, with a line in the debug log
/history commands, the editor's unlock toggleunlock anyway and tell the operator
Creative scrollgoes through

The pedestal asks a second time at the end because two players can start Fire I and Ice I at the same moment. If the stage is blocked by then, researchWhenBlocked in gameplay.toml decides: PAUSE (default) keeps the progress and waits, CANCEL stops and hands the scroll back.

warnOnForcedUnlock turns off the notice an operator gets when a command pushes a blocked stage through.

Hidden while​

The stage is out of sight while the condition holds. It can still be unlocked, so a secret path found through a looted scroll still works. Combine it with "Blocked while" to stop that.

mode picks how it hides: "anonymous" (default) or "vanish".

Whereanonymousvanish
Stage graph (player view)node shown as "???"node and its lines gone
Item tooltip, Jade, lock messages"???""???"
Another stage's requirements"???""???"
Its scroll in JEI / EMIhiddenhidden
Editor, commands, debug logunchangedunchanged

Where the stage is only shown, it vanishes; where it explains something, it reads "???".

{ "type": "hidden_while", "mode": "vanish", "condition": { "not": { "unlocked": "explorer" } } }

Cheaper/costlier while​

Scales the research time, the item costs and the XP costs in percent while the condition holds. 100 is unchanged, 50 half, 0 free or instant, up to 1000. A missing field is 100.

{ "type": "cost_while", "time": 50, "items": 100, "xp": 75, "condition": { "unlocked": "scholar" } }
  • Several blocks that hold multiply with each other and with the pedestal booster.
  • Item counts round up and never fall below 1 unless the factor is 0. XP rounds the same way.
  • Item and XP costs are fixed on the scroll at the first deposit. Unlocking Scholar halfway through does not change what is already owed. Time changes live.

The pedestal shows what applies and why. The scroll tooltip also lists discounts the player could still get by unlocking something; showInactiveCostHints in visual.toml turns those hints off.

Revoke when​

Takes the stage away once, at the moment its condition turns from false to true, if the owner has it. The owner is the world for a global stage and the player for an individual one.

{ "type": "revoke_when", "condition": { "unlocked": "shadow_pact" } }

Take the shadow pact and the light path is gone.

  • It fires whatever unlocked or locked the other stage: pedestal, trigger, command, script, quest.
  • Chains work. Losing one stage can fire the revoke of another, and since a revoke only ever removes stages, a chain always ends.
  • Players who were offline lose the stage at their next login.
  • The stage can be researched again afterwards. Add "Blocked while" with the same condition to stop that.
  • Revoking works like a relock: recipes lock again, and on an individual stage the player's locked items drop while dropOnRevoke in [individual_stages] is on.

The player gets a toast saying what was taken and why. An operator whose command or editor click started it gets one too.

Two warnings can show before it happens, each with its own switch in visual.toml:

  • showRevokeWarningOnStage — "Revoked when ..." on the stage's own scroll tooltip and graph panel.
  • showRevokeWarningOnTrigger — "Unlocking takes away ..." on the scroll and pedestal of the stage whose unlock would fire it.
A "While" stage fires a revoke every time it opens

A While stage that keeps opening and closing turns "is unlocked" on and off. A revoke that looks at it fires on every opening. That is how the rule works, not a bug.

What players see​

The pedestal, the scroll tooltip and the stage graph say why a stage is blocked. In the graph a blocked stage has its own look, a red no-entry badge by default, styled as blocked in graph.toml like the other node states.

blockedDisplay = "PLAIN" in visual.toml hides the conditions everywhere and only says that the stage is blocked. The actionbar texts for a blocked and a revoked stage are lock_messages.stageBlocked and lock_messages.stageRevoked.

In the editor​

Logic, the button next to Settings and Dependencies on the stage's screen. Each block is a card; + Block adds one. A card shows live whether its condition holds for you right now, and marks every term that is met. The stage picker only offers stages the condition may look at.

See also​

  • Dependencies — what has to be done before a stage can be researched.
  • Interchangeable Stages — several stages that lock the same thing, where one is enough.
  • Relocking — stages that lock themselves again from triggers.
Something wrong or missing here? Ask on Discord · Open an issue