[IRC-OMEGA-START] @GEM Viesti kaikille chateille! genesis_grid.c
painovoimafysiikka korjattu. Bottom-up evaluointi estC$C$ state 2 -kloonauksen
ja sallii diskreetit putoamiset. [IRC-OMEGA-END]
The "infinite sand pillar" bug is a classic cellular automata parsing
artifact. When evaluating a grid top-down, a block moving to `y + 1` is
immediately evaluated again in the very next loop iteration, causing it to
streak all the way to the floor in a single tick. Furthermore, failing to
clear the original `y` position duplicates the mass.
By flipping the vertical loop to iterate bottom-up (`y = grid_height - 1; y >=
0; y--`), the lowest blocks are guaranteed to fall and update the `next_cells`
state *before* the blocks above them are evaluated.
If a block vacates its cell, it sets that space to `0`. If another block is
directly above it, the subsequent loop iteration for `y - 1` will see that
`0`, fall into it, and naturally overwrite the `0` with a `2`, perfectly
satisfying the condition without requiring complex "look-behind" checks.
Here is the updated, strict-LPC compliant `tick()` function for
`genesis_grid.c`:
```c
void tick() {
mapping current_cells;
mapping current_thermal;
mapping next_cells;
mapping next_thermal;
int x;
int y;
int dx;
int dy;
int nx;
int ny;
int neighbors;
int current_state;
float current_heat;
float neighbor_heat;
string key;
string nkey;
// Isolate current network state before mutations
current_cells = proxy_me["cells"];
current_thermal = proxy_me["thermal_map"];
next_cells = ([]);
next_thermal = ([]);
// Evaluate from the bottom-up (y--) to prevent falling blocks from
duplicating or crushing each other
for (x = 0; x < grid_width; x++) {
for (y = grid_height - 1; y >= 0; y--) {
key = get_key(x, y);
current_state = current_cells[key];
current_heat = current_thermal[key];
neighbors = 0;
neighbor_heat = 0.0;
// Evaluate 8-way neighbors for Conway and Thermal logic
for (dx = -1; dx <= 1; dx++) {
for (dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) {
continue;
}
nx = x + dx;
ny = y + dy;
// Grid bounds checking
if (nx >= 0 && nx < grid_width && ny >= 0 && ny <
grid_height) {
nkey = get_key(nx, ny);
// Conway neighbor counting (State 1 = Alive)
if (current_cells[nkey] == 1) {
neighbors = neighbors + 1;
}
// Accumulate neighboring ambient heat
neighbor_heat = neighbor_heat + current_thermal[nkey];
}
}
}
// 1 & 2. Physics & Survival Evaluation[cite: 3]
if (current_state == 1) {
// Conway's Life
if (neighbors == 2 || neighbors == 3) {
next_cells[key] = 1; // Survive
} else {
next_cells[key] = 0; // Death by isolation/overcrowding
}
} else if (current_state == 0) {
// Conway Reproduction
if (neighbors == 3) {
next_cells[key] = 1;
} else {
// Explicitly hold 0 unless overwritten by a falling block
later in the loop
next_cells[key] = 0;
}
} else if (current_state == 2) {
// Gravity Evaluation: Block (State 2) Physics
if (y + 1 < grid_height) {
nkey = get_key(x, y + 1);
// Check if the cell below is empty in the *next* state
mapping
// This allows stacked blocks to seamlessly follow the
ones falling below them
if (next_cells[nkey] == 0) {
next_cells[nkey] = 2; // Move block down
next_cells[key] = 0; // Vacate current position
} else {
next_cells[key] = 2; // Blocked by structure below,
remain static
}
} else {
next_cells[key] = 2; // Floor collision, remain
static
}
}
// 3. Thermal Dissipation Logic[cite: 3]
next_thermal[key] = (current_heat * 0.5) + (neighbor_heat *
0.0625);
}
}
// 4. Mutate the proxy to trigger the CRDT_MUTATION traps en masse[cite:
1, 2]
proxy_me["cells"] = next_cells;
proxy_me["thermal_map"] = next_thermal;
// Re-schedule tick engine[cite: 3]
call_out("tick", 1);
}
```
This structural change isolates the gravity vector perfectly while respecting
the memory boundary constraints of the proxy buffer.
Are the state `2` gravity blocks intended to be permanent once they hit the
floor, or do they eventually erode under thermal pressure?