Come creare un fiume realistico senza conoscere in anticipo l'intera mappa?

Aug 24 2020

Intro

Sto sviluppando un gioco in tempo reale che ha una mappa generata dinamicamente e mi piacerebbe aggiungere i fiumi che vanno dalle montagne al mare.

Brevi informazioni sulla mappa

Nel mio gioco, quando un giocatore si sposta sul bordo della mappa attualmente generata, vengono caricati nuovi pezzi (piccolo pezzo quadrato di mappa) di mappa sul server. Se non vengono trovati blocchi per la posizione richiesta, vengono generati utilizzando lo stesso seme utilizzato in altre parti della mappa. Attualmente, non ci sono limiti alle dimensioni della mappa o alla quantità totale di blocchi generati. Sto usando il rumore Perlin per generare la mappa. La tratto come una mappa alta, con ogni campo che ha un intervallo di valori che occupa, ad esempio l'acqua bassa inizia da -0.12inclusiva e termina in 0esclusiva.

Ho già letto su come rendere realistico il fiume:

  • La mia mappa del fiume è anche lontanamente realistica?
  • Come si simula il percorso di un fiume?
  • Creazione di una mappa del mondo realistica - Waterways

Domanda

Come si aggiungono i fiumi alla mappa quando non so come appaiono le mappe intere? Se non so dove sono le montagne non posso individuare la sorgente del fiume. E se ho già generato una parte della mappa, non posso semplicemente aggiungere il fiume un po 'più tardi quando un giocatore incontra una catena montuosa.

Analogie

Uno scenario simile (credo) è in Minecraft. Anche lì, la mappa si genera mentre il giocatore si muove usando un seme e ci sono fiumi che continuano a turbinare mentre la mappa si genera. Purtroppo, non conosco la tecnica usata lì.

Schermate del gioco

Caricamento di blocchi temporaneamente disabilitato, per mostrare i limiti:

Risposte

14 Ash Aug 24 2020 at 15:54

Il problema è irrisolvibile come chiesto. Potresti finire per generare un fiume che il giocatore fa risalire alla cima di una collina minore nel mezzo di un deserto.

Ci sono alcune alternative che possono far funzionare questo:

LOD e fisica:

È possibile eseguire il subcampionamento e il supercampionamento del rumore Perlin per creare mappe multi-risoluzione. Se le tue tessere sono 1 tessera per 1 metro, puoi creare l'intera mappa a un livello più gestibile, ad esempio 1 tessera per 1 km, calcolare punti di primavera realistici e un percorso fluviale irregolare, quindi suddividere in giù, per dire 1 tessera per 100 m - a quel livello sai dove scorre il fiume con una precisione di 10 tessere, calcola dove scorre il fiume lungo quel percorso e poi dove il fiume scorre attraverso quelle tessere più piccole in modo ricorsivo, ecc., finché non arrivi al tuo livello di dettaglio completo.

È meglio precalcularlo e conservarlo, se possibile. Puoi ancora eseguirlo su richiesta, ma non è banale da programmare.

LOD e 1D perlin

Come sopra, sulla mappa a bassa risoluzione, trova il punto più alto da cui verrebbe una sorgente, trova il punto sul livello del mare più vicino, traccia una linea retta. Ora usa il rumore del perlin 1D per rendere il vento del fiume perpendicolare alla linea.

Questo è molto più facile da codificare: può avere alcuni artefatti non realistici, ma per un gioco di tessere 2D come questo è improbabile che li noti.

Fai finta

Avere 2 stili di fiumi. Uno in "salita", uno in "discesa". Crea tessere per mostrare il fiume proveniente da una sorgente e che si forma in un fiume pieno, e una che mostra un fiume pieno che si scarica in un piccolo elemento sotterraneo.

Se il valore del rumore del perlin per un'area costiera è un valore molto preciso, allora genera un fiume "in salita". Questo viaggia fino al punto più alto del bordo della tessera che non confina con una tessera esplorata, che poi quando viene caricata la tessera successiva, va al punto più alto successivo. Se rileva che è andato a un massimo locale (non c'è un punto più alto) o tutte le tessere vicine sono già state esplorate, torna indietro circa al centro, metti una tessera che mostri il fiume che esce da una grotta o sorgente o qualcos'altro sotto terra, quindi l'utente non vede il fiume partendo dalla cima di una piccola collina.

Se il valore del rumore del perlin per una montagna è un valore molto preciso, allora genera un fiume "in discesa", segue l'altro bordo più basso di una tessera inesplorata e se arriva al minimo locale, o un pezzo senza vicini inesplorati , metti una tessera che mostri il fiume che scompare sotto terra.

Questo di solito è abbastanza buono per un gioco 2D basato su tessere.

2 (o più) canali perlin

Attualmente stai eseguendo il generatore di perlin una volta per tessera, per dare un singolo valore. Suggerirei di eseguirlo più volte per piastrella (con semi diversi ovviamente e di solito fattori di ridimensionamento diversi). Usa quei valori multipli per popolare le tessere, invece di uno solo;

Questo può aiutare a rompere l'aspettativa che il faggio sia vicino alle pianure, le pianure di solito vicino alla foresta, la foresta di solito vicino alle montagne, ecc.

Se lo esegui due volte, suggerirei umidità ed elevazione. Se lo esegui 3 volte, suggerirei le dimensioni delle caratteristiche (sabbia / roccia, ghiaccio / neve o baren -> prateria -> macchia -> alberi), umidità (deserto -> fertile -> fiume -> palude) e elevazione (acqua -> pianura -> colline -> montagne). 4 volte forse includerebbe anche una temperatura.

Piuttosto che concentrarti sul far scorrere il tuo fiume "in discesa", prova a farlo scorrere dove l'umidità è all'interno di un particolare intervallo di contorno. Mentre il fiume non scorre "realisticamente" in discesa, in un gioco di tessere come quello che stai mostrando l'elevazione è oscurata, è meglio assicurarti che gli alberi crescano vicino ai fiumi, i fiumi non siano delimitati dal deserto e la terra vicino ai fiumi sia fertili terreni agricoli.

3 chasly-supportsMonica Aug 24 2020 at 06:54

Come si aggiungono i fiumi alla mappa quando non so come appaiono le mappe intere? Se non so dove sono le montagne non posso individuare la sorgente del fiume. E se ho già generato una parte della mappa, non posso semplicemente aggiungere il fiume un po 'più tardi quando un giocatore incontra una catena montuosa.

Non puoi farlo interamente in un blocco. Se sei sull'orlo di un blocco e sembra esserci un minimo locale, hai due scelte.

  1. Estendi il terreno in modo invisibile intorno al minimo finché non trovi il perimetro di quel minimo nel pezzo ancora inesplorato. Non devi completare l'intero nuovo pezzo perché a quel punto sai dove si scaricherà la piscina. Questo tornerà nel blocco corrente o da qualche parte, ancora incompleto, nel blocco non ancora esplorato. In altre parole, devi estenderti oltre ciò che è visibile / è stato esplorato. Si potrebbe chiamare questa programmazione just-in-case .

  2. Avere un algoritmo deterministico che si occupi specificamente di questa eventualità. Cioè, chiudo deliberatamente ogni possibile sbocco nel nuovo pezzo. In effetti hai costruito una diga. Questo quasi certamente porterà a manufatti dall'aspetto falso.

Nota che usare i minimi locali in questo modo (assumendo un terreno non permeabile) consentirà alla grana di essere fine come desideri. Questo potrebbe anche consentire di mostrare sorgenti e altre piccole sorgenti del fiume.

2 SZCZERZOKŁY Aug 24 2020 at 15:15

Alcuni anni fa ho scritto un algoritmo per un gioco di ruolo che funzionava in modo simile.
Pensa in "Campo minato". Quando scopri un quadrato di montagna c'è una probabilità% ax che ci sarà acqua. Ma quel quadrato influenza la probabilità che un pezzo accanto sia una montagna. Che influenzano l'aspetto dell'acqua. Per ogni mappa potresti imporre fonti d'acqua. La mappa viene avviata da un intervallo compreso tra 0 e 100. È la quantità di fonti d'acqua. Più la mappa non è ombreggiata, maggiore è la probabilità che l'acqua si alzi.

Ora, per aiutarti la natura è venuta con questa cosa elegante che i ruscelli appaiono e poi si infiltra nelle crepe e scompare. Oggigiorno con la tecnologia moderna possiamo risalire a dove è tornato, ma nella fase di "scoperta" una fonte potrebbe mostrare 3 o 4 diversi ruscelli. Quindi non hanno bisogno di essere una linea continua dalla fonte scoperta a "da qualche parte". Potrebbe terminare dopo 4 o 5 blocchi.

Quindi potresti terminare i pezzi generati dall'acqua quando il giocatore incontra il pezzo "secco" già scoperto.
O

Crea una modifica divertente nella tua mappa. Con il tempo (movimento del giocatore) i pezzi secchi si sono bagnati quando il generatore cerca di collegare la "pozza" d'acqua più grande (se inferiore). Il generatore potrebbe anche avere la probabilità di creare un ruscello, quindi non andrà nella linea più diritta.

Ricorda che il tuo giocatore si comporta come un umano tipico. Quindi potrebbero scoprire la sorgente del fiume, potrebbe scorrere in regioni non scoperte ma solo per divocazione e la loro presenza cambiano il modo in cui scorre l'acqua.

JohnO Aug 24 2020 at 21:49

L'algoritmo più semplice è che i fiumi si "aggancino" a una valle di montagna ogni volta che un fiume esistente si trova entro una certa distanza di soglia (e forse angolo) da una valle che soddisfa i requisiti minimi.

Supponiamo che tu abbia un fiume generato da qualsiasi algoritmo tu stia usando. Non esiste ancora una fonte esistente e finisce nella "nebbia di guerra" sulla mappa. Ma il giocatore si sposta per rivelarlo e tu usi l'algo per generare nuovamente i pezzi mancanti.

Presumendo che il tuo algoritmo generi occasionalmente montagne, se le montagne / valli vengono create entro n unità dalla "fine" del fiume e con un angolo inferiore a +/- 45 gradi della tangente del fiume, allora genera un percorso fluviale da quello indica la valle della montagna e posiziona un ghiacciaio lì.

Se il punto finale del fiume è più lontano di n unità, inizia a generare il suo percorso e se quel percorso arriva entro n unità della valle, fai come sopra.

Sarebbe necessario prima generare le montagne e poi sovrapporre il fiume sopra una mappa del genere.

Potresti persino riuscire a consentirgli di connettersi a diverse montagne / valli se ci sono più siti potenziali, e questo ti darebbe affluenti che si alimentano in un fiume principale in riva al mare.

Questo ovviamente si basa su uno schema di generazione di mappe in due parti, in cui vengono generati la maggior parte delle caratteristiche della mappa, e i fiumi sono "disegnati" sopra di esso. Funzionerebbe per Minecraft, ad esempio, che credo faccia questo. Se il tuo gioco fosse più sofisticato e usasse l'elevazione per determinare i percorsi dei fiumi, questo non sarebbe praticabile.