better mod4 examples

This commit is contained in:
2026-06-22 00:29:22 -04:00
parent 8fc002cda1
commit d0d1a87cf5
3 changed files with 144 additions and 54 deletions

View File

@@ -1,5 +1,7 @@
#import "/lib.typ": callout, example, note, solution, tip, todo
#let mod4 = $#h(0.5em)&(mod 4)$
= Core Mechanics <core>
== Entity IDs
@@ -59,75 +61,158 @@ public class Entity {
#note[ `onGround` is only ever updated via `move`, and this branch is the *only* place that
`ItemEntity.move` is called. ]
== Observable Drop Delay
The effect is that if the item is on a block and has negligible horizontal momentum, it *cannot
fall* until the condition is satisfied, even if it's no longer on the ground. It can only fall early
if it gains horizontal momentum or is pushed.
This means if we know the remainder of $"id" slash 4$, we can predict which ages allow it to fall.
And the inverse: if we know which age allowed an item to fall, we can deduce the remainder of
$"id" / 4$.
#table(
columns: (auto, auto),
$"age"$, $"id"$,
[0], [0],
[1], [3],
[2], [2],
[3], [1],
)
This means if we know the remainder of $"age" / 4$, we can
#todo[Falling item animation][Spawn a few items, note their ID and age. Let them settle on a block, then
remove that supporting block. There will be a few ticks where the item hovers in place before it
falls.]
== Observable Drop Delay
We can't control the absolute entity ID a particular item will receive, but we can *compare* ids of
multiple entities. By observing the drop delay for a "reference" item, we can predict the behavior
of other items.
#example[
Consider this timeline. We spawn a few items, give them time to settle on the ground, then remove
their support. We observe when item $O$ begins to fall, and infer when we should expect the other
items to fall.
Suppose we spawn four items in order. For simplicity, spawn them all in the same tick so their
ages are equal, and assume no other entities spawn.
- `t+0`, spawn item $O$
- `t+1`, spawn item $A$
- `t+4`, spawn item $B$
- `t+4`, spawn item $C$
- `t+20`, remove support
- `t+22`, item $O$ begins to fall
1. Spawn items $A$, $B$, $C$, and $D$ in order in the same tick. Let them settle on a block.
2. At tick $t=0$, remove the supporting blocks.
3. At tick $t=1$, item $B$ begins to fall.
Assuming no other entities spawn in this time period; these are the only things which increment
the counter.
At what ticks should we expect items $A$, $B$, and $C$ to begin to fall?
Based on when item $B$ fell, when should we expect the other items to fall?
#solution[
Item $O$ falls when its age is $22 = 2 (mod 4)$, so its id must be $-2 (mod 4)$
To simplify the arithmetic, orient everything around $t=0$. So we'll let $"age"_0$ to be the
items' ages at $t=0$ and add tick offsets from there. All items spawned in the same tick, so
they all have the same $"age"_0$.
Item $A$ spawns next, so its id must be $-1 (mod 4)$.
It can only fall when its age is $1 (mod 4)$.
It checks on ticks `t+2`, `t+6`, `t+10`, `t+14`, `t+18`, but is supported for all these.
On tick `t+22`, it will no longer be supported and will begin to fall.
Since $B$ falls at $t=1$, the relation for $"id"^B$ must be
$ "age"_0 + "id"^B + 1 = 0 mod4 $
Item $B$ spawns next, so its id must be $0 (mod 4)$.
It can only fall when its age is $0 (mod 4)$.
These are ticks `t+4`, `t+8`, `t+12`, `t+16`, `t+20`. So it falls immediately when the support
is removed.
$A$ spawned right before $B$, so $"id"^A + 1 = "id"^B$. Plug that in to the relation we got for
$"id"^B$.
$ "age"_0 + "id"^A + 1 + 1 = 0 mod4 $
Item $C$ spawns next, so its id must be $1 (mod 4)$.
It can only fall when its age is $-1 = 3 (mod 4)$.
These are ticks `t+7`, `t+11`, `t+15`, `t+19`, `t+23`.
*$A$ must fall at $t=2$.*
- `t+20` remove support, item $B$ falls
- `t+22` items $O$ and $A$ fall
- `t+23` item $C$ falls
$C$ spawned right after $B$, so its id is $"id"^C - 1= "id"^B$. Plug that in.
$ "age"_0 + "id"^C - 1 + 1 = 0 mod4 $
*$C$ must fall at $t=0$.*
$D$ spawned right after $C$, so its id is $"id"^D - 2 = "id"^B$. Plug that in.
#tip[You can freely add or subtract 4 to either side of a mod 4 equality.]
$
"age"_0 + "id"^D - 2 + 1 &= 0 mod4 \
"age"_0 + "id"^D - 1 &= 0 mod4 \
"age"_0 + "id"^D - 1 + 4 &= 0 mod4 \
"age"_0 + "id"^D + 3 &= 0 mod4
$
*$D$ must fall at $t=3$.*
]
#todo[Demonstration]
]
For simplicity, suppose we spawn all our items on the same tick. Then `this.tickCount` will be the
same for all of them, and we only need to consider the ID.
#example[
Consider a variation of the previous example, but where the items do not spawn on the same tick.
Their ages will be different. Again, assume no other entities spawn.
The result of this is that if you spawn several item entities, allow them to settle on a block, then
remove that block
1. Spawn item $A$ at $t=-10$.
2. Spawn items $B$ and $C$ in order at $t=-8$.
3. Spawn item $D$ at $t=-7$. Let them settle on a block.
4. At tick $t=0$, remove the supporting blocks.
5. At tick $t=1$, item $B$ begins to fall.
Based on when item $B$ fell, and accounting for the different item ages, when should we expect the
other items to fall?
#solution[
We'll need to track the item ages separately this time, but still oriented around $t=0$.
Let $"age"^B_0$ be item $B$'s age at $t=0$.
We know item $B$ fell at $t=1$, so we have the relation
$ "age"^B_0 + "id"^B + 1 = 0 mod4 $
Item $A$ spawned just before item $B$, so $"id"^A + 1 = "id"^B$. It spawned 2gt earlier, so $"age"^A_0 - 2= "age"^B_0$. Plug those in.
$ "age"^A_0 - 2 + "id"^A + 1 + 1 = 0 mod4 $
*$A$ must fall at $t=0$.*
Item $C$ spawned just after item $B$, so $"id"^C - 1 = "id"^B$. It spawned in the same tick, so $"age"^C_0 = "age"^B_0$. Plug those in.
$ "age"^C_0 + "id"^C - 1 + 1 = 0 mod4 $
*$C$ must fall at $t=0$.*
Item $D$ spawned just after item $B$, so $"id"^D - 2 = "id"^B$. It spawned 1gt later, so $"age"^D_0 + 1 = "age"^B_0$. Plug those in.
$ "age"^D_0 + 1 + "id"^D - 2 + 1 = 0 mod4 $
*$D$ must fall at $t=0$.*
]
#todo[Demonstration]
]
#example[
Now consider what it means if the pattern is broken. Keep the item ages the same for simplicity,
but this time do *not* assume that no other entities spawn.
1. Spawn items $A$, $B$, and $C$ in order in the same tick. Let them settle on a block.
2. At tick $t=0$, remove the supporting blocks. Item $C$ begins to fall.
3. At tick $t=1$, item $A$ begins to fall.
3. At tick $t=2$, item $B$ begins to fall.
What number of entities must have spawned between items $A$ and $B$? Between $B$ and $C$?
#solution[
Following the same conventions as before, where $x$ is the number of entities between $A$ and
$B$ and $y$ is the number of entities between $B$ and $C$.
The ids of $A$ and $B$ are related by
$ "id"^A + 1 + x = "id"^B $
And we observe the drop delay related by
$ "age"_0 + "id"^A + 1 = 0 mod4 $
$ "age"_0 + "id"^B + 2 = 0 mod4 $
Substitute $"id"^B$ and solve for $x$.
$
"age"_0 + "id"^A + 1 & = "age"_0 + "id"^A + 1 + x + 2 mod4 \
1 & = 3 + x mod4 \
-2 & = x mod4 \
-2 + 4 & = x mod4 \
2 & = x mod4 \
$
*So 2 entities must have spawned between $A$ and $B$.* (Or any number with a remainder of 2, like 6, 10, etc.)
The ids of $B$ and $C$ are related by
$ "id"^B + 1 + y = "id"^C $
And we observe the drop delay related related by
$ "age"_0 + "id"^B + 2 = 0 mod4 $
$ "age"_0 + "id"^C + 0 = 0 mod4 $
Substitute $"id"^C$ and solve for $y$.
$
"age"_0 + "id"^B + 2 & = "age"_0 + "id"^B + 1 + y + 0 mod4 \
2 & = 1 + y mod4 \
1 & = y mod4 \
$
*So 1 entity must have spawned between $B$ and $C$.* (Or any number with a remainder of 1, like 5, 9, etc.)
]
#todo[Demonstration]
]

View File

@@ -50,9 +50,9 @@
#let example = callout.with(kind: "eg", label: "For example:")
#let details(body, label: "Details") = {
#let details(body, label: "Details", open: false) = {
context if target() == "html" {
html.details({
html.details(open: open, {
html.summary(strong[Click for #label])
body
})
@@ -64,4 +64,5 @@
}
}
#let solution = details.with(label: "Solution")
// #let solution = details.with(label: "Solution")
#let solution = callout.with(kind: "solution", label: "Solution:")

View File

@@ -78,6 +78,10 @@ body {
border-width: 1px 0;
}
.callout .callout {
margin-inline: 0em;
}
hr {
margin: 0 -1em;
}