Losowa funkcja nasion do generowania mapy?

28

Szukam funkcji do generowania losowej mapy opartej na kafelkach, gdy zmieniają się wizualne granice mapy (przechodząc przez mapę). Chcę, aby mapa była nieskończenie duża i miała strukturę przypominającą labirynt.

Jeśli jednak świat jest nieskończony, powrót do miejsca, w którym był już gracz, podnosi problem. Gra musi pamiętać, jak naprawdę wszystko tam wyglądało.

Pomyślałem więc: „Jak Minecraft rozwiązuje ten problem?” i pomyślałem sobie, że muszą używać jakiejś funkcji liczby losowej z ziarnem, która może zarówno iść do przodu, jak i do tyłu, i w ten sposób odtwarzać stare kafelki dokładnie tak, jak były, ale w nowych przypadkach.

Co o tym myślisz?

Mathias Lykkegaard Lorenzen
źródło
Jak brzmi moja odpowiedź na +5, a pytanie tylko na +2? To jest jedno z najlepszych pytań na pierwszej stronie.
2
Czy Minecraft nie przechowuje po prostu fragmentów, które już odwiedziłeś / zmodyfikowałeś?
FxIII,
@FxIII: Minecraft musi, ponieważ możesz modyfikować krajobraz. Jeśli nie możesz tego zrobić, przechowywanie fragmentów jest prawdopodobnie marnotrawstwem, a przynajmniej nadmierną komplikacją.
@Joe Wreschnig: Ok, Ok ... Bałam się, że przegapiłem coś naprawdę dużego!
FxIII,

Odpowiedzi:

20

Zauważyłeś różnicę między generatorem liczb losowych a funkcją szumu . Generator liczb losowych wyrzuca inny numer za każdym razem, gdy go wywołujesz. Funkcja szumu pobiera pewne argumenty - powiedzmy mapę xiy - i wyrzuca liczby o losowych właściwościach statystycznych , ale za każdym razem o tej samej wartości dla tych samych argumentów , tj. Jest to właściwa funkcja matematyczna.

Oba są bardzo ściśle powiązane. Funkcja hałas może symulować generator liczb losowych, przekazując w innej wartości za każdym razem - na przykład noise(1), noise(2)i tak dalej. A generator liczb losowych, zrzucony do gigantycznej tabeli, może działać jako funkcja szumu. W obu przypadkach używasz niewłaściwego narzędzia do pracy.

Minecraft w szczególnych zastosowań Perlin hałasu , rodzaj hałasu, który jest tani, aby obliczyć i posiada pożądaną właściwość bycia ciągły w tak wielu wymiarach, jak trzeba - jeśli wykres f(x)aby f(x + 1), tam nie będzie żadnych nagłych skoków. Dzięki temu jest bardzo przydatny w wielu rzeczach, takich jak modulacja tekstury, chmury i gazy objętościowe oraz generowanie terenu.

Jeśli szukasz implementacji, z którą chcesz zacząć grać, ulepszony generator hałasu Perlina Kena Perlina jest jedną z najprostszych implementacji.


źródło
3
Zauważ, że wiele generatorów liczb losowych używa zarodka i generuje ten sam zestaw liczb, biorąc pod uwagę to samo ziarno.
thedaian
3
@thedaian: Co nie jest szczególnie przydatne w tym przypadku, chyba że chcesz zregenerować każdą liczbę; funkcja szumu pozwala uzyskać 500. liczbę bez konieczności generowania 499 wcześniej.
Biorąc pod uwagę algorytm Perlin Noise, czy można go skalibrować? Rozważ, że chcę, aby algorytm generował więcej paczek płytek ściennych, a następnie paczki płytek kosmicznych.
Mathias Lykkegaard Lorenzen
3
Nie przeczytałeś i nie zrozumiałeś linków, które podałem w ciągu sześciu minut.
1
Ta odpowiedź byłaby kompletna z postem na blogu Notcha
deceleratedcaviar
3

Sposób, w jaki Minecraft kontroluje generowanie, polega na utworzeniu poziomu zalążka, który jest wykorzystywany do generowania wszystkich liczb losowych w grze. Jeśli porcja nie istnieje na dysku, gdy zostanie o to poproszona, zostanie wygenerowana za pomocą funkcji generowania Notch opartej na ziarnie poziomu; jest on następnie zapisywany na dysku na później.

Wygląda na to, że chcesz osiągnąć podobne zachowanie, więc jest to bezpieczna droga.

Keeblebrox
źródło
2

Jak wskazał Joe, szukasz funkcji skrótu. Ogólnie, funkcje losowe są po prostu funkcjami mieszającymi zaszczepionymi ostatnią zwracaną liczbą. Więc jeśli Random()zwrócone Hash(seed)=1234, drugie połączenie Random()wróci Hash(1234), przy tak dalej.

Jeśli szukasz prostej funkcji mieszającej dla liczb pseudolosowych, sprawdź MurMurHash . Zaimplementowałem go w C # i mogę go gdzieś opublikować, jeśli jesteś zainteresowany. Bardziej szczegółowe informacje na temat szumu Perlina, który korzysta z takiej funkcji skrótu, można znaleźć tutaj , a jej implementacja w języku C # znajduje się tutaj .

Wszystkie te informacje pochodzą z pytania, które zadałem rok temu tutaj na Stack Overflow. To, czego szukasz, nazywa się generowaniem treści proceduralnych, więc jeśli potrzebujesz więcej informacji, poszukaj ich. Szczęśliwy generowanie terenu!

dlras2
źródło
-1. Hash Perlina nie przypomina w niczym technik stosowanych w MMH lub innych kryptograficznych procedurach haszujących; ten kod C # jest śmieciem, który wydaje się wykonywać liniową interpolację między wartościami losowymi; wymaga dużo więcej pamięci niż właściwy hałas Perlina i prawdopodobnie działa wolniej.
1
@Joe - Przepraszam, że tak bardzo czujesz swoją implementację Perlin Noise. Hałas Perlin sam w sobie jest pojęciem przekształcania funkcji skrótu w funkcję ciągłego hałasu. Dzięki MurMurHash bardzo skutecznie generuję dużo Perlin Noise. Jeśli chodzi o kod C #, jest to przykład, w jaki sposób programowo określić wartość pojedynczego punktu w hałasie 2D Perlina. Nigdy nie użyłbym go w produkcji, ale moim zdaniem łatwiej jest przejść niż kod, który napisałeś.
dlras2,
1
OP nie wiedział o hałasie i haszowaniu, więc po prostu starałem się przedstawić referencje w nadziei, że będą dalej badać i samodzielnie decydować, jak wdrożyć to, co trzeba.
dlras2,
„Hałas Perlin sam w sobie jest pojęciem przekształcania funkcji skrótu w funkcję ciągłego hałasu”. Nie, szum Perlina jest jedną z funkcji ciągłego szumu wymyśloną przez Kena Perlina (a nie tą, którą nazwał „szumem simpleksowym”). Nie wszystkie funkcje ciągłego hałasu są hałasem Perlina; nie wszystkie ciągłe funkcje szumowe są równomiernym hałasem gradientowym, którego szczególnym przykładem jest hałas Perlina; rzecz, z którą się łączysz, to nie hałas gradientowy, ale hałas wartościowy.
Kod w linku jest „łatwiejszy do przejścia”, ponieważ nie jest to szum Perlina; nie jest tak gładka; zużywa znacznie więcej zasobów; w skrócie, łatwiej jest przejść, ponieważ jest głupszy.