Tentang
Ini sebenarnya adalah dua pertanyaan dalam satu. Pertama-tama saya mencari cara untuk secara efisien menyimpan data ubin dalam jumlah besar. Aspek lain berkaitan dengan permintaan set data dan menampilkan ubin. Biarkan saya memberi Anda latar belakang terlebih dahulu.
Kami membuat game taipan multipemain berbasis browser menggunakan perpustakaan CraftyJS untuk merendernya ke Canvas. Di latar belakang GUI kami menjalankan Yii Framework pada PHP dan semuanya terhubung ke generator peta dan mesin gim Python acak.
Beginilah tampilan peta kasar pertama terlihat: http://i.imgur.com/khAXtl.png
Menyimpan data peta
Dunia game dihasilkan secara acak setiap kali game dimulai. Ukurannya adalah 100x100 ubin heksagonal untuk setiap pemain. Itu berarti bahwa untuk permainan tiga pemain, ada 90.000 ubin yang dibuat. Saat ini saya baru saja membuat array JavaScript tempat saya membuat peta.
Ini berfungsi dengan baik untuk rendering, tetapi untuk segala jenis interaksi dengan peta kita perlu menyimpan pemain mana yang memiliki ubin, struktur seperti apa yang dibangun di atasnya, berapa harga saat ini dan seterusnya. Pada awalnya, setidaknya untuk prototipe, kami ingin menggunakan MySQL, tetapi setelah beberapa pengujian, tidak secepat secepat yang saya inginkan. Mungkin penyimpanan objek seperti MongoDB akan lebih cocok untuk menyimpan data ubin daripada tabel SQL. Atau mungkin sesuatu yang lain?
Menampilkan peta
Masalah lain yang saya lihat adalah bergerak di sekitar peta. Saat ini saya sedang membuat entitas Crafty untuk setiap ubin meskipun itu tidak ada di viewport. Ini lambat, karena meskipun Crafty hanya membuat yang ada di viewport, Crafty menyimpan dan mungkin mengulangi semua ubin pada setiap acara render. Apa yang saya miliki saat ini adalah peta yang dibuat tergambar yang sangat lambat untuk memuat dan gagap ketika Anda bergerak, sekarang saya ingin membuatnya dimainkan.
Ide pertama saya adalah memuat subset ubin yang ditampilkan di viewport. Tetapi ketika seorang pemain akan memindahkan viewport ke area kosong, saya harus meminta server dan menunggu respon kembali, baru kemudian peta dapat di-render. Ini akan baik-baik saja dalam aplikasi asli, tetapi itu lamban dalam permainan web.
Cara untuk mendapatkan kinerja yang lancar dari peta bisa preloading subset ubin yang lebih besar ke dalam array javascript dan menggunakannya sebagai cache. Pemain akan memiliki beberapa layar "di-cache" dan ketika dia memindahkan viewport, saya akan memuat lebih banyak ubin ke "cache" JS.
Apakah saya menuju ke arah yang benar? Saya ingin mendapatkan lebih banyak informasi dari seseorang yang telah melakukan hal serupa. Saya baru dalam pengembangan game, tetapi telah melalui banyak sumber selama beberapa minggu terakhir.
sumber
Jawaban:
Gameplay
Pertama-tama saya ingin bertanya, apakah Anda benar-benar membutuhkan 10.000 ubin per pemain? Meskipun saya tidak tahu jenis permainan apa yang Anda buat, umumnya benar bahwa peta besar membuat permainan panjang. Peta terbesar di Civilization 5 adalah 10240 ubin, dan itu hanya berfungsi karena Anda tidak perlu bermain lebih dari sebagian kecil saja.
Basis Data
Anda sebaiknya tidak mencoba menjalankan game seperti ini dari basis data, Anda harus menyimpan data dalam memori aplikasi. Anda bisa menggunakan database untuk membuat cadangan game. Untuk cadangan yang lengkap, simpan serialisasi data game, dan kemudian Anda bisa menambahnya dengan menyimpan pesanan yang diberikan dan kemudian jalankan kembali jika cadangan perlu digunakan.
Penyimpanan JavaScript
Adapun klien, saya akan mengatakan Anda lebih baik menyimpan seluruh peta dimuat, setidaknya jika Anda tetap berpegang pada trilyun ubin memiliki semuanya di pohon objek yang bagus mungkin agak terlalu banyak, jadi Anda mungkin harus menyimpan data dalam format "semi-binary". String bekerja sangat baik untuk hal-hal semacam ini, secara bergantian, Anda dapat dengan aman menyimpan bilangan bulat tak bertanda hingga 53 bit dalam float 64 bit, banyak hal dalam array dan saya pikir Anda akan melihat jejak memori yang cukup sederhana.
Visualisasi JavaScript
Walaupun saya tidak akan mengatakan bahwa Anda tidak seharusnya menggunakan kanvas, Anda sebenarnya tidak membutuhkannya untuk hal-hal seperti ini. Atur semuanya sebagai sekelompok elemen img, dan ubah properti src untuk menampilkan bagian peta yang berbeda.
Pro tip
By the way, kadang-kadang lebih mudah untuk berbagi benih yang digunakan untuk menghasilkannya daripada berbagi seluruh peta.
sumber
MySQL tidak lambat. Kemungkinan besar Anda melakukan kueri naif atau memiliki indeks sub-optimal. Pendekatan NoSQL seperti MongoDB mungkin lebih cepat, mungkin juga tidak. Pola akses dan pilihan kueri Anda adalah yang paling penting di sini. Dimungkinkan untuk memberikan saran tentang cara meningkatkan kinerja, tetapi tidak tanpa melihat apa yang sudah Anda lakukan.
Ya tentu saja. Tidak banyak yang bisa ditambahkan di sini - klien meminta ubin dari server, jadi Anda hanya perlu memastikan bahwa yang Anda minta mencakup area yang lebih besar dari layar.
Tambahan:
Jika Anda kompeten dengan Python maka saya akan menyarankan Anda membuang perantara PHP. Jika Anda menjalankan game sebagai proses Python maka Anda dapat menyimpan data ubin dalam memori jauh lebih mudah dan mengurangi akses MySQL secara signifikan. Ini membantu bahwa Python adalah bahasa yang jauh lebih waras daripada PHP juga.
sumber