Bagaimana saya harus memeriksa apakah seorang pemain telah menyelesaikan suatu pencapaian?


13

Saya membuat game MMO dan saya baru saja sampai pada titik di mana saya perlu mengimplementasikan pencapaian ... Bagaimana saya melakukannya? Hal paling lurus ke depan yang harus dilakukan adalah menjalankan ini setiap 100ms ,:

for a in achievements
    for p in players
        if a.meetsRequirements(p) then p.completeAchievement(a)

Tapi itu hanya menimbulkan lebih banyak komplikasi. Misalnya, bagaimana saya memeriksa apakah pencapaiannya telah benar-benar selesai? Apakah para pemain memiliki properti khusus hanya untuk pencapaian tertentu? Saya melakukan hal semacam ini dengan pencarian, karena mereka terutama "mengumpulkan 100 kayu", jadi pencarian aktif pada pemain memeriksa itu. Juga, harus ada waktu yang lebih baik untuk memeriksanya, saya pikir ini akan memperlambat server saya secara berkala.


7
Mengapa tidak menjalankan pemeriksaan terkait saja saat tindakan dilakukan? Yaitu jika pengguna mengumpulkan kayu, lihat apakah mereka cocok dengan spesifikasi "kumpulkan 100 kayu".
Mike Cluck

1
Tampaknya agak berantakan ... Akan ada banyak cek di mana-mana. Saya pikir saya akan tetap berpegang pada algoritma di atas karena kesederhanaannya ...
jcora

10
Ada beberapa cara untuk membuatnya tidak berantakan: seperti memiliki pengendali event "OnChange" lalu menempelkan "objek" prestasi ke situ dan menangani logika di sana. Juga pahami bahwa dengan pengaturan Anda saat ini, Anda memiliki tingkat kerumitan O (n ^ 2) yang berarti permainan Anda menjadi lebih lambat lebih cepat dengan lebih banyak karakter. Jenis masalah untuk MMO
Mike Cluck

Jawaban:


23

Apa yang Anda lakukan tergantung pada sifat pencapaian. Kecuali jika semua pencapaian Anda sesuai dengan pola sederhana (kumpulkan X jumlah Ys), Anda harus membuat case-case tertentu sampai tingkat tertentu.

Menggunakan sistem komunikasi berbasis pesan, Anda dapat memberikan kait yang membuat pengkodean kasus khusus dilokalkan. Anda dapat memiliki tindakan tertentu untuk mengirimkan pesan kepada pendengar yang mendaftar sendiri. Kemudian kode / skrip prestasi Anda hanya dapat mendaftarkan diri dengan pendengar yang tepat dan melakukan pengujian apa pun yang diperlukan untuk melepaskan prestasi.

Anda akan memiliki pesan untuk acara-acara biasa yang mungkin ingin Anda dengarkan. Hal-hal seperti "pemain telah memperoleh item X" atau "entitas Y yang membunuh entitas Z". Dengan cara ini, Anda dapat melacak hal-hal seperti berapa banyak Z yang telah terbunuh oleh pemain.

Itu mungkin yang terbaik yang dapat Anda lakukan untuk sistem pencapaian. Ini memusatkan kode sebanyak mungkin, dan menempatkan tanggung jawab pada pendengar untuk deteksi pencapaian yang sebenarnya.

Juga, harus dicatat bahwa, untuk sistem pencapaian terpusat (Live X-Box, prestasi Steam), kemajuan menuju pencapaian biasanya disimpan di server. Jadi untuk akumulasi pencapaian ("lakukan tugas XY beberapa kali"), skrip pencapaian hanya mendeteksi ketika X telah dilakukan dan menabrak jumlah server. Untuk jenis pencapaian lainnya ("melakukan tugas X"), pencapaian server adalah biner: apakah Anda telah melakukannya, atau belum.


+1 Ini adalah informasi yang bagus. Bahkan berguna tanpa saya perlu menerapkan prestasi saat ini.
Joshua Hedges

Terima kasih! Tidak sabar untuk mengimplementasikan ini, saya berharap saya punya ide ini sebelumnya ...
jcora

3

Bergantung pada sifat pencapaian Anda, Anda juga dapat memperkenalkan semacam "prestasi penanda".

Misalnya, jika Anda memiliki 3 pencapaian berturut-turut:
Kayu 1 - Kumpulkan 100 kayu
Kayu 2 - Kumpulkan 500 kayu
Kayu 3 - Kumpulkan 1k kayu

Maka masuk akal untuk hanya mendaftarkan acara OnChange untuk pencapaian pertama sampai pemain menyelesaikannya. Setelah selesai, Anda dapat mendaftarkan objek pencapaian berikutnya.

Ini tentu saja memerlukan desain (atau perhitungan) pohon ketergantungan prestasi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.