Bagaimana Sih Cara Kerja Gacha Sebenarnya?

Teknologi 24 Des 2018

Hai, MedForians!

Apakah anda salah satu dari budak gacha? Pasti rata-rata yang membaca postingan ini pastinya merupakan budak gacha (termasuk saya sendiri). Postingan ini akan mengajak kalian bagaimana sih sebenarnya cara kerja gacha.

Awalnya saya menulis ini karena dari penelitian proyek. Kebetulan proyek yang saya kerjakan persis mirip dengan logika gacha. Saya coba membuat sedikit sketsa tentang gacha ini dan hasilnya lumayan memuaskan.

Untuk edisi fokus kali ini, saya menggunakan bahasa JavaScript lagi. Akan tetapi, kali ini saya menggunakan Node.js sebagai frameworknya. Bagi kalian yang baru tahu tentang Node.js, kalian langsung bisa kunjungi website resminya.

Source Code

Untuk source codenya kalian dapat lihat di sini untuk versi yang kompleks. Sedangkan untuk versi yang biasa-biasa saja, kalian dapat lihat di sini.

Yang kita bahas kali ini adalah yang versi simpel atau biasa-biasa saja. Untuk versi komplek kiranya dapat menjadi bahan belajar bagi saya dan kalian semua.

Kritik dan saran sangat diterima, apabila ada bug dan transformasi kode silahkan buka kolom Issues.

Pengenalan Identitas dan Penggolongan Kartu

PERINGATAN: Penggunaan bahasa teknis dan pemograman akan lebih ditekankan di bagian ini hingga selesai.

Screenshot_2018-08-22-23-12-53-816_com.bushiroad.en_.bangdreamgbp
Contoh kartu event di game BanG Dream!

Dalam kasus ini, saya menggunakan konteks penulisan data sebagai berikut.

{
    "id": string,
    "name": string,
    "rarity": string,
    "costume": string,
    "on_event": boolean
}

Dapat kita lihat, terdapat 5 kolom yang saya gunakan. Tergantung situasi sih, kolom ini bisa saja berubah sesuai keadaan tergantung apa yang anda inginkan.

Contoh dasarnya begini, setiap siswa pasti memiliki NIS kan? Nah, dalam game itu sebenarnya yang kita panggil hanya ID aja, yang lain ngikut kalau dipanggil. Istilahnya di basis data itu Unique Key/Primary Key, yakni Key yang mustahil ada kembarannya.

“Ah, tapi banyak tuh di game si idol A punya lebih dari 3 kartu.”

“Tapi costumenya beda atau skillnya beda kan?”

Itu gunanya ID, sebagai pengenal untuk kartu dan sebagai pembeda antar satu kartu dengan kartu yang lain. Dalam post ini, saya sudah membuat contoh kartunya dan akan diterapkan dalam post ini. Bentuk datanya berbentuk JSON karena kebetulan kita menggunakan JavaScript.

Kemudian untuk kolom on_event, mengapa di situ diberikan tipe data boolean? Biasanya tiap season akan ada seperti highlight card sehingga kita dengan mudah mengganti isinya dengan true apabila kartu itu adalah highlight card, simpel kan?

Untuk contoh pengisiannya:

{
    "id": "LLSP001",
    "name": "Honoka Kousaka",
    "rarity": "R",
    "costume": "Normal",
    "on_event": false
}

Terlihat jelas, kartu dengan ID LLSP001 berisi data tentang Honoka Kousaka dengan rarity R dan costumenya masih normal dan kartunya juga bukan termasuk highlight card.

Kelangkaan Kartu dan Rumusnya

PERINGATAN: Disarankan untuk membuka kodenya, karena kita akan fokus membahas kode di sini.

Gacha ini terinspirasi oleh Loot Tables yang menggunakan metode Weighted Pseudo Number yang mana setiap berat dari data semuanya dijumlahkan untuk mendapatkan range tertentu.

Untuk rarity dari setiap kartu, dalam kasus ini saya menggunakan tetapan berikut:

unknown

Kemudian, dari tetapan tersebut saya kalikan semua menjadi 100 agar range hitungannya semakin besar dan makin kapitalis.

Untuk range dari tiap rarity, saya gunakan rumus yakni:

range_rarity = rarity_sebelumnya + rarity_sekarang

Sehingga apabila diterapkan dalam kode akan menjadi seperti ini:

R = r_rate
SR = R + sr_rate
SSR = SR + ssr_rate
EVENT = SSR + event_rate

Kemudian, sudah terang kan bagaimana ratenya? Kemudian kita cari kartunya dengan cara mengacak angka berdasarkan rentang ratenya lalu kita cocokkan angka tersebut berada di range mana. Apabila kita telah mendapatkan raritynya, acak lagi kartu yang raritynya sama dengan yang telah diacak tadi sehingga kita mendapatkan kartu yang diinginkan.

Untuk mengacak kartu, kita perlukan yang namanya pengulangan sehingga logika yang kita gunakan dapat terulang dengan output yang berbeda. Sehingga, kita juga mendapatkan output kartu yang berbeda-beda pula

Dalam versi kodenya, kira-kira seperti ini:

for (let index = 1; index <= jumlahKartu; index++) {
    // Penyimpanan output nanti
    let res;
    // Variabel untuk mengacak angka sesuai jumlah range tadi.
    let randNumber = Math.floor(Math.random() * parseFloat(range));

    // Apabila anda familiar dengan contoh IF ELSE "Nilai Siswa"
    // maka saya tak usah menjelaskan bagian ini.
    if (SSR < randNumber && randNumber <= EVENT) {
        res = whenEvent();
        getItem.push(res[reloadNumber(res.length)]);
    }
    else if (SR < randNumber && randNumber <= SSR) {
        res = whenRarity("SSR");
        getItem.push(res[reloadNumber(res.length)]);
    }
    else if (R < randNumber && randNumber <= SR) {
        res = whenRarity("SR");
        getItem.push(res[reloadNumber(res.length)]);
    }
    else if (randNumber <= R) {
        res = whenRarity("R");
        getItem.push(res[reloadNumber(res.length)]);
    }
}

Lebih jelasnya dapat dilihat di sini mulai dari baris 30 hingga 90.

Membuat Pemain Menjadi Penasaran

Biasanya ketika kita ingin roll 10x secara langsung sering terjadi developer berbaik hati sedikit memberikan garansi 1 SR ketika roll 10x. Nah, saya menggunakan variabel one_or_ten dengan tipe data boolean untuk mengetahui apakah client ingin roll 1x atau 10x. Contohnya seperti ini:

if (one_or_ten === false) {
    rollItUp(1);
}
else if (one_or_ten === true) {
    let res = whenRarity("SR");
    getItem.push(res[reloadNumber(res.length)]);
    rollItUp(9);
}

Tapi coba perhatikan, yang akan masuk duluan pertama dalam penampungan yakni SR. Sehingga atmosfer keseruan gacha agak berkurang sedikit. Maka dari itu, kita gunakan metode Fisher-Yates Shuffle yang pernah kita bahas dalam edisi fokus sebelumnya. Akan tetapi, metode yang lalu kita meggunakan FOR Loop, kali ini kita menggunakan WHILE Loop dengan alasan array yang dihasilkan masih semu.

Berikut contohnya:

let shuffledArray = [];
let stop = false;
while (stop === false) {
    if (getItem.length < 1) stop = true;
    else {
        var index = Math.floor(Math.random() * getItem.length);
        var item = getItem[index];
        getItem.splice(index, 1);
        shuffledArray.push(item);
        stop = false;
    }
}

Output yang Diharapkan

Screenshot_85
Untuk versi simpel

Screenshot_86
Untuk versi kompleks, dengan pembedaan seri dan warna.

Kesimpulan

Masih banyak metode selain ini untuk menghasilkan kartu yang berbeda dengan tingkat rarity atau tingkat kelangkaan yang berbeda juga. Akan tetapi, dari beberapa metode yang saya temukan saya rasa metode ini yang cepat masuk di kepala saya.

Tujuan utama postingan ini adalah membuka mata para pemain game bergacha bagaimana komputer mengadu domba insting keberuntungan anda.

Dan untuk MedForians yang asal usulnya bukan programmer dan takjub dengan post ini, saya katakan.

Selamat bergabung di dunia Programmer yang fana ini!

Tag

Ikramullah

Tukang review game. Hobi saya sumpah-serapah dengan teknologi baru.