Simple Diminishing Return with Cap

19

Masalah

Pemain memperoleh 5 poin per level hingga level 80 dengan maksimum 400. Ada 5 statistik untuk dibagikan dan tidak ada batas maksimum berapa banyak yang dapat Anda tambahkan ke stat.

  • Kekuatan
  • Daya tahan
  • Intelijen
  • Kelincahan
  • Keberuntungan - Memberikan peluang kritis dan kerusakan kritis

Saya ingin menerapkan persamaan pengembalian yang semakin berkurang pada katakanlah Keberuntungan. Untuk kesempatan kritis, saya tidak berharap pemain dapat mencapai peluang kritis 100%.

Akan ada langit-langit di mana ia akan mencapai sebagai pertumbuhan semakin menurun mencapai menuju 0 per poin ditambahkan.

Contoh jika peluang kritis maksimum yang saya inginkan dimiliki pemain adalah 40%, Setiap poin keberuntungan akan meningkatkan peluang kritis semakin sedikit, sampai peluang kritis mencapai sekitar 40%. Dengan mana 1 keberuntungan akan memberikan jumlah yang sangat sangat kecil.

Ada solusi? Terima kasih dan bantuan Anda sangat dihargai!

Nick
sumber
Kemungkinan rangkap dari Bagaimana mengembangkan Rumus Kerusakan RPG? - tl; dr kata kunci yang Anda cari adalah kurva sigmoid
BlueRaja - Danny Pflughoeft
@ BlueRaja Saya pikir itu bukan duplikat. Pertanyaan ini adalah tentang fungsi diminishing-return secara umum — yaitu tentang kerusakan-kalkulasi. Ketika itu terjadi, jawaban atas pertanyaan itu sebagian besar membahas fungsi pengembalian yang menurun, tetapi saya pikir pertanyaannya masih jelas berbeda.
Anko

Jawaban:

30

Anda ingin memulai dengan fungsi asimptotik. Yaitu, angka yang dimulai dari angka adan mendekati angka lainnya b, tetapi tidak pernah benar-benar mencapainya. Mungkin akan lebih mudah jika a = 0dan b = 1. Anda akan mengambil persamaan ini, memasukkan jumlah poin stat (poin Keberuntungan) yang dimiliki karakter, dan mendapatkan nilai stat aktual (Crit Chance) sebagai output.

Contoh yang sangat sederhana adalah di y = x / (x + n)mana nbeberapa konstanta positif. Di sini xadalah input Anda, tempat Anda memberi makan dalam jumlah poin stat, dan youtput Anda, di mana Anda mendapatkan nilai stat akhir.

Untuk n = 5memeriksa seperti apa tampilannya:

y = x / (x + 5) plot untuk x dalam [0,100]

Ketika Anda memberi makan, x = 0Anda mendapatkan y = 0, tetapi tidak peduli seberapa besar xAnda memasukkan, ytidak pernah mencapai 1. Sempurna.

Sekarang, Anda dapat menyesuaikan ini dengan keinginan hati Anda. Anda dapat mengalikan dengan faktor skala untuk mengatur 'batas' ke apa pun yang Anda inginkan. y = a * x / (x + 5). Jika Anda ingin batasnya menjadi 40%, kalikan dengan ,4. y = .4 * x / (x + n). Sekarang ketika Anda memberi makan x, yakan meningkat tetapi tidak akan pernah mencapai .4.

Sesuaikan nuntuk mengatur seberapa cepat atau lambat persamaan landai. n = 100akan meningkat jauh lebih lambat daripada n = 5:

y = x / (x + 100) plot untuk x dalam [0,400]

Anda bisa menyelesaikan persamaan ini karena njika Anda tahu Anda ingin nilai stat yang ingin Anda capai pada titik-titik stat angka tertentu. Katakanlah karakter harus memiliki 35% Crit Chance di 100 poin of Luck. Memecahkan .35 = .4 * 100 / (100 + n)untuk nhasil n = 14.29.

Angka-angka ini tidak harus konstanta mentah juga. Mungkin statistik lain masuk ke menghitung nilai n. Mungkin beberapa karakter memiliki angka yang berbeda nsehingga skala mereka lebih baik dalam stat 'pilihan' mereka.

Jika Anda menginginkan kurva yang bentuknya berbeda atau lebih kompleks, ada banyak contoh fungsi asimptotik yang bisa Anda gunakan juga. Saya akan meninggalkan Anda untuk menjelajahinya sesuai keinginan.

Adam
sumber
3
Kurva favorit saya adalah kurva eksponensial. Ambil saja rasio tetap dari kumpulan yang tersisa dengan setiap level.
John Dvorak
@ JanDvorak untuk kelengkapan, dapatkah Anda memberikan contoh? Ada banyak kurva eksponensial dan pembaca mungkin tidak tahu bagaimana menerapkan saran Anda dari komentar sebelumnya saja.
Adam
Ini adalah titik awal yang baik dan matematika dijelaskan dengan baik, tetapi perlu diingat Anda tidak bisa hanya memilih fungsi yang terlihat bagus; masalah ini membutuhkan pertimbangan yang cermat dan banyak penyesuaian. Misalnya, salah satu kelemahan metode ini adalah kekecewaannya terhadap spesialisasi. Jika semua lima statistik sama-sama layak, poin yang dihabiskan untuk yang paling sedikit akan menjadi yang paling berharga (dan yang paling maju paling sedikit). Bentuk ideal adalah distribusi poin yang sama, yang membuat pilihan pemain tentang cara membelanjakannya kurang menarik.
Marcks Thomas
@MarcksThomas Itu tidak menganggap sinergi antara atribut, atau kemampuan untuk secara taktis mengisolasi atribut dan "menang" dengannya. Sebagai contoh, bayangkan seorang pemanah yang luar biasa yang meningkatkan ketangkasan mereka ke titik di mana musuh mati sebelum mereka mencapai mereka: bahkan jika ketangkasan memiliki efektivitas yang semakin berkurang, taktik yang dipilih membuat atribut lainnya tidak penting. Taktik lain yang melibatkan kekuatan mungkin sama efektifnya, sehingga atribut-atributnya "bernilai sama", tetapi taktik sering berarti bahwa spesialisasi itu dominan. Jika sistem atribut Anda juga menghargai spesialisasi, gim akan menyimpang.
Yakk
Saya menyebutnya sistem "mengeluarkan batu dari tas". Nilainya P = x/(x+n)adalah probabilitas, mengingat tas dengan n batu hitam dan x batu putih, bahwa Anda mengeluarkan batu putih dari kantung buta. Salah satu pendekatan yang dapat Anda lakukan adalah membuat crits set X = keberuntungan Anda, dan N = keberuntungan mereka. Kesempatan Anda untuk kritik adalah 50% jika Anda memiliki keberuntungan yang sama dengan musuh Anda. Jika Anda ingin peluang dasar menjadi 10%, maka kami X = keberuntungan Anda, N = 9x keberuntungan mereka.
Yakk
10

Basis yang baik akan menjadi fungsi seperti arctan, karena melewati asal dan menunjukkan asimtot horisontal.

Arktan

Skala oleh 40 / (pi/2), atau 80/piuntuk batas yang Anda inginkan. Kemudian ubah luckuntuk mendapatkan kurva kecuraman yang Anda inginkan.

critical = 80/pi * arctan(f(luck))
jmegaffin
sumber
8

Saya sangat suka cara game Souls mengatasi masalah ini. Alih-alih membuat setiap stat memberikan bonus berdasarkan fungsi kontinu seperti yang disarankan, ini memberikan bonus dalam fungsi linier satu demi satu.

Saya tidak dapat mengingat angka pastinya dari atas kepala saya, tetapi fungsinya ada di sepanjang baris berikut ini (setiap stat memiliki konstanta sendiri)

{0 <= x <20: y = 4x, 20 <= x <30: y = 3x + 20, 30 <= x <40: y = 2x + 50, 40 <= x <60: y = 1x + 90 , 60 <= x: y = 0.5x + 120}

Merencanakan

Metode ini memberikan banyak manfaat bagi perancang dan pemain. Perancang mendapat manfaat karena Anda dapat menyetel manfaat tepat per poin dalam suatu keterampilan yang cukup sepele, dan pemain mendapat manfaat karena mereka tahu persis berapa banyak manfaat yang akan mereka lihat dari level ke level.

Dalam kasus fungsi kontinu, beberapa level mungkin memberikan manfaat yang tidak tercermin dalam angka karena pengukuran alias. Yakin bahwa level terakhir memberi Anda peningkatan 0,9 dalam bonus XYZ, tetapi karena nilai aktual berubah dari 23,52 menjadi 24,42, dan Anda membulatkan angka sebelum menampilkannya, pemain tidak menyadari bahwa ada sesuatu yang berubah.

Dari perspektif UX, saya pasti akan menyarankan pergi dengan fungsi linear piecewise. Namun, menggunakan fungsi kontinu dapat lebih mudah untuk dilakukan di kemudian hari, karena pemain tidak akan terikat pada konstanta bulat.

Kaslai
sumber
1
Perkiraan kurva yang tidak membutuhkan banyak matematika, dan mudah diubah. Saya suka itu. :)
Casey Kuball
> Anda putaran nomor sebelum menampilkan itu => salah satu cara kompensasi adalah untuk ceilyang jumlah kenaikan sebelum menambahkan, dan hanya memungkinkan bilangan bulat tingkat stat. atau floorkemudian x <= 0: x = 1untuk menghindari secara tidak sengaja melewati tutup lunak.
Bob
1
Meskipun Anda masih bisa melakukan fungsi sambungan, itu tidak memiliki efek yang Anda cari di sini. Nilai keberuntungan adalah persentase, dengan maksimal 400 peringkat. Ini berarti setiap titik penilaian harus menghasilkan keuntungan sub-1% dalam nilai, bahkan dalam fungsi linier dengan 100% keberuntungan. Caranya hanya menunjukkan titik desimal yang cukup sehingga y (399) berbeda dari y (400). Fungsi Anda melakukan hal yang sama dengan membuat Anda tumbuh sangat besar sehingga peningkatan selalu menjadi bagian integral. Pada x = 40, y lebih dari 4 kali nilai x.
MichaelS
@MichaelS Saya baru saja memberikan contoh jenis fungsi yang digunakan dalam Dark Souls. Ini perlu diseimbangkan secara berbeda tergantung pada situasi yang diterapkan, tetapi poin saya tetap bahwa pemain akan memahami efek fungsi linear piecewise jauh lebih mudah daripada kurva arctangent atau bagian kerucut.
Kaslai
3

Jan Dvorak menunjukkan fungsi eksponensial dalam komentar. Saya akan jelaskan di sini.

Perhatikan bahwa operasi eksponensial (dan trigonometri) jauh lebih mahal secara komputasi daripada operasi akar kuadrat, yang itu sendiri jauh lebih buruk daripada matematika dasar, jadi Anda mungkin lebih baik dengan pendekatan Adam jika Anda akan melakukan perhitungan ini berkali-kali per detik . Jika Anda hanya menghitung nilai saat level pemain, mengganti peralatan, dll., Kecepatan tidak penting, jadi gunakan apa pun yang memberi Anda kurva terbaik.

Fungsi eksponensial adalah beberapa dasar, B , untuk beberapa kekuatan, x , y=B^x. Matematikawan biasanya menggunakan basis e , (~ = 2.718), tetapi tidak ada alasan Anda tidak dapat menggunakan 2 atau 10 jika Anda mau.

y=e^x terlihat seperti ini: y = e ^ x

Perhatikan sisi kiri bergerak secara asimpot ke 0. Jadi kita dapat membalik sumbu x dengan melakukan y=e^(-x) , tetapi masih turun dari 1 ke 0 dan kami ingin naik. Jadi kita bisa membalikkan sumbu y dengan y=-e^(-x) . Sekarang naik dari -1 ke 0. Kita bisa menambahkan 1 untuk mendapatkan y=1- e^(-x) dan naik dari 0 ke 1.

y = 1-e ^ (- x)

Dari sini, itu hanya masalah penskalaan secara vertikal dan horizontal. Kita dapat mengalikan semuanya dengan beberapa nilai, sebut saja A , yang menetapkan batas asimptotik. Kemudian kita dapat mengalikan x dengan nilai laju perubahan, k , untuk menyesuaikan seberapa cepat itu mendekati batas.

Ini memberi kita persamaan akhir dari y=A*(1 - e^(-k*x)). Dengan menggunakan nilai k=0.012dan A=0.5, kita dapat menetapkan batas menjadi 50% dan membiarkannya mendekati batas sekitar itu x=400.

y = 0,5 * (1-e ^ (- 0,012 * k))

Sekarang, Anda dapat membuat beberapa penyesuaian untuk ini. Satu tweak yang saya buat berubah menjadi A=0.5041, jadi jika kita membulatkan persentase dengan 2 desimal (seperti 32,23%), y (399) = 49,99% dan y (400) = 50,00%. Dari y (347) dan seterusnya, ada beberapa tempat di mana dibutuhkan dua poin untuk mendapatkan perubahan 0,01%. Tetapi poin terakhir yang mungkin masih memberikan (hampir) manfaat nyata, dan membawanya ke bahkan 50%.

Sebagai alternatif, kita dapat mengubah knilai untuk memiliki efek yang serupa. Pada k=0.02305, putaran nilainya menjadi 49,99% pada y=399dan 50,00% pada y=400. Namun, ini memiliki masalah bahwa grafiknya sangat dangkal di akhir - dibutuhkan 48 poin untuk mendapatkan seperseratus persen terakhir (dari y(352)=49.99%ke y(399)=49.99%ke y(400)=50.00%) dan peluang krit 1% terakhir membutuhkan 230 poin (dari y(170)=49.01%ke y(400)=50.00%) yang mungkin agak terlalu berkurang pada pengembalian.

Jika Anda mau, Anda bisa menyesuaikan A dan k sehingga berkurang ke batas yang agak lebih tinggi pada laju yang lebih lambat, untuk memberikan sesuatu antara peluruhan linier dan eksponensial. Melakukan y=0.6*(1-e^(-0.00447*x)), Anda berakhir dengan ini: y = 0,6 * (1-e ^ (- 0,00447 * x))

Perhatikan bahwa kurva terus melewati 50%, tetapi karena ada batas keras peringkat 400, pemain tidak bisa melewati titik itu (dan jika mereka berhasil melewatinya, masih ada batas keras 60% krit). Dengan persamaan ini, Anda dapat menggunakan 1 tempat desimal dan masih melihat keuntungan setiap 2 hingga 3 poin, dengan centang terakhir dari y(399)=49.9%hingga y(400)=50.0%.

Secara matematis, persamaan sebelumnya mungkin tampak lebih baik, karena mereka sebenarnya mendekati 50%, tetapi saya pribadi berpikir kenaikan 0,1% setiap pasangan poin terasa lebih baik daripada kenaikan 0,01%. Bahkan dengan A=0.05041dan k=0.012, dibutuhkan 102 poin untuk beralih dari y(298)=49.00%menjadi y(400)=50.00%. 25% dari poin Anda menghabiskan 2% dari kritik Anda mungkin terlalu berkurang. Persamaan 60% hanya membutuhkan 20 poin untuk persen terakhir (yang masih 5 kali lebih tinggi dari 4 poin yang dibutuhkan untuk persen pertama).

Dengan beberapa persamaan terakhir ini, saya hanya menyambungkan persamaan ke dalam spreadsheet dan nilai tweak secara manual hingga terlihat bagus. Anda harus melakukan hal serupa jika menginginkan topi yang berbeda.

Michael
sumber
2
Catatan tentang kecepatan relatif operasi matematika sudah benar, tetapi mungkin tidak relevan untuk statistik pemain. Kemacetan dalam permainan modern biasanya adalah hal-hal yang menangani ribuan item per frame (mis. Fisika & rendering). Skrip gameplay yang mungkin dijalankan beberapa puluh kali per frame tidak mungkin menjadi blip relatif untuk ini, dan umumnya penuh dengan cache cache yang akan meninggalkan CPU banyak waktu jempol untuk melakukan matematika yang Anda suka. tl; dr: Jangan merasa tertekan untuk menghindari operasi mahal kecuali Anda sedang menulis shader atau hal-hal lain yang perlu dijalankan dalam jumlah besar
DMGregory
-1

Untuk solusi yang sangat sederhana, bagaimana dengan root kuadrat x 2

Akar kuadrat dari 400 (maksimum yang mungkin) adalah 20, 20 * 2 = 40.

Catwood
sumber
Mengapa memilih bawah? Ini memecahkan pertanyaan yang diajukan dan sederhana yang juga diminta.
Catwood
1
Saya bukan downvoter, tapi itu mungkin karena jawaban Anda terlalu spesifik dan tidak memberikan informasi apa pun yang belum disediakan (akar kuadrat hanya eksponensial dengan kekuatan 1/2) dan Anda tidak menjelaskan alasan mengapa ini bisa bermanfaat.
Kaslai
Saya tidak downvote, tapi saya rasa ini bukan jawaban yang bagus karena tidak terlalu fleksibel - root-persegi tidak asimptotik, jadi jika level max berubah, Anda perlu mengubah formula untuk menjaga agar max stat yang sama.
BlueRaja - Danny Pflughoeft