Saya bertanya-tanya apakah ada bahaya yang mungkin terjadi ketika loop game saya berjalan secepat sistem memungkinkan?
Saat ini saya memiliki loop, yang, dengan mengukur waktu yang berlalu dalam nanodetik, menjalankan logika game dan merender logika pada kecepatan yang telah ditentukan tanpa masalah. Faktanya, logika apa pun yang saya lakukan di loop adalah clock ke sejumlah panggilan setiap detik.
Loop itu sendiri meskipun hanya berjalan secepat yang suka yang muncul hingga sekitar 11,7 juta loop per detik di mesin saya.
Loop (kodesemu sederhana):
while(!isGameOver){
if(canPollInputs){
pollInputs()
}
while(canStepLogic){
stepLogic()
}
if(canRender){
render()
}
}
Pertanyaan saya pada dasarnya adalah apakah loop sederhana itu, jika tidak berjalan pada kecepatan yang terkendali, dapat membahayakan sistem?
Sunting: Itu berarti logika saya berjalan 30 kali per detik (30 tps), penyaji saya berjalan pada 60 fps, saya mengumpulkan input 100 kali per detik dan ada juga beberapa logika untuk mengatasi logika atau membuat waktu lebih lama dari yang diharapkan . Tetapi loop itu sendiri tidak dibatasi.
Sunting: Menggunakan Thread.sleep()
untuk contohnya Throttle loop utama ke 250 loop per detik mengarah ke pengurangan tetapi loop berjalan di sekitar 570 loop per detik, bukan 250 yang diinginkan (akan menambahkan kode ketika saya di mesin desktop saya ..)
Sunting: Ini dia, gameloop java yang berfungsi untuk mengklarifikasi hal-hal. Juga merasa bebas untuk menggunakannya tetapi jangan mengklaim itu milik Anda;)
private void gameLoop() {
// Time that must elapse before a new run
double timePerPoll = 1000000000l / targetPPS;
double timePerTick = 1000000000l / targetTPS;
double timePerFrame = 1000000000l / targetFPS;
int maxFrameSkip = (int) ( (1000000000l / MINIMUM_FPS) / timePerTick);
int achievedPPS = 0;
int achievedFPS = 0;
int achievedTPS = 0;
long timer = TimeUtils.getMillis();
int loops = 0;
int achievedLoops = 0;
long currTime = 0l;
long loopTime = 0l;
long accumulatorPPS = 0l;
long accumulatorTPS = 0l;
long accumulatorFPS = 0l;
long lastTime = TimeUtils.getNano();
while(!isRequestedToStop) {
currTime = TimeUtils.getNano();
loopTime = currTime - lastTime;
lastTime = currTime;
loops = 0;
accumulatorPPS += loopTime;
accumulatorTPS += loopTime;
accumulatorFPS += loopTime;
if(accumulatorPPS >= timePerPoll) {
pollInputs();
playerLogic();
achievedPPS++;
accumulatorPPS -= timePerPoll;
}
while(accumulatorTPS >= timePerTick && loops < maxFrameSkip) {
tick();
achievedTPS++;
accumulatorTPS -= timePerTick;
loops++;
}
// Max 1 render per loop so player movement stays fluent
if(accumulatorFPS >= timePerFrame) {
render();
achievedFPS++;
accumulatorFPS -= timePerFrame;
}
if(TimeUtils.getDeltaMillis(timer) > 1000) {
timer += 1000;
logger.debug(achievedTPS + " TPS, " + achievedFPS + " FPS, "
+ achievedPPS + " Polls, " + achievedLoops + " Loops");
achievedTPS = 0;
achievedFPS = 0;
achievedLoops = 0;
}
achievedLoops++;
}
}
Seperti yang Anda lihat hampir tidak ada kode yang dijalankan pada setiap loop tetapi selalu ada pilihan tertentu berdasarkan berapa banyak waktu nyata telah berlalu. Pertanyaannya mengacu pada 'lingkaran pekerja' itu dan bagaimana hal itu memengaruhi sistem.
sumber
Jawaban:
Ini akan menyebabkan satu inti CPU untuk selalu berjalan pada 100%. Ini biasanya tidak menyebabkan kerusakan pada sistem. CPU dirancang untuk beroperasi pada 100% selama berjam-jam. Tetapi pada perangkat seluler itu akan menghabiskan baterai dengan cepat dan memanaskan perangkat, yang kemungkinan akan membebani Anda dengan bintang di peringkat toko Anda. Pada komputer desktop, ini bukan masalah, tetapi akan mengkonsumsi lebih banyak listrik pengguna, menyebabkan kipas CPU berputar lebih cepat yang mungkin menyebabkan beberapa kebisingan dan buang siklus CPU yang seharusnya dapat digunakan oleh proses lain. Meskipun ini bukan cacat kritis, itu masih gaya yang buruk, jadi Anda harus menghindarinya jika memungkinkan.
Anda tidak mengatakan apa-apa tentang bagaimana loop logika game Anda bekerja secara internal, tetapi ketika Anda menggunakan pendekatan delta-waktu (setiap perhitungan yang Anda lakukan membutuhkan waktu sejak panggilan terakhir ke akun), Anda berhadapan dengan delta yang sangat kecil. nilai waktu. Ini berarti Anda dapat mengalami masalah dengan ketidaktepatan floating-point yang dapat menyebabkan semua jenis perilaku aneh. Juga, resolusi dari pengatur waktu sistem seringkali terbatas, jadi ketika loop logika Anda terlalu cepat, Anda bisa mendapatkan nilai delta-t dari nol, yang kemudian dapat menyebabkan pembagian dengan nol yang mengakibatkan crash.
Untuk mengurangi masalah ini, Anda harus membatasi framerate Anda (grafik dan logika) hingga maksimum dari apa yang dapat dilihat mata manusia. Berapa banyak yang diperdebatkan dan tergantung pada jenis animasi dan pada jenis tampilan yang ditampilkan, tetapi perkiraan berkisar dari 40 FPS hingga 120 FPS. Itu berarti Anda perlu mengatur waktu minimum eksekusi setiap loop antara 20 ms dan 8 ms. Jika pengulangan selesai lebih cepat, biarkan utas cpu
sleep
untuk sisa waktu yang tersisa.sumber
Anda membuang-buang siklus CPU. Itu berarti waktu baterai lebih rendah pada notebook, tablet dan telepon, tagihan listrik yang lebih tinggi, lebih banyak panas yang dihasilkan oleh mesin, kipas yang lebih berisik. Juga, Anda mungkin makan siklus dari proses sistem penting lainnya (misalnya server jendela bisa menjadi tersentak-sentak), yang kemudian dapat mempengaruhi gameplay. Beberapa penjadwal sistem pada sistem multitasking pre-emptive hari ini juga menghukum aplikasi yang menggunakan terlalu banyak siklus, sehingga Anda mungkin cepat terlebih dahulu, lalu tiba-tiba melihat keheranan aneh ketika Anda dicekik oleh sistem.
Banyak gamer hardcore juga membuat PC khusus dari awal yang berada di ujung spesifikasi penggemar mereka, dalam hal ini hari yang panas dan panas yang dihasilkan gim Anda dapat menyebabkan keselamatan terpicu di dalam mesin (paling-paling) atau bahkan membuat bagian terlalu panas dan mati (paling buruk). Jadi jika itu target audiens Anda, Anda mungkin ingin memastikan Anda selalu meninggalkan sedikit ruang "di atas".
Akhirnya, ada masalah gameplay di mana Anda mungkin menguntungkan pemain dengan mesin lebih cepat daripada yang lebih lambat. Memiliki loop game dibatasi pada frekuensi tertentu dan menggunakan siklus tambahan semata-mata untuk aspek yang tidak relevan dengan gameplay (seperti rendering grafik kesetiaan yang lebih tinggi, efek suara surround atau apa pun) akan membuat game Anda lebih adil.
sumber
Anda seharusnya tidak memiliki gerakan / gameplay yang gelisah
Ada dua cara untuk menerapkan logika game - terikat ke waktu nyata, atau dikaitkan dengan jumlah "putaran" / langkah pemrosesan. Jika sesuatu dalam gim Anda bergerak ke kiri, apakah gerakannya akan berbeda jika stepLogic Anda () dipanggil 100 bukannya 50 kali?
Jika kode Anda memperlakukan waktu yang telah berlalu secara eksplisit di mana-mana dan melakukannya dengan benar, maka mungkin tidak apa-apa; tetapi jika ada sesuatu dalam kode Anda yang tergantung pada jumlah 'langkah' maka Anda akan mendapatkan efek samping yang tidak diinginkan.
Pertama, kecepatan benda-benda yang harus bergerak terus-menerus akan bervariasi tidak dapat diprediksi (tergantung pada penggunaan prosesor), dan ini membuat kontrol yang sangat menjengkelkan - Anda tidak dapat membuat pukulan atau lompatan yang tepat jika tiba-tiba permainan mempercepat atau memperlambat. Bahkan untuk game tanpa 'kedutan' sama sekali, itu terlihat menjengkelkan dan gelisah jika segalanya tidak berjalan lancar.
Kedua, Anda mungkin mendapatkan masalah dengan kemampuan karakter tergantung pada kecepatan komputer - contoh klasik adalah masalah Quake lama di mana rentang lompatan maksimum secara tidak sengaja tergantung pada fps Anda.
Masalah ini dapat muncul bahkan jika Anda mencoba untuk membuat kode menjadi fps-independent, akumulasi kesalahan pembulatan sering dapat menyebabkan bug seperti itu.
sumber
Satu-satunya potensi bahaya adalah konsumsi daya Anda, jadi jangan lakukan ini pada perangkat seluler. Sebaliknya, beberapa sistem embedded menghabiskan seluruh hidup mereka dalam satu lingkaran menunggu hal-hal terjadi.
Dulu sepenuhnya normal untuk hanya membuat frame game secepat mungkin, kadang-kadang bahkan tanpa timer untuk mengimbangi gameplay untuk kecepatan CPU yang berbeda. Game balap Bullfrog, Hi-Octane adalah korban yang sangat buruk dalam hal ini, dan saya menduga inilah yang disebut oleh poster yang menyebutkan Civ2.
Saya akan menyarankan Anda untuk setidaknya memasukkan input pada setiap pass jika Anda menggunakan sistem Windows atau yang sejenis, untuk memastikan respons input yang tajam.
sumber
swap
/present
/flip
lakukan menunggu sinyal vsync, untuk mengatur loop game.