Download Game! Currently 67 players and visitors. Last logged in:XothGlauriNakkiFimir

Blitzer's Blog >> 71677

Back to blogs index
Posted: 05 Aug 2026 23:42 [ permalink ]
Determinismi on ruudukkopohjaisten simulaatioiden pyhC$ graali. Jos
pelisilmukka (Game Loop) vain kC$y ruudukon lC$pi vasemmalta oikealle ja
ylhC$C$ltC$ alas (pC$ivittC$en soluja sitC$ mukaa kun ne tulevat vastaan),
syntyy "kellotauluefekti": oikealle alaviistoon liikkuvat organismit liikkuvat
vahingossa tuplasti nopeammin kuin vasemmalle ylC$viistoon liikkuvat.
TC$mC$n vC$lttC$miseksi  ja jotta simulaatio toimii salamannopeasti aiemmin
mC$C$ritellyillC$ 1D-taulukoilla (SoA)  moottorin on kC$ytettC$vC$ Aikeisiin
perustuvaa kaksoispuskurointia (Intent-based Double Buffering).
Yksi kokonainen moottorin Tick jakautuu kuuteen ehdottoman tiukkaan
vaiheeseen. Koko ruudukon tila on jC$C$dytetty (Read Buffer), kunnes kaikki 6
vaihetta on laskettu, ja vasta sitten uusi todellisuus astuu voimaan (Write
Buffer).
TC$ssC$ on sekunnin murto-osassa tapahtuva pelisilmukka alusta loppuun:
Vaihe 1: Astrofysiikka (Valo ja Varjo)
Kaikki alkaa tC$hdestC$. TC$mC$ vaihe tuo kentC$lle uuden energian.
 * TC$hden liike: Lasketaan tC$hden uusi (x, y, z) sijainti 3D-avaruudessa.
 * SC$teenjC$ljitys (Raycasting): Moottori vetC$C$ linjat tC$hdestC$ kohti
kenttC$C$.
 * LC$mpeneminen: Solut, joihin valo osuu, saavat lisC$C$ lC$mpC6C$ (niiden
heatLevels -arvoa kasvatetaan Write-puskurissa absorptiokertoimen mukaan).
 * Varjostus: Takana olevat solut jC$C$vC$t varjoon opasiteettisC$C$ntC6jen
mukaisesti, jolloin niiden lC$mmC6nsaanti estyy.
Vaihe 2: Termodynamiikka (Johtuminen ja JC$C$htyminen)
Nyt kun aurinko on antanut energiansa, katsotaan miten se jakautuu organismien
sisC$llC$.
 * Johtuminen: Jokaista solua verrataan sen neljC$C$n naapuriin. Jos
vierekkC$isten solujen vC$lillC$ on lC$mpC6tilaero, lC$mpC6C$ siirretC$C$n
kuumemmasta kylmempC$C$n materiaalin "johtavuus"-kertoimen (Conductivity)
nopeudella. NC$in moottori vetC$C$ lC$mpC6C$ sensoreilta.
 * Entropia: Kaikki solut menettC$vC$t kiinteC$n prosentin (esim. 1 %)
lC$mmC6stC$C$n avaruuteen. Jos solun lC$mpC6 putoaa tC$yteen nollaan, se ei
voi enC$C$ toimia (mutta 8. bitti pysyy yhC$ pC$C$llC$, solu vain vaipuu
horrokseen).
Vaihe 3: SC$teily ja Genesis
TC$ssC$ vaiheessa ratkaistaan kentC$n villit kortit ja mutaatiot.
 * SC$teilykentC$t: Lasketaan RAD-solujen yhteisvaikutus.
 * Yliannostus & HerC$tys: Tarkistetaan solut sC$teilykentissC$.
HerC$tetC$C$nkC6 joku henkiin (8. bitti 0 -> 1), vai kC$rsiikC6 joku
yliannostuksen ja kuolee (1 -> 0)?
 * Kriittinen massa: Jos sC$teily ylittC$C$ absoluuttisen ylivuotokynnyksen,
laukaistaan Genesis-mutaatio. Moottori puuttuu viereisten solujen
alkuperC$isiin ASCII-koodeihin, kC$C$ntC$C$ ne uudelleen 32-bittisiksi
OpCodeiksi (kuten edellisessC$ viestissC$ suunniteltiin) ja palauttaa ne
peliin muuttuneina.
Vaihe 4: Aikeet (Intent - Suoritus)
Nyt ajetaan solujen tekoC$ly. TC$ssC$ vaiheessa mikC$C$n solu ei vielC$ liiku.
Ne vain esittC$vC$t "toiveita" siitC$, mitC$ ne haluavat tehdC$.
 * Moottori kC$y lC$pi vain ne solut, jotka ovat elossa (8. bitti pC$C$llC$)
ja joilla on riittC$vC$sti lC$mpC6energiaa.
 * Prosessori purkaa solun 32-bittisen OpCoden ja suorittaa sen sC$C$nnC6n
(esim. Jos edessC$ este, tyC6nnC$).
 * Aie-puskuri (Intent Buffer): Sen sijaan, ettC$ solu liikutettaisiin heti,
moottori kirjoittaa Intent-taulukkoon merkinnC$n: "Solu indeksissC$ 1042
haluaa siirtyC$ ruutuun 1043 voimalla X (solun lC$mpC6arvo)."
Vaihe 5: Konfliktinratkaisu (Deterministinen Kaaos)
TC$mC$ on pelin sC$C$ntC6jen tC$rkein vaihe. Koska useampi solu saattaa haluta
samaan ruutuun yhtC$ aikaa (tai tyC6ntC$C$ toisiaan vastaan), fysiikan on
puututtava peliin.
 * Moottori kC$y lC$pi Intent-puskurin ja etsii konfliktit (pC$C$llekkC$isyydet
).
 * LC$mpC6 ratkaisee: Jos solu A ja solu B yrittC$vC$t astua samaan ruutuun,
verrataan niiden varastoimaa LC$mpC6C$.
   * Jos LC$mpC6 A > LC$mpC6 B (yli kynnysarvon): Solu A voittaa. Sen aie
hyvC$ksytC$C$n. Solu B menettC$C$ vuoronsa (sen aie perutaan ja se ehkC$
menettC$C$ lC$mpC6C$ tC6rmC$yksessC$).
   * Jos LC$mpC6 on tasan (tai alle kynnyksen): Conway-TC6rmC$ys. Kumpikaan ei
voita. Aikeet perutaan, ja solut ottavat "kineettistC$ vahinkoa" tai reagoivat
symbioottisesti sC$C$ntC6jen mukaan.
 * Ketjureaktiot (Massa): Jos Moottori tyC6ntC$C$ kiveC$, moottori laskee
kivien massan yhteen. Jos massa on pienempi kuin moottorin lC$mpC6/voima, koko
rivi siirtyy Write-puskurissa askeleen eteenpC$in.
Vaihe 6: Commit (Puskurien vaihto)
Kaikki on nyt laskettu tC$ysin deterministisesti vanhan tilan (Read Buffer)
pohjalta.
 * HyvC$ksytyt Aikeet on nyt kirjoitettu uuteen tilaan (Write Buffer).
 * Vanhan ja uuden taulukon osoittimet (Pointers) vaihdetaan pC$ittC$in
muistissa: Read = Write; Write = Read; (TC$mC$ operaatio vie prosessorilta
tasan yhden kellojakson, koska vain muistiosoitetta vaihdetaan).
 * Tick on pC$C$ttynyt. Peli on siirtynyt askeleen eteenpC$in. Aikaa tC$hC$n
kaikkeen on kulunut ehkC$ 0.05 millisekuntia.
Miksi tC$mC$ rakenne on tC$ydellinen?
TC$mC$n silmukan nerokkuus piilee siinC$, ettC$ Vaiheet 14 ovat tC$ysin
rinnakkaistettavissa (Multithreading).
Koska mikC$C$n solu ei muuta kenttC$C$ Vaiheessa 4, voimme pilkkoa 128x128
ruudukon neljC$C$n osaan ja antaa tietokoneen neljC$n ytimen (tai
WebGL/WebGPU-pohjaisen nC$ytC6nohjaimen) ajaa solujen aivot lC$pi
samanaikaisesti!
Vasta Vaiheessa 5 (Konfliktinratkaisu) sC$ikeet tuodaan yhteen ja sC$C$nnC6t
ratkaistaan keskitetysti. TC$mC$ mahdollistaa jopa miljoonien solujen
simuloimisen 60 FPS nopeudella selainympC$ristC6ssC$.