Sudahkah Anda membaca The Chronicles of Amber oleh Roger Zelazny?
Bayangkan diri Anda bermain di game MMO orang ketiga. Anda muncul di dunia dan mulai berkeliaran. Setelah beberapa waktu, ketika Anda berpikir, bahwa Anda telah mempelajari peta, Anda menyadari, bahwa Anda berada di suatu tempat, yang belum pernah Anda lihat sebelumnya. Anda kembali ke tempat terakhir yang Anda yakin tahu dan masih ada di sana. Tetapi seluruh dunia telah berubah dan Anda bahkan tidak memperhatikan bagaimana itu terjadi.
Saya sudah membaca tentang generasi dunia prosedural. Saya telah membaca tentang Perlin noise dan oktaf, Simplex noise, algoritma Diamond-square, tentang simulasi lempeng tektonik dan erosi air. Saya percaya saya memiliki pemahaman yang kabur tentang pendekatan umum dalam generasi dunia prosedural.
Dan dengan pengetahuan ini saya tidak tahu bagaimana Anda bisa melakukan sesuatu seperti yang ditulis di atas. Setiap gagasan yang muncul di benak saya menemui beberapa masalah teoretis. Berikut adalah beberapa ide yang dapat saya pikirkan:
1) Generasi dunia "reversibel" dengan sejumlah seed sebagai input dan beberapa menggambarkan-a-chunk-number
Saya ragu bahwa itu bahkan mungkin, tetapi saya membayangkan sebuah fungsi, yang akan menerima sebuah seed dan menghasilkan matriks angka, yang di atasnya potongan dibangun. Dan untuk setiap nomor unik ada potongan unik. Dan fungsi kedua, yang mendapatkan nomor chunk yang unik ini dan menghasilkan seed, yang berisi angka ini. Saya sudah mencoba membuat skema pada gambar di bawah ini:
2) Membuat potongan sepenuhnya acak dan membuat transisi di antara mereka.
Seperti yang disarankan Aracthor . Manfaat dari pendekatan ini adalah memungkinkan dan tidak memerlukan fungsi sihir :)
Kontra pendekatan ini menurut saya, adalah bahwa kemungkinan tidak mungkin untuk memiliki dunia yang beragam. Jika Anda katakan saja kepulauan dan benua yang diwakili oleh hanya satu angka dan bongkahan yang berdekatan, maka ukuran bongkahannya tidak akan sama dengan benua. Dan saya ragu bahwa adalah mungkin untuk melakukan transisi yang cantik antara potongan-potongan. Apakah saya melewatkan sesuatu?
Jadi, dengan kata lain, Anda sedang mengembangkan MMO dengan dunia yang dihasilkan secara prosedural. Tetapi alih-alih memiliki satu dunia, Anda memiliki banyak dunia . Pendekatan apa yang akan Anda ambil untuk menghasilkan dunia dan bagaimana Anda menerapkan transisi pemain dari satu dunia ke dunia lain tanpa pemain memperhatikan transisi.
Ngomong-ngomong, saya yakin Anda punya ide umum. Bagaimana Anda akan melakukannya?
sumber
Jawaban:
Gunakan irisan tingkat tinggi. Jika Anda menggunakan noise 2d untuk peta ketinggian sebelumnya, gunakan noise 3D dengan koordinat terakhir yang diperbaiki. Sekarang Anda dapat perlahan mengubah posisi di dimensi terakhir untuk memodifikasi medan. Karena noise Perlin kontinu dalam semua dimensi, Anda akan mendapatkan transisi yang lancar selama Anda dengan lancar mengubah posisi tempat Anda mencicipi fungsi noise.
Jika Anda hanya ingin mengubah medan yang jauh dari jarak ke pemain seperti offset misalnya. Anda juga bisa menyimpan offset untuk setiap koordinat di peta dan hanya menambah tetapi tidak pernah menguranginya. Dengan cara ini peta hanya menjadi lebih baru tetapi tidak pernah lebih tua.
Gagasan ini juga berfungsi jika Anda sudah menggunakan noise 3D, cukup sampel dari 4D lalu. Juga, lihatlah kebisingan Simplex. Ini adalah versi peningkatan kebisingan Perlin dan berfungsi lebih baik untuk dimensi yang lebih banyak.
sumber
Ide Anda untuk membagi dunia menjadi beberapa bidak tidak buruk. Itu tidak lengkap.
Satu-satunya masalah adalah persimpangan antara potongan. Misalnya, jika Anda menggunakan perlin noise untuk menghasilkan bantuan, dan seed berbeda untuk setiap chunk, dan risiko ini terjadi:
Sebuah solusi akan menghasilkan bantuan potongan tidak hanya dari benih kebisingan Perlin, tetapi juga dari potongan lain di sekitarnya.
Algoritma Perlin menggunakan nilai peta acak di sekitarnya untuk "memuluskan" diri mereka sendiri. Jika mereka menggunakan peta umum, akan dihaluskan bersama.
Satu-satunya masalah adalah jika Anda mengubah biji chunk untuk membuatnya berbeda ketika pemain surut, Anda harus memuat ulang bongkahan juga, karena perbatasan mereka juga harus berubah.
Ini tidak akan mengubah ukuran bongkahan, tetapi itu akan meningkatkan jarak minimal dari pemain menjadi bongkar / muat, karena bongkahan harus dimuat ketika pemain melihatnya, dan, dengan metode ini, bongkahan yang berdekatan harus terlalu .
MEMPERBARUI:
Jika setiap potongan dunia Anda memiliki tipe yang berbeda, masalahnya akan tumbuh. Ini bukan hanya tentang kelegaan. Solusi mahal adalah sebagai berikut:
Anggaplah bongkahan hijau adalah dunia hutan, kepulauan yang biru dan gurun yang datar.
Solusinya di sini adalah untuk menciptakan zona "transisi", di mana relief dan sifat dasar Anda (serta objek yang di-ground-kan, atau apa pun yang Anda inginkan) akan semakin beralih dari satu jenis ke jenis lainnya.
Dan seperti yang Anda lihat pada gambar ini, bagian kode yang akan menjadi kotak kecil di sudut-sudut chunk: mereka harus membuat tautan antara 4 potongan, berpotensi sifat berbeda.
Jadi untuk tingkat kompleksitas ini, saya pikir generasi dunia 2D klasik seperti Perlin2D tidak dapat digunakan. Saya merujuk Anda ke jawaban @danijar untuk itu.
sumber
Meskipun ide danijar cukup solid, Anda bisa menyimpan banyak data, jika Anda ingin memiliki area lokal yang sama dan perubahan jarak. Dan meminta semakin banyak irisan kebisingan yang semakin kompleks. Anda bisa mendapatkan semua ini dengan mode 2d yang lebih standar.
Saya mengembangkan sebuah algoritma untuk secara prosedural menghasilkan noise fraktal acak, sebagian berdasarkan pada algoritma square diamond yang saya tetapkan untuk menjadi tak terbatas, dan juga deterministik. Jadi diamond-square dapat membuat lansekap tak terbatas, serta algoritma saya sendiri yang agak gumpal.
Idenya pada dasarnya sama. Tetapi, alih-alih mengambil sampel derau dimensi yang lebih tinggi, Anda dapat mengulangi nilai pada tingkat berulang yang berbeda.
Jadi, Anda masih menyimpan nilai yang Anda minta sebelumnya, dan menyimpannya (skema ini secara mandiri dapat digunakan untuk mempercepat algoritma yang sudah super cepat). Dan ketika area baru diminta, itu dibuat dengan nilai y baru. dan area apa pun yang tidak diminta dalam permintaan itu dihapus.
Jadi, alih-alih menjelajahi ruang yang berbeda dalam dimensi tambahan. Kami menyimpan sedikit data monotonik untuk dicampur dalam jumlah yang berbeda (dengan jumlah yang semakin besar pada tingkat yang berbeda).
Jika pengguna bergerak ke suatu arah, nilai-nilai dipindahkan sesuai (dan di setiap tingkat) dan nilai-nilai baru dihasilkan di tepi yang baru. Jika benih iteratif teratas diubah, seluruh dunia akan berubah secara drastis. Jika iterasi akhir diberikan hasil yang berbeda, maka jumlah perubahan akan sangat kecil + -1 blok atau lebih. Tapi, bukit akan tetap ada di sana dan lembah dll, tetapi celah dan celah akan berubah. Kecuali Anda melangkah cukup jauh, maka bukit itu akan hilang.
Jadi jika kita menyimpan 100x100 potongan nilai setiap iterasi. Maka tidak ada yang bisa berubah pada 100x100 dari pemain. Tapi, pada 200x200 hal bisa berubah 1 blok. Pada 400x400, berbagai hal dapat berubah sebanyak 2 blok. Pada 800x800 hal-hal akan dapat berubah sebanyak 4 blok. Jadi segalanya akan berubah dan mereka akan berubah semakin banyak semakin jauh Anda melangkah. Jika Anda kembali mereka akan berbeda, jika Anda pergi terlalu jauh mereka akan benar-benar berubah dan benar-benar hilang karena semua benih akan ditinggalkan.
Menambahkan dimensi yang berbeda untuk memberikan efek stabilisasi ini, tentu saja akan berhasil, menggeser y dari kejauhan, tetapi Anda akan menyimpan banyak data untuk banyak blok besar ketika Anda tidak harus melakukannya. Dalam algoritme fraktal noise deterministik Anda bisa mendapatkan efek yang sama dengan menambahkan nilai yang berubah (pada jumlah yang berbeda) ketika posisi bergerak melampaui titik tertentu.
https://jsfiddle.net/rkdzau7o/
sumber