finish cellthing article (not cleaned up/proofread yet)

This commit is contained in:
Crispy 2024-06-02 18:57:49 +02:00
parent e529558a0b
commit 0fe6ae5adf
6 changed files with 47 additions and 14 deletions

View file

@ -79,7 +79,7 @@ So now the engine picks a random position, then checks the cache and picks a ran
I want to simulate a swarm of bees, so I create a rule for a bee moving by one cell, and enable <code>rotate</code> so it works in all directions. That was easy,<br>
</p>
<p>
<video src="snad/bees.mp4" controls></video><br>
<video src="snad/bees_biased.mp4" controls></video><br>
</p>
<p>
Oh no, the swarm is moving toward the top left instead of spreading equally. But I can see that the bees move in all four directions, so the rule seems to be rotated correctly.<br>
@ -95,22 +95,42 @@ In the diagram below, the bee would move left when the left (purple) cell is pic
<img src="snad/bee_movement_pattern.png" alt=""><br>
But to move right or down, it needs the bees own position to be picked by the engine, since the rules always extend right-down. That means when the engine picks the bee's position, there are <em>two</em> possible rules to execute. Therefore, moving right and down both have half the probability overall compared to moving up or left.<br>
</p>
<h3 id="the-overlap-checker">the overlap checker</h3>
<p>
TODO explain overlap checker<br>
In this version, the cache is not only searched for matches <em>at</em> the chosen position, but also <em>overlapping</em>. Given that, it only needs to pick positions within the world.<br>
</p>
<p>
Since the root issue was caused by asymmetry, I thought this implementation should be correct. This one was actually my first instinct when I created the cache, but as a <a href="https://gaussian.dev/">friend</a> suggested, an absolute-position based checker seemed (and indeed was) more performant and simpler, so I did that one first.<br>
</p>
<p>
<video src="snad/bees.mp4" controls></video><br>
</p>
<p>
Now the bees are evenly distributed, just like real bees!<sup>(false)</sup><br>
</p>
<h2 id="just-one-more-implementation">just one more implementation</h2>
<p>
I wasn't happy with the performance difference<br>
while I was trying to figure out the reason for the directional bias in the previous implementation, I realised that the overlap checker also has biases. the probability of any given cached match to be executed is dependent on its area, which is not very intuitive. two objects of different mass fall at different speeds<br>
While I was trying to figure out the reason for the directional bias in the previous implementation, I realised that the overlap checker also has biases. The probability of any given cached match to be executed is dependent on its area, which is not very intuitive. Two objects of different mass fall at different speeds, and adding empty padding to a rule makes it run faster.<br>
</p>
<p>
TODO video different sized blocks falling<br>
<video src="snad/rule_size_bias.mp4" controls></video><br>
</p>
<p>
TODO explain rule origin shifting<br>
Ideally the red, pink and blue cells should all fall at around the same rate, but the red sand always lands first and the pink last.<br>
</p>
<p>
go back to my <a href="/">other garbag</a><br>
Alright, the Final (I <em>hope</em>) implementation stores an origin offset for rules. This is zero for normal rules, but is automatically modified by rotation and mirroring, so that the origin always falls on the same actual rule cell. The picked position now needs to extend on all four edges, since rules may happen to have their origin point on a blank input cell, making it possible to trigger partially outside the world bounds. The amount to extend by is determined by the maximum width and height of all the rule variants, minus one since at least one cell has to be inside the bounds for the rule to have any effect.<br>
</p>
<h2 id="fin">fin</h2>
<p>
If you somehow read through all that, congratulations I think? Now enjoy this fire:<br>
<video src="snad/fire.mp4" controls></video><br>
</p>
<p>
Download the thing and make something fun: <a href="https://git.crispypin.cc/CrispyPin/snad">git.crispypin.cc/CrispyPin/snad</a><br>
</p>
<p>
Or go back to my <a href="/">other garbage</a><br>
</main>
</body>

Binary file not shown.

BIN
site/snad/bees_biased.mp4 Normal file

Binary file not shown.

BIN
site/snad/fire.mp4 Normal file

Binary file not shown.

Binary file not shown.

View file

@ -49,7 +49,7 @@ So now the engine picks a random position, then checks the cache and picks a ran
## swarm
I want to simulate a swarm of bees, so I create a rule for a bee moving by one cell, and enable `rotate` so it works in all directions. That was easy,
<video src="snad/bees.mp4" controls></video>
<video src="snad/bees_biased.mp4" controls></video>
Oh no, the swarm is moving toward the top left instead of spreading equally. But I can see that the bees move in all four directions, so the rule seems to be rotated correctly.
@ -63,15 +63,28 @@ In the diagram below, the bee would move left when the left (purple) cell is pic
But to move right or down, it needs the bees own position to be picked by the engine, since the rules always extend right-down. That means when the engine picks the bee's position, there are *two* possible rules to execute. Therefore, moving right and down both have half the probability overall compared to moving up or left.
TODO explain overlap checker
### the overlap checker
In this version, the cache is not only searched for matches *at* the chosen position, but also *overlapping*. Given that, it only needs to pick positions within the world.
Since the root issue was caused by asymmetry, I thought this implementation should be correct. This one was actually my first instinct when I created the cache, but as a [friend](https://gaussian.dev/) suggested, an absolute-position based checker seemed (and indeed was) more performant and simpler, so I did that one first.
<video src="snad/bees.mp4" controls></video>
Now the bees are evenly distributed, just like real bees!<sup>(false)</sup>
## just one more implementation
I wasn't happy with the performance difference
while I was trying to figure out the reason for the directional bias in the previous implementation, I realised that the overlap checker also has biases. the probability of any given cached match to be executed is dependent on its area, which is not very intuitive. two objects of different mass fall at different speeds
While I was trying to figure out the reason for the directional bias in the previous implementation, I realised that the overlap checker also has biases. The probability of any given cached match to be executed is dependent on its area, which is not very intuitive. Two objects of different mass fall at different speeds, and adding empty padding to a rule makes it run faster.
TODO video different sized blocks falling
<video src="snad/rule_size_bias.mp4" controls></video>
TODO explain rule origin shifting
Ideally the red, pink and blue cells should all fall at around the same rate, but the red sand always lands first and the pink last.
Alright, the Final (I *hope*) implementation stores an origin offset for rules. This is zero for normal rules, but is automatically modified by rotation and mirroring, so that the origin always falls on the same actual rule cell. The picked position now needs to extend on all four edges, since rules may happen to have their origin point on a blank input cell, making it possible to trigger partially outside the world bounds. The amount to extend by is determined by the maximum width and height of all the rule variants, minus one since at least one cell has to be inside the bounds for the rule to have any effect.
go back to my [other garbag](/)
## fin
If you somehow read through all that, congratulations I think? Now enjoy this fire:
<video src="snad/fire.mp4" controls></video>
Download the thing and make something fun: [git.crispypin.cc/CrispyPin/snad](https://git.crispypin.cc/CrispyPin/snad)
Or go back to my [other garbage](/)