Waktu pemuatan sebelum game vs. dalam waktu pemuatan game

9

Saya sedang mengembangkan game di mana labirin acak disertakan.
Ada beberapa makhluk AI, mengintai labirin. Dan saya ingin mereka pergi di beberapa jalur sesuai dengan bentuk labirin.

Sekarang ada dua kemungkinan bagi saya untuk mengimplementasikan itu, cara pertama (yang saya gunakan) adalah dengan menghitung beberapa jalur yang diinginkan bersembunyi setelah labirin dibuat.
Yang kedua, adalah dengan menghitung jalur yang perlu dihitung, ketika makhluk mulai mengintai itu.

Perhatian utama saya adalah waktu pemuatan. Jika saya menghitung banyak jalur saat membuat labirin, waktu pemuatan pra agak lama, jadi saya berpikir untuk menghitungnya saat diperlukan.
Saat ini gim ini tidak 'berat' sehingga menghitung jalur di pertengahan gim tidak terlihat, tapi saya khawatir itu akan menjadi lebih rumit.

Setiap saran, komentar, opini, akan sangat membantu.

Edit:

Seperti untuk saat ini, mari pmenjadi jumlah jalur yang dihitung sebelumnya, seekor makhluk memiliki kemungkinan 1/puntuk mengambil jalur baru (yang berarti perhitungan jalur) alih-alih jalur yang ada.
Makhluk tidak memulai patrolinya sampai jalannya dihitung sepenuhnya tentu saja, jadi tidak perlu khawatir tentang dia terbunuh dalam proses.

Penjaga
sumber
8
Pada titik ini, itu akan menjadi pra-optimalisasi. Saya akan membiarkannya apa adanya sampai ada masalah.
John McDonald
3
Dan untuk berbincang sedikit dengan @JohnMcDonald, jika Anda dapat menghitung jalur ini di tengah permainan dan itu tidak terlihat, berapa banyak faktor yang berkontribusi pada waktu buka?
James

Jawaban:

6

BerickCook telah mengungkapkan gagasan itu dengan benar. Tinggalkan perhitungan di mana mereka berada jika mereka bekerja dengan baik sekarang.

Jika Anda dapat melakukan perhitungan sebelumnya dan Anda yakin tidak akan membutuhkannya di tengah permainan, maka lakukanlah sebelumnya. Lain lakukan setelah memuat. Jika perhitungan selama pertandingan tidak terlalu mencolok, Anda bisa melakukannya di sana. Jika pada suatu titik kompleksitas berkembang dan perhitungan menjadi terlalu berat, mulailah mengoptimalkan.

Tetapi satu hal: jika perhitungan Anda diterapkan untuk menjalankan mid game, Anda selalu dapat memaksanya untuk dilakukan selama memuat.

Ada banyak solusi:

  • menghitung / memuat jalur selama pembuatan / pemuatan level
  • gunakan utas kedua untuk menghitung jalur
  • optimalkan algoritma Anda
  • gunakan sistem interruptible jika Anda tidak memiliki akses ke threading.

Saya telah melihat dan menggunakan opsi terakhir dalam permainan pasar massal. Cukup pastikan Anda menyimpan dengan benar semua data yang diperlukan untuk melanjutkan perhitungan, dan memeriksa secara teratur untuk sisa waktu / operasi selama perhitungan.

Tergantung pada kasus Anda, sistem interruptible dapat memberikan solusi awal dan parsial yang dapat digunakan acara sebelum perhitungan berakhir.


Edit : menjawab @Keeper

"Algoritma interruptible" hanya berguna karena kendala yang kami miliki. Pada dasarnya kami merenungkan kurangnya multithreading.

Pada satu titik kami memiliki permainan di mana AI harus menghitung sejumlah besar langkah berdasarkan beberapa kamus. Selama perhitungan ini semua animasi akan berhenti karena kamus diperluas dengan lebih banyak data dan dataset yang menyimpan data diubah dan kurang efisien ketika permainan diadaptasi untuk multipemain (di mana AI harus berinteraksi bahkan untuk pergerakan pemain). Kami hanya memiliki satu utas yang tersedia untuk loop game (yang penting adalah kode multi-platform harus dijalankan pada semua platform yang didukung). Pada titik ini diputuskan untuk memutus algoritma perhitungan sehingga kami dapat menginterupsinya. Oleh karena itu kami tidak bisa hanya menggunakan sistem rekursif yang ada karena variabel tidak dapat disimpan. Fungsi diganti dengan objek yang hanya menampung semua variabel dan pointer yang diperlukan untuk objek induk dan anak. Saya tidak

  • menyimpan status perhitungannya saat ini
  • interupsi baik pada akhir loop atau selama loop (ketika objek anak menyela)
  • keluar saat waktu habis
  • melanjutkan di mana ia berhenti memulai kembali loop di indeks yang tepat atau memanggil objek anak yang saat ini berada di atas tumpukan anak-anaknya.
  • bersihkan semuanya jika komputasinya terganggu
  • memberikan hasil parsial terbaik.

Hanya operasi yang paling mahal dipecah menjadi objek yang terpisah dan butuh beberapa waktu untuk menemukan tempat yang tepat di mana kita bisa menghentikan perhitungan, tetapi pada akhirnya itu bekerja dengan sangat baik.

Kami kehilangan kinerja, tetapi kinerja yang dirasakan jauh lebih baik bagi pengguna karena animasi berjalan lancar di semua platform, semua platform kemudian dapat menggunakan kamus yang lebih besar tanpa menderita animasi berombak atau macet. Juga ini memungkinkan kami untuk menjalankan beberapa instance secara paralel ketika kami membutuhkannya nanti.

Tentu saja sekarang di iPhone dan iPad gim tidak membutuhkan ini, menggunakan utas kedua akan ideal. Tapi saya curiga kodenya masih ada.

Anjing hutan
sumber
Terima kasih, kedengarannya sangat menarik. Bisakah Anda menjelaskan tentang konsep "sistem interruptible" (mengapa dan bagaimana). (Googling tidak begitu membantu ..). Saya akan menambahkan beberapa detail ke pertanyaan.
Penjaga
@ Keeper Saya harap saya menjawab pertanyaan Anda tentang bagian interruptible. Ini menyebalkan tetapi harus dilakukan dan itu tidak relevan pada kebanyakan sistem modern.
Coyote
Meskipun saya tidak akan menggunakan metode ini untuk saat ini, Anda membuka mata saya untuk sesuatu yang baru. Jawaban Anda layak diterima.
Penjaga
8

Untuk saat ini, karena menghitung jalur tengah permainan tidak terlalu mencolok, itulah pendekatan yang ideal. Jika / ketika sampai ke titik di mana gameplay terganggu oleh perhitungan, maka alihkan untuk menghitung setiap lintasan sebelum level dimuat.

Waktu pemuatan awal yang lebih lama dapat dimaafkan, tetapi fluktuasi FPS acak selama bermain biasanya tidak.

BerickCook
sumber
2

Satu kemungkinan jika Anda membutuhkannya adalah memindahkan perhitungan ke utas kedua karena hampir setiap PC memiliki lebih dari satu inti CPU saat ini.

Proses dasarnya adalah:

  • Saat makhluk meminta jalur, tambahkan permintaan ke antrian permintaan safe thread dan beri tanda utas.
  • Makhluk berdiri diam sambil menunggu utas untuk menghapus entri dari antrian itu, memprosesnya, dan menaruhnya di daftar yang lengkap.
  • Setiap frame memeriksa daftar yang sudah selesai dari utas utama dan menetapkan jalur yang telah selesai untuk makhluk.

Anda juga harus berhati-hati dengan beberapa kasus tepi tambahan (mis., Bagaimana jika makhluk itu mati sebelum permintaan diproses).

Adam
sumber
2
Jika Anda tidak ingin memperkenalkan threading, Anda juga dapat menghitung jalur Anda secara bertahap (mis. Menghitung beberapa langkah setiap frame).
bummzack