Saving State


Everything you have built so far is stateless: a variable is always recomputed from the current values of its inputs, so a network has no memory of what happened before. Sometimes you need exactly that memory, for example a lamp that stays on after a button was pressed. In this tutorial, we will use the Delayer to save state.

A Delayer remembers the previous values of the Variable Card in its top slot, and exposes them as a List. Start by crafting one, attach it to a network with a Redstone Reader that is targeting a Button, and insert the reader's Boolean card of the aspect that is simply called Redstone, which is True while there is a signal. Next, set the Capacity to 1 in its gui, and leave Ticks/Operation at 1.

The newest value is always the last element of the List, so a Capacity of 1 makes the history hold exactly one element: the value of the previous tick. With a larger Capacity, the first element would be an older value instead. Now write a new Variable Card using the bottom slots. This card refers to the Delayer's history.

The trick for saving state is a feedback loop: put a Variable Card in the Delayer whose value depends on the Delayer's own history. Each tick, the Delayer evaluates that card and stores the result, which becomes the previous value on the next tick. This dependency must be indirect: putting the history card itself in the top slot only gives an error that the variable is referring to itself. Let's use this to build a latch: a lamp that is switched on by one Button, and switched off by another.

Every operator you apply in the Logic Programmer results in its own Variable Card, so we will build the latch from several small cards. You can find each operator by typing its name in the search field. Start by reading the two Buttons with Redstone Readers as Boolean Redstone cards named On and Off. As the Get Or Default operator takes all of its inputs as cards, also create an Integer card with value 0 and a Boolean card with value False. Now define Previous as Get Or Default of the history card, that Integer and that Boolean, so that it also works while the history is still empty.

Next, define NotOff as Not Off, then Keep as Previous And NotOff, and finally State as On Or Keep. Take the reader card out of the Delayer's top slot, and place State there instead. All other cards, including the intermediate ones, must be placed in a Variable Store, as the network can otherwise not find them. Finally, create a second Variable Card named State by building that same Or expression once more, as the first one has to stay in the Delayer, and insert it into the Redstone aspect of a Redstone Writer that is targeting a Redstone Lamp. The lamp will now stay on after pressing On, until you press Off.

For the final part, we will make a toggle that flips on every press of a single Button: the On one. If we would simply invert Previous while the Button is pressed, the state would flip on every tick of the press. We therefore need to detect the exact tick in which the Button becomes pressed. Place a second Delayer with Capacity 2, so that its history holds the two most recent values. Write a new Redstone card of that Button into its top slot, as the earlier On card has to stay in the Variable Store, and write its history card. This history is exactly [False, True] in the tick after the Button was pressed.

Create a static List of the Booleans False and True, in that order, and define Edge as the second Delayer's history card Equals that List. Next, define NotPrevious as Not Previous, and State as Choice of Edge, NotPrevious and Previous. Place it in the top slot of the first Delayer, which must still have Capacity 1, insert a second copy into the Redstone Writer, and put the new cards in the Variable Store. Every press of the Button now toggles the lamp. Feedback loops like these can save any kind of value, not just Booleans, so you can now build counters, timers and much more.

Crafting Table
Crafting Table
  • Variable Card
  • Crystallized Menril Chunk
  • Variable Card
  • Clock
  • Variable Store
  • Clock
  • Variable Card
  • Crystallized Menril Chunk
  • Variable Card
→
Delayer
Operator
Get Or Defaultget_or_defaultSafely get the list element at the given position, if that element is not available, return the given default value.
  • List
  • Integer
  • Any
  • Any
Global name: listGetOrDefault(List, Integer, Any) → AnyMethod name: List.getOrDefault(Integer, Any) → Any
Operator
Not!
  • Boolean
  • Boolean
Global name: booleanNot(Boolean) → BooleanMethod name: Boolean.not() → Boolean
Operator
And&&
  • Boolean
  • Boolean
  • Boolean
Global name: booleanAnd(Boolean, Boolean) → BooleanMethod name: Boolean.and(Boolean) → Boolean
Operator
Or||
  • Boolean
  • Boolean
  • Boolean
Global name: booleanOr(Boolean, Boolean) → BooleanMethod name: Boolean.or(Boolean) → Boolean
Operator
Equals==Tests whether two values are equal. The types of both must be the same.
  • Any
  • Any
  • Boolean
Global name: anyEquals(Any, Any) → BooleanMethod name: Any.equals(Any) → Boolean
Operator
Choice?If the first value is true, the second value is taken, otherwise the third value.\nType two and three must be equal.
  • Boolean
  • Any
  • Any
  • Any
Global name: booleanChoice(Boolean, Any, Any) → AnyMethod name: Boolean.choice(Any, Any) → Any
Advancements
  • Variable DelayingWrite a history variable in a §lDelayer§r.
  • State LatchingBuild a latch that is set by one button and reset by another, by feeding a variable that depends on its own §lDelayer§r history back into that §lDelayer§r, and write it to a Redstone Writer.
  • State TogglingBuild a toggle that flips on every button press, by detecting the rising edge of the button in a second §lDelayer§r, and write it to a Redstone Writer.
Ödüller
Delayer2
Redstone Reader5
Redstone Writer5
Variable Card64