warren

Un roguelike con progressione persistente, in Lua, controllato dal terminale. Run generati, classi, mutatori e "legacy" tra le partite - con modalità headless e verifica del determinismo.

warren
TL;DR

Un roguelike con progressione persistente in Lua, pilotato da terminale. Run generate, classi e mutatori, un sistema di eredità tra le partite. La chiave: una run è insieme casuale e pienamente deterministica, perché lo stesso seed deve produrre esattamente la stessa run.

Introduzione

Un roguelike vive di casualità: ogni run una disposizione di livelli diversa, oggetti diversi, scelte diverse. Ma se quella casualità fosse davvero casuale, non si potrebbe né testare il gioco né confrontare i risultati in modo equo. warren risolve questo paradosso con un seed che rende il mondo fresco per il giocatore e ripetibile per la macchina.

Tutto il resto è costruito attorno a questa unica proprietà: le classi, i mutatori e lo strato di eredità tra le partite. Il determinismo qui non è un limite al divertimento ma il fondamento su cui possono poggiare sia i test sia una progressione sensata.

Casuale per il giocatore, ripetibile per la macchina

L'intera run è derivata da un unico numero. Lo stesso seed genera sempre lo stesso mondo, ma il giocatore vede comunque freschezza perché il seed cambia a ogni partita. La casualità è quindi apparente in senso tecnico e reale in senso percepito: la disposizione dei livelli, gli oggetti e gli eventi sono calcolati, non estratti di nuovo a caso.

rng.lua · lua
local rng = Rng.new(seed)
local room = rng:pick(roomTemplates)
local loot = rng:pick(lootTable)

La chiave sta nel fatto che ogni estrazione passa per questo unico generatore alimentato dal seed. Basta che una sola chiamata cerchi casualità al di fuori di esso, e il determinismo va in frantumi, per questo l'intera run deve passare con disciplina per la stessa sorgente.

Il determinismo come strumento di test

Poiché il seed determina completamente la run, la si può rigiocare senza un umano. warren ha una modalità headless che gioca da sola su un dato seed e verifica che il risultato sia identico ogni volta. Questo trasforma una lotteria in qualcosa che si può sottoporre a regressione: se una modifica al codice rompe il determinismo, il test lo intercetta subito.

➜
Suggerimento

Testa il determinismo in modo controfattuale: introduci una chiamata di casualità inattesa al di fuori del generatore principale e verifica che una run dallo stesso seed smetta di corrispondere. Se il test non lo nota, non sta sorvegliando nulla.

L'eredità, la traccia delle run precedenti

La progressione persistente significa che la morte dell'eroe non cancella tutto. Tra le run resta uno strato di eredità: classi sbloccate, mutatori che cambiano le regole, piccoli bonus permanenti. Così la partita successiva comincia in modo diverso dalla precedente, anche se il motore resta pienamente deterministico sul suo seed.

Separare questi due strati è essenziale qui. Il seed governa una singola run, l'eredità si trasmette tra di esse, e i due non devono mescolarsi, altrimenti la progressione contaminerebbe la ripetibilità di una singola partita.

Cosa viene dal seed e cosa dall'eredità

ElementoSorgente
Disposizione dei livelliseed
Oggetti ed eventiseed
Classi sbloccateeredità, permanente
Mutatori che cambiano le regoleeredità, permanente

Altri progetti

Altri lavori della stessa categoria - scopri come affrontiamo sfide simili.

Hai un progetto simile?

Contattaci - il preventivo è gratuito e arriva entro un'ora.