PlayPendium
Contraption · Voer voor de geest

Een level dat zelf bewijst dat het oplosbaar is

Het spel maakt nooit met de hand een puzzel. Het laat er een groeien uit één enkel getal, en speelt die puzzel vervolgens tegen zichzelf om er zeker van te zijn dat hij triviaal noch onmogelijk is voordat jij hem ooit te zien krijgt.

De datum van vandaag 1 getal, gehasht tot een seed
wordt
De dagelijkse puzzel 1 identiek veld voor iedereen

In het Engels geschreven en geredigeerd. Deze Nederlandse versie is met machinevertaling gemaakt; waar precisie ertoe doet, is het Engelse origineel leidend. Lees het origineel in het Engels →

01 · Alles uit één getal

Een hele wereld opgevouwen in een seed

Een Contraption-level wordt nergens opgeslagen. Er is geen bestand dat vermeldt waar het doel zit of hoe de richels liggen. In plaats daarvan wordt het hele level, de startpositie van de bal, de plek van het doel, het aantal en de plaatsing van de vaste muren, de voorraad onderdelen die je krijgt, berekend uit één enkel startgetal dat een seed heet. Geef de generator dezelfde seed en je krijgt, byte voor byte, dezelfde puzzel. 1

Dat kan omdat de enige bron van "willekeur" van de generator een kleine deterministische pseudowillekeurige-getallengenerator is. Die van Contraption is mulberry32, een compacte 32-bits generator van de hand van Tommy Ettinger; je herkent hem aan zijn kenmerkende constante, 0x6d2b79f5, die bij elke trekking bij de toestand wordt opgeteld. 2 Hij is snel, hij past in een paar regels en, cruciaal, hij is helemaal niet willekeurig: het is een vaste wiskundige reeks die er alleen maar gehusseld uitziet. Geef hem een startpunt en hij produceert voor altijd dezelfde stroom getallen. De generator leest die stroom vervolgens om te bepalen waar alles komt te staan.

02 · De dagelijkse puzzel

Hoe een datum een gedeelde uitdaging wordt

De modus Dagelijks leunt op dit determinisme om iets sociaals te doen. Zijn seed is niet willekeurig, hij wordt gefabriceerd uit de kalender. Het spel neemt de datum van vandaag in universele tijd, schrijft die in een korte tekenreeks zoals "contraption:2026-7-28" en haalt die tekst door een hashfunctie om hem in te dikken tot één 32-bits getal. 1

De hash is FNV-1a, een bekende niet-cryptografische mixer: hij begint bij een vaste offset, decimaal 2166136261, oftewel 0x811c9dc5, en vouwt voor elk teken de letter erin met een exclusieve-of, om daarna te vermenigvuldigen met het FNV-priemgetal 16777619. 3 Wat overblijft is een getal dat voor een gegeven dag stabiel is en van de ene dag op de andere wild verschilt, zodat een wijziging van één teken in de datum de seed volledig door elkaar gooit. Omdat de kalender voor iedereen dezelfde is, is de seed dat ook, en de puzzel dus ook. Twee vreemden aan weerszijden van de wereld openen Dagelijks en staan voor exact hetzelfde veld, en dat is precies wat het vergelijken van een score betekenisvol maakt.

De dagelijkse uitdaging is eerlijk, niet omdat een server iedereen hetzelfde level toestuurt, maar omdat ieders exemplaar onafhankelijk hetzelfde level opnieuw berekent uit dezelfde datum.

03 · De generator twijfelt aan zichzelf

De puzzel afwijzen die zichzelf oplost

Willekeurige geometrie is makkelijk; goede willekeurige geometrie niet. Een generator die zomaar een doel en wat richels rondstrooit, levert soms een level op waarin de bal, losgelaten vanaf de bovenkant, gewoon uit zichzelf recht in het doel valt. Dat is geen puzzel, dat is een tussenfilmpje. Dus voordat Contraption een kandidaatwereld accepteert, draait het een stille test die de code preSolved noemt: het simuleert het level met nul geplaatste onderdelen en controleert of de kale bal het doel alleen door de zwaartekracht bereikt. Als dat zo is, wordt het level weggegooid en gooit de generator opnieuw. 1

Dit is een subtiele omkering van hoe je normaal over een natuurkunde-engine denkt. Dezelfde functie simulate() die jouw machine afspeelt, wordt naar binnen gekeerd, tijdens het genereren, om de moeilijkheid van het level zelf te keuren. De engine is zowel de scheidsrechter van jouw oplossing als de kwaliteitsinspecteur van de puzzel.

04 · Een kleine oplosser, ingebouwd

"Kan dit met één onderdeel?"

Het te makkelijke level afwijzen is maar het halve werk. Het andere gevaar is het onmogelijke level, een doel dat ergens is weggestopt waar geen enkele opstelling van onderdelen bij kan. Contraption wapent zich hiertegen met een kleine brute-force-oplosser genaamd plausiblySolvable. Die denkt niet slim na. Hij probeert gewoon. 1

Concreet schuift hij één helling over een raster van posities over het veld en probeert hem op elke plek in vier verschillende standen gekanteld. Voor elk van die proefplaatsingen draait hij de volledige simulatie en vraagt: heeft die ene helling de bal thuisgebracht? Zodra één plaatsing slaagt, wordt het level oplosbaar verklaard en naar jou verscheept. Als er na de hele doorloop geen enkele werkt, gooit de generator het level liever weg en probeert hij een nieuwe seed.

De zoektocht van de oplosser met één onderdeel, een grof raster, telkens vier kantelingen
DoorloopparameterBereikBetekenis
Helling X15 → 85, stap 14kolommen over het veld
Helling Y30 → 120, stap 18rijen omlaag over het veld
Geprobeerde hoeken4±0.45 en ±0.8 radialen
Test per plaatsing1 volledige simulatiebereikt de bal het doel?

Het is de moeite waard eerlijk te zijn over wat dit bewijst, want de code is er ook eerlijk over: het commentaar noemt het een "goedkope plausibiliteitscontrole … niet uitputtend". Een level dat slaagt, heeft zeker minstens één grove oplossing met één helling. Een level dat faalt, is misschien nog steeds oplosbaar met een ventilator, een tandwiel of een slimmere helling die het raster nooit heeft geprobeerd, dus de generator behandelt falen niet als bewijs van onmogelijkheid. Hij bewaart de eerste niet-triviale wereld die hij vond als terugvaloptie, en als er veertig pogingen voorbijgaan zonder een schone oplossing met één onderdeel, verscheept hij die terugvaloptie in plaats van eindeloos door te lussen. Het resultaat is een pragmatische garantie: nooit een gratis overwinning, bijna altijd een echte weg naar binnen, en nooit een oneindig wachten op het "perfecte" level. 1

05 · Het diepere idee

Genereren-en-testen, de nederigste vorm van intelligentie

Neem een stap terug en de levelmaker van Contraption is een schoolvoorbeeld van een heel oud en heel algemeen probleemoplossingspatroon: genereren en testen. Stel willekeurig een kandidaat voor; toets hem aan je eisen; houd hem als hij slaagt, verwerp hem en stel een nieuwe voor als hij faalt. Het is de lus achter procedurele content in talloze spellen, achter een groot deel van de evolutionaire berekening en, met een beetje goede wil, achter natuurlijke selectie zelf: mutatie stelt voor, de omgeving test, overlevers blijven. 4

Wat de versie van Contraption elegant maakt, is dat de test geen goedkope benadering van speelbaarheid is, hij is speelbaarheid. De generator schat niet of een level eerlijk is door richels te tellen of afstanden te meten. Hij speelt het level letterlijk, twee keer: één keer leeg om er zeker van te zijn dat het geen cadeautje is, en één keer met een aftastende helling om er zeker van te zijn dat er een pad bestaat. Dezelfde deterministische natuurkunde die jouw oplossing zal beoordelen, is de natuurkunde die de puzzel heeft gekeurd. Er is geen aparte "levelvalidator" die uit de pas kan gaan lopen met de echte regels, want er is maar één set regels, die voor alles wordt gebruikt.

En omdat het allemaal deterministisch is, is de keuring in beide richtingen vrij van geluk. De dagelijkse seed kan niet samenspannen om de ene speler een makkelijker veld te geven dan de andere, en hij kan niemand een oneerlijk veld geven, want voordat het level een uitdaging is, heeft het het al overleefd om gespeeld te worden, door het spel, tegen zichzelf.

Sources & notes
  1. Seed-to-level generation, the preSolved rejection test, the plausiblySolvable one-ramp solver (grid ranges, four angles, up to 40 attempts, fallback world), and the daily-seed date string are all read directly from Contraption's own game engine and random-number code. Grounded in the game's code, not invented.
  2. mulberry32 is a compact 32-bit pseudo-random generator by Tommy Ettinger; it advances its state with the constant 0x6d2b79f5 and has a period of 2³². Author's reference gist (with his own later caveats on its equidistribution). gist.github.com/tommyettinger/46a874533244883189143505d203312c
  3. "Fowler–Noll–Vo hash function." Wikipedia, the 32-bit FNV offset basis is 2166136261 (0x811c9dc5) and the FNV prime is 16777619 (0x01000193); FNV-1a XORs each byte into the hash first and then multiplies by the prime. en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function
  4. On generate-and-test / "generation followed by evaluation" as a general search and problem-solving strategy, and its kinship with procedural generation and evolutionary methods. See "Procedural generation," Wikipedia. en.wikipedia.org/wiki/Procedural_generation
  5. Further reading on Procedural generation, [2410.15644] Procedural Content Generation in Games: A Survey with Insights on Emerging LLM Integration. arxiv.org.
  6. Further reading on Procedural generation, Procedural Content Generation in Games: A Survey with Insights on Emerging LLM Integration. doi.org.
  7. Further reading on Procedural generation, "Procedural City Generation with Combined Architectures for Real-time V" by Gr. open.clemson.edu.
Was this worth reading?
← Back to Contraption
PlayPendium · About · Contact · Privacy · Terms · Cookies · Accessibility · Copyright · Browse all games · Inspirations · © 2026