Fungsi seed acak untuk pembuatan peta?

28

Saya mencari fungsi untuk menghasilkan peta acak berbasis ubin sebagai batas visual dari perubahan peta (dengan menelusuri peta). Saya ingin peta menjadi sangat besar, dan memiliki struktur seperti labirin.

Namun, jika dunia tidak terbatas, kembali ke tempat pemain sebelumnya telah menimbulkan masalah. Permainan itu harus mengingat bagaimana sebenarnya semua yang ada di sana.

Jadi, saya berpikir - "Bagaimana cara Minecraft memecahkan masalah ini?" dan saya berpikir pada diri sendiri bahwa mereka harus menggunakan semacam fungsi bilangan acak dengan sebuah seed, yang keduanya bisa maju tetapi juga mundur, dan dengan cara itu, menghasilkan ubin lama persis seperti sebelumnya, tetapi dalam contoh baru.

Apa pendapat Anda tentang ini?

Mathias Lykkegaard Lorenzen
sumber
Bagaimana jawaban saya di +5 namun pertanyaannya hanya di +2? Ini adalah salah satu pertanyaan terbaik di halaman depan sekarang.
2
Bukankah minecraft hanya menyimpan bongkahan yang sudah Anda kunjungi / modifikasi?
FxIII
@FxIII: Minecraft harus, karena Anda dapat memodifikasi lanskap. Jika Anda tidak bisa melakukannya, menyimpan bongkahan itu mungkin merupakan pemborosan, atau paling tidak kerumitan yang berlebihan.
@ Jo Wreschnig: Baik, Baik ... Saya takut kehilangan sesuatu yang besar!
FxIII

Jawaban:

20

Apa yang Anda perhatikan adalah perbedaan antara generator angka acak dan fungsi noise . Generator nomor acak mengeluarkan nomor yang berbeda setiap kali Anda memanggilnya. Fungsi noise mengambil beberapa argumen - katakanlah, peta x dan y - dan mengeluarkan angka dengan sifat statistik seperti acak , tetapi nilai yang sama untuk argumen yang sama setiap waktu , yaitu fungsi matematika yang tepat.

Keduanya sangat terkait erat. Sebuah fungsi noise dapat mensimulasikan nomor acak generator, dengan melewati dalam nilai yang berbeda setiap kali - misalnya noise(1), noise(2)dan sebagainya. Dan generator bilangan acak, yang dibuang ke meja raksasa, dapat bertindak sebagai fungsi derau. Namun dalam kedua kasus, Anda menggunakan alat yang salah untuk pekerjaan itu.

Minecraft khususnya penggunaan Perlin noise , jenis kebisingan yang murah untuk menghitung, dan memiliki properti yang diinginkan menjadi terus menerus dalam beberapa dimensi seperti yang Anda perlu - jika Anda grafik f(x)untuk f(x + 1), tidak akan ada setiap melompat tiba-tiba. Ini membuatnya sangat berguna untuk banyak hal seperti modulasi tekstur, awan dan gas volumetrik, dan generasi medan.

Jika Anda mencari implementasi untuk mulai bermain, generator kebisingan Perlin Ken Perlin yang ditingkatkan adalah salah satu implementasi paling sederhana.


sumber
3
Perhatikan bahwa banyak generator angka acak menggunakan seed, dan akan menghasilkan set angka yang sama dengan seed yang sama.
thedaian
3
@thedaian: Yang mana tidak terlalu berguna dalam kasus ini, kecuali jika Anda ingin membuat ulang setiap nomor; fungsi noise memungkinkan Anda mendapatkan nomor 500 tanpa harus menghasilkan 499 sebelum itu.
Dengan algoritma Perlin Noise, apakah mungkin untuk mengkalibrasi itu? Pertimbangkan saya ingin algoritme lebih mungkin menghasilkan paket ubin dinding, dan kemudian paket ubin ruang.
Mathias Lykkegaard Lorenzen
3
Anda belum membaca dan memahami tautan yang saya berikan dalam enam menit.
1
Jawaban ini akan lengkap dengan posting blog Notch: notch.tumblr.com/post/3746989361/terrain-generation-part-1
deceleratedcaviar
3

Cara Minecraft mengendalikan generasinya adalah dengan membuat seed level yang digunakan untuk seed semua generasi nomor acak untuk gim. Jika sepotong tidak ada pada disk ketika diminta, itu akan dihasilkan menggunakan fungsi generasi Notch berdasarkan pada seed level; itu kemudian disimpan ke disk untuk nanti.

Sepertinya Anda ingin mencapai perilaku serupa, jadi itu cara yang aman untuk dilakukan.

Keeblebrox
sumber
2

Seperti yang ditunjukkan Joe, Anda mencari fungsi hash. Secara umum, fungsi acak hanyalah fungsi hash yang diunggulkan dengan angka yang dikembalikan terakhir. Jadi, jika Random()dikembalikan Hash(seed)=1234, panggilan kedua Random()akan kembali Hash(1234), begitu seterusnya.

Jika Anda mencari fungsi hashing sederhana untuk angka acak semu, periksa MurMurHash . Saya sudah menerapkannya di C # dan dapat mempostingnya di suatu tempat jika Anda tertarik. Informasi lebih rinci tentang Perlin Noise, yang menggunakan fungsi hash seperti itu, dapat ditemukan di sini , dan implementasinya dalam C # ada di sini .

Semua informasi ini berasal dari pertanyaan yang saya ajukan setahun yang lalu di sini di Stack Overflow. Apa yang Anda cari disebut pembuatan konten prosedural, jadi jika Anda memerlukan informasi lebih lanjut, lakukan pencarian untuk itu. Selamat menghasilkan medan!

dlras2
sumber
-1. Hash Perlin, dalam hal ini, tidak memiliki kemiripan dengan teknik yang digunakan dalam MMH atau rutinitas hashing kriptografis lainnya; bahwa kode C # adalah sampah yang tampaknya hanya melakukan interpolasi linier antara nilai acak; itu membutuhkan lebih banyak memori daripada kebisingan Perlin yang tepat dan kemungkinan berjalan lebih lambat.
1
@ Jo - Maaf, Anda merasa sangat kuat tentang implementasi Perlin Noise Anda. Perlin Noise sendiri merupakan konsep mengubah fungsi hash menjadi fungsi noise terus menerus. Saya telah menghasilkan banyak Perlin Noise dengan sangat efektif dengan MurMurHash. Adapun kode C #, ini adalah contoh bagaimana secara terprogram menentukan nilai satu titik dalam 2D ​​Perlin Noise. Saya tidak akan pernah menggunakannya dalam produksi, tetapi menurut saya, lebih mudah untuk berjalan daripada kode yang Anda posting.
dlras2
1
OP tidak memiliki pengetahuan tentang kebisingan atau hashing, jadi saya hanya berusaha memberikan referensi dengan harapan bahwa mereka akan menyelidiki lebih lanjut dan memutuskan sendiri bagaimana menerapkan apa pun yang perlu mereka lakukan.
dlras2
"Perlin Noise sendiri merupakan konsep mengubah fungsi hash menjadi fungsi noise berkelanjutan." Tidak, noise Perlin adalah salah satu fungsi noise berkelanjutan yang ditemukan oleh Ken Perlin (dan bukan yang disebutnya "noise simpleks"). Tidak semua fungsi noise kontinu adalah noise Perlin; tidak semua fungsi noise kontinu bahkan noise gradien, dimana noise Perlin adalah contoh khusus; hal yang Anda tautkan bukan gradien noise, tetapi nilai noise.
Kode di tautan Anda "lebih mudah untuk dilalui" karena itu bukan Perlin noise; tidak semulus itu; ia menggunakan sumber daya yang jauh lebih banyak; Singkatnya, lebih mudah untuk dilalui karena itu adalah dumber.