Variable that need to persist in next states can be classified into 3 types:
Constants are not created using the init function. As such, their state in the game is not volatile. No next is needed to make sure they will be in the next state of the game.
Blocks are modified directly with the legal moves of the players or random. With the their only method of change being movement from one location to another, their persistence can be summed up into two types of next functions that MUST both be included as a pair:
(<= (next (hand ?player 1 ?c)) (does random (deal ?player ?c)))
This is a simple example of dealing a card. The card that was in another location gets added to the new location; in this case, the player's hand.
(<= (next (deck main 1 ?c)) (true (deck main 1 ?c)) (not (does random (deal ?player ?c))))
The card that was dealt must be excluded from where it was previously. This next function makes it so that all cards in the first main deck move on to the next state except if that specific card was used in the deal move by random.
Values are modified directly with the legal moves of the players. With their method of change being modification of the value, special care has to be made so that the value is not modified multiple different times or to multiple different values. Doing do will create duplicates of the values that will confuse future logical checks. The number of next functions are directly proportional to the number of moved that can modify the variable, with the addition of one more.
For example, a player has HP as a numeric value and there are two types cards which can affect it, one to decrease and one to increase. Each card will need a separate next function to modify this value:
(<= (next (stat ?player 1 ?new)) (true (stat ?player 1 ?old) (does ?actor (attack ?player ?value)) (add ?value ?new ?old))
(<= (next (stat ?player 1 ?new)) (true (stat ?player 1 ?old) (does ?actor (heal ?player ?value)) (add ?value ?old ?new))
Because each can only be done once on any players turn (even if multiple actions can be performed on any 1 player's turn, they are separated into multiple “turns” that are back-to-back), there is no need to include next functions that deal with if a decrease and increase happen to the HP. This is, however one more function that needs to be made, one where neither happen.
(<= (next (stat ?player 1 ?old)) (true (stat ?player 1 ?old) (not (does ?actor (attack ?player ?value))) (not (does ?actor (heal ?player ?value))))
Not increasing or decreasing in HP cannot be separated into 2 next functions because one or both of them will always be true. If an increase happens, then the HP increase next will be true, so a new HP stat will be created in the next state of the game. However, the no HP decrease next will also be true, so an unmodified HP stat would also be carried onto to the next state of the game. The only way to stop this is to place them both in the same check.
This means that there is an n+1 relation between the number of legal moves that affect a value and the number of next functions associated with that value.