cleanup
This commit is contained in:
202
content/core.typ
202
content/core.typ
@@ -1,6 +1,4 @@
|
|||||||
#import "/lib.typ": callout, example, note, solution, tip, todo
|
#import "/lib.typ": callout, details, example, note, solution, tip, todo
|
||||||
|
|
||||||
#let mod4 = $#h(0.5em)&(mod 4)$
|
|
||||||
|
|
||||||
= Core Mechanics <core>
|
= Core Mechanics <core>
|
||||||
|
|
||||||
@@ -18,48 +16,59 @@ the game*.
|
|||||||
|
|
||||||
Typically, item entities fall to the floor and sit stationary soon after being created. Processing
|
Typically, item entities fall to the floor and sit stationary soon after being created. Processing
|
||||||
movement for these stationary entities would be wasteful, so an optimization was added in 1.14: if
|
movement for these stationary entities would be wasteful, so an optimization was added in 1.14: if
|
||||||
an item is sitting stationary on a block, then only process movement every 4th tick.
|
an item is sitting stationary on a block, then only process movement for that item every 4th tick.
|
||||||
|
|
||||||
However, it would also be wasteful if every 4th tick processed _every_ item, so instead the items
|
However, it would also be wasteful if every 4th tick processed all items, so instead the items are
|
||||||
are divided into four groups. Each tick stationary items from only one of the four groups check for
|
divided into four staggered groups. Each tick stationary items from only one of the four groups
|
||||||
movement.
|
check for movement.
|
||||||
|
|
||||||
#callout(kind: "tip", label: "Key Point:")[
|
#callout(kind: "tip", label: "Key Point:")[
|
||||||
Stationary items can only begin to fall when their $"age" + "id"$ is a multiple of $4$.
|
Stationary items only begin to fall when their $"age" + "id"$ is a multiple of $4$.
|
||||||
]
|
]
|
||||||
|
|
||||||
Here is the relevant code path for the optimization:
|
In other words, divide the value by 4 and look at the remainder. If the remainder is 0, the item
|
||||||
|
checks for movement. That condition is written as `... % 4 == 0` in Java and as $... equiv 0 &(mod
|
||||||
|
4)$ in math.
|
||||||
|
|
||||||
```java
|
#tip[
|
||||||
public class ItemEntity extends Entity {
|
You can freely add or subtract multiples of 4 to any expression without changing the value $mod 4$.
|
||||||
public void tick() {
|
|
||||||
...
|
|
||||||
if (this.onGround() && !(this.getDeltaMovement().horizontalDistanceSqr() > (double)1.0E-5F) && (this.tickCount + this.getId()) % 4 != 0) {
|
|
||||||
...
|
|
||||||
} else {
|
|
||||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
|
||||||
...
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Entity {
|
For example, $-1 equiv 3 &(mod 4)$ because $3 = -1 + 4$.
|
||||||
public void move(final MoverType moverType, Vec3 delta) {
|
]
|
||||||
...
|
|
||||||
this.setOnGroundWithMovement(this.verticalCollisionBelow, this.horizontalCollision, movement);
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnGroundWithMovement(final boolean onGround, final boolean horizontalCollision, final Vec3 movement) {
|
|
||||||
this.onGround = onGround;
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#note[ `onGround` is only ever updated via `move`, and this branch is the *only* place that
|
#details(label: [the relevant Java code])[
|
||||||
`ItemEntity.move` is called. ]
|
#note[ `onGround` is only ever updated via `move`, and this branch is the *only* place that
|
||||||
|
`ItemEntity.move` is called. `tickCount` is the item's age. ]
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ItemEntity extends Entity {
|
||||||
|
public void tick() {
|
||||||
|
...
|
||||||
|
if (this.onGround() && !(this.getDeltaMovement().horizontalDistanceSqr() > (double)1.0E-5F) && (this.tickCount + this.getId()) % 4 != 0) {
|
||||||
|
...
|
||||||
|
} else {
|
||||||
|
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Entity {
|
||||||
|
public void move(final MoverType moverType, Vec3 delta) {
|
||||||
|
...
|
||||||
|
this.setOnGroundWithMovement(this.verticalCollisionBelow, this.horizontalCollision, movement);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnGroundWithMovement(final boolean onGround, final boolean horizontalCollision, final Vec3 movement) {
|
||||||
|
this.onGround = onGround;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
The effect is that if the item is on a block and has negligible horizontal momentum, it *cannot
|
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
|
fall* until the condition is satisfied, even if it's no longer on the ground. It can only fall early
|
||||||
@@ -86,36 +95,44 @@ of other items.
|
|||||||
Based on when item $B$ fell, when should we expect the other items to fall?
|
Based on when item $B$ fell, when should we expect the other items to fall?
|
||||||
|
|
||||||
#solution[
|
#solution[
|
||||||
To simplify the arithmetic, orient everything around $t=0$. So we'll let $"age"_0$ to be the
|
To simplify the arithmetic, orient everything around $t=0$. So we'll let $"age"_0$ be the
|
||||||
items' ages at $t=0$ and add tick offsets from there. All items spawned in the same tick, so
|
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$.
|
they all have the same $"age"_0$.
|
||||||
|
|
||||||
Since $B$ falls at $t=1$, the relation for $"id"^B$ must be
|
Since $B$ falls at $t=1$, the relation for $"id"_B$ must be
|
||||||
$ "age"_0 + "id"^B + 1 = 0 mod4 $
|
|
||||||
|
|
||||||
$A$ spawned right before $B$, so $"id"^A + 1 = "id"^B$. Plug that in to the relation we got for
|
$ "age"_0 + "id"_B + 1 equiv 0 & (mod 4) $
|
||||||
$"id"^B$.
|
|
||||||
$ "age"_0 + "id"^A + 1 + 1 = 0 mod4 $
|
Item $A$ gets the ID 1 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 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
*$A$ must fall at $t=2$.*
|
*$A$ must fall at $t=2$.*
|
||||||
|
|
||||||
$C$ spawned right after $B$, so its id is $"id"^C - 1= "id"^B$. Plug that in.
|
Item $C$ gets the ID 1 after $B$, so $"id"_C - 1= "id"_B$. Plug that in.
|
||||||
$ "age"_0 + "id"^C - 1 + 1 = 0 mod4 $
|
|
||||||
|
$ "age"_0 + "id"_C - 1 + 1 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
*$C$ must fall at $t=0$.*
|
*$C$ must fall at $t=0$.*
|
||||||
|
|
||||||
$D$ spawned right after $C$, so its id is $"id"^D - 2 = "id"^B$. Plug that in.
|
Item $D$ gets the ID 2 after $B$, so $"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 - 2 + 1 & equiv 0 & (mod 4) \
|
||||||
"age"_0 + "id"^D - 1 &= 0 mod4 \
|
"age"_0 + "id"_D + 3 & equiv 0 & (mod 4)
|
||||||
"age"_0 + "id"^D - 1 + 4 &= 0 mod4 \
|
|
||||||
"age"_0 + "id"^D + 3 &= 0 mod4
|
|
||||||
$
|
$
|
||||||
|
|
||||||
*$D$ must fall at $t=3$.*
|
*$D$ must fall at $t=3$.*
|
||||||
|
|
||||||
|
#callout(kind: "tip", label: "Therefore:")[
|
||||||
|
The expected fall times are:
|
||||||
|
|
||||||
|
- $C$ at $t=0$.
|
||||||
|
- $B$ at $t=1$.
|
||||||
|
- $A$ at $t=2$.
|
||||||
|
- $D$ at $t=3$.
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
#todo[Demonstration]
|
#todo[Demonstration]
|
||||||
@@ -137,22 +154,42 @@ of other items.
|
|||||||
#solution[
|
#solution[
|
||||||
We'll need to track the item ages separately this time, but still oriented around $t=0$.
|
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$.
|
Let $"age"_(0, B)$ be item $B$'s age at $t=0$.
|
||||||
|
|
||||||
We know item $B$ fell at $t=1$, so we have the relation
|
We know item $B$ fell at $t=1$, so we have the relation
|
||||||
$ "age"^B_0 + "id"^B + 1 = 0 mod4 $
|
$ "age"_(0, B) + "id"_B + 1 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
|
#todo[Add "gt" to the glossary]
|
||||||
|
|
||||||
|
Item $A$ gets the ID 1 before $B$, so $"id"_A + 1 = "id"_B$.
|
||||||
|
It spawned 2gt earlier, so $"age"_(0, A) - 2= "age"_(0, B)$. Plug those in.
|
||||||
|
|
||||||
|
$ "age"_(0, A) - 2 + "id"_A + 1 + 1 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
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$.*
|
*$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.
|
Item $C$ gets the ID 1 after $B$, so $"id"_C - 1 = "id"_B$.
|
||||||
$ "age"^C_0 + "id"^C - 1 + 1 = 0 mod4 $
|
It spawned in the same tick, so $"age"_(0, C) = "age"_(0, B)$. Plug those in.
|
||||||
|
|
||||||
|
$ "age"_(0, C) + "id"_C - 1 + 1 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
*$C$ must fall at $t=0$.*
|
*$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.
|
Item $D$ gets the ID 2 after $B$, so $"id"_D - 2 = "id"_B$.
|
||||||
$ "age"^D_0 + 1 + "id"^D - 2 + 1 = 0 mod4 $
|
It spawned 1gt later, so $"age"_(0, D) + 1 = "age"_(0, B)$. Plug those in.
|
||||||
|
|
||||||
|
$ "age"_(0, D) + 1 + "id"_D - 2 + 1 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
*$D$ must fall at $t=0$.*
|
*$D$ must fall at $t=0$.*
|
||||||
|
|
||||||
|
#callout(kind: "tip", label: "Therefore:")[
|
||||||
|
The expected fall times are:
|
||||||
|
|
||||||
|
- $A$ at $t=0$.
|
||||||
|
- $C$ at $t=0$.
|
||||||
|
- $D$ at $t=0$.
|
||||||
|
- $B$ at $t=1$.
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
#todo[Demonstration]
|
#todo[Demonstration]
|
||||||
@@ -165,7 +202,7 @@ of other items.
|
|||||||
1. Spawn items $A$, $B$, and $C$ in order in the same tick. Let them settle on a block.
|
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.
|
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=1$, item $A$ begins to fall.
|
||||||
3. At tick $t=2$, item $B$ begins to fall.
|
4. 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$?
|
What number of entities must have spawned between items $A$ and $B$? Between $B$ and $C$?
|
||||||
|
|
||||||
@@ -175,43 +212,48 @@ of other items.
|
|||||||
|
|
||||||
The ids of $A$ and $B$ are related by
|
The ids of $A$ and $B$ are related by
|
||||||
|
|
||||||
$ "id"^A + 1 + x = "id"^B $
|
$ "id"_A + 1 + x = "id"_B $
|
||||||
|
|
||||||
And we observe the drop delay related by
|
And the observed drop delays satisfy
|
||||||
|
|
||||||
$ "age"_0 + "id"^A + 1 = 0 mod4 $
|
$ "age"_0 + "id"_A + 1 equiv 0 & (mod 4) $
|
||||||
$ "age"_0 + "id"^B + 2 = 0 mod4 $
|
$ "age"_0 + "id"_B + 2 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
Substitute $"id"^B$ and solve for $x$.
|
Substitute $"id"_B$ and solve for $x$.
|
||||||
|
|
||||||
$
|
$
|
||||||
"age"_0 + "id"^A + 1 & = "age"_0 + "id"^A + 1 + x + 2 mod4 \
|
"age"_0 + "id"_A + 1 + x + 2 & equiv "age"_0 + "id"_A + 1 & (mod 4) \
|
||||||
1 & = 3 + x mod4 \
|
x + 2 & equiv 0 & (mod 4) \
|
||||||
-2 & = x mod4 \
|
x & equiv 2 & (mod 4) \
|
||||||
-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.)
|
*So the number of entities between $A$ and $B$ is $2 &(mod 4)$.* (For example, 2, 6, 10, ...)
|
||||||
|
|
||||||
The ids of $B$ and $C$ are related by
|
The ids of $B$ and $C$ are related by
|
||||||
|
|
||||||
$ "id"^B + 1 + y = "id"^C $
|
$ "id"_B + 1 + y = "id"_C $
|
||||||
|
|
||||||
And we observe the drop delay related related by
|
And the observed drop delays satisfy
|
||||||
|
|
||||||
$ "age"_0 + "id"^B + 2 = 0 mod4 $
|
$ "age"_0 + "id"_B + 2 equiv 0 & (mod 4) $
|
||||||
$ "age"_0 + "id"^C + 0 = 0 mod4 $
|
$ "age"_0 + "id"_C + 0 equiv 0 & (mod 4) $
|
||||||
|
|
||||||
Substitute $"id"^C$ and solve for $y$.
|
Substitute $"id"_C$ and solve for $y$.
|
||||||
|
|
||||||
$
|
$
|
||||||
"age"_0 + "id"^B + 2 & = "age"_0 + "id"^B + 1 + y + 0 mod4 \
|
"age"_0 + "id"_B + 1 + y + 0 & equiv "age"_0 + "id"_B + 2 & (mod 4) \
|
||||||
2 & = 1 + y mod4 \
|
y - 1 & equiv 0 & (mod 4) \
|
||||||
1 & = y mod4 \
|
y & equiv 1 & (mod 4) \
|
||||||
$
|
$
|
||||||
|
|
||||||
*So 1 entity must have spawned between $B$ and $C$.* (Or any number with a remainder of 1, like 5, 9, etc.)
|
*So the number of entities between $B$ and $C$ is $1 &(mod 4)$.* (For example, 1, 5, 9, ...)
|
||||||
|
|
||||||
|
#callout(kind: "tip", label: "Therefore:")[
|
||||||
|
The number of spawned entities must be
|
||||||
|
|
||||||
|
- $2 &(mod 4)$ between $A$ and $B$.
|
||||||
|
- $1 &(mod 4)$ between $B$ and $C$.
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
#todo[Demonstration]
|
#todo[Demonstration]
|
||||||
|
|||||||
3
lib.typ
3
lib.typ
@@ -16,9 +16,10 @@
|
|||||||
warn: color.rgb("#a52a2a"),
|
warn: color.rgb("#a52a2a"),
|
||||||
tip: color.rgb("#228b22"),
|
tip: color.rgb("#228b22"),
|
||||||
todo: color.rgb("#ff0000"),
|
todo: color.rgb("#ff0000"),
|
||||||
|
eg: auto,
|
||||||
).at(kind)
|
).at(kind)
|
||||||
block(
|
block(
|
||||||
fill: col.transparentize(85%),
|
fill: if (col != auto) {col.transparentize(85%)} else {auto},
|
||||||
stroke: (y: col),
|
stroke: (y: col),
|
||||||
width: 100%,
|
width: 100%,
|
||||||
outset: (x: 1em, y: 0.5em),
|
outset: (x: 1em, y: 0.5em),
|
||||||
|
|||||||
Reference in New Issue
Block a user