Web game untuk mahasiswa logistik. Empat level soal dimainkan dengan nyawa dan batas waktu, lengkap dengan leaderboard dan panel admin untuk dosen.
Materi logistik seperti pemilihan moda transportasi, Vehicle Running Cost, Gravity Location Model, dan penentuan rute distribusi biasanya diajarkan lewat soal hitungan. Mahasiswa mengerjakan di kertas, dikumpulkan, lalu dikoreksi. Politeknik Negeri Batam ingin materi yang sama dijalankan dengan cara lain: dimainkan, ada batas waktu, dan ada konsekuensi kalau salah.
Versi pertama game ini dibuat dengan PHP native. Masalahnya, menambah level baru berarti menyalin banyak kode, dan dosen tidak punya cara untuk memantau atau mengatur jalannya permainan selain membuka database. Saya membangun ulang seluruh aplikasinya di Laravel dan menambahkan sisi admin yang sebelumnya tidak ada.
Pemain masuk dengan NIM, lalu mendarat di career map berupa ilustrasi jalan dengan empat pin level. Pin berikutnya terbuka setelah level sebelumnya dimainkan. Setiap level punya layar briefing berisi narasi kasus, lalu masuk ke soal dengan jumlah nyawa dan timer yang berjalan. Salah jawab memotong nyawa, nyawa habis berarti selesai dengan skor seadanya. Setiap kali main tersimpan sebagai baris skor, jadi dosen bisa melihat riwayat lengkap, bukan hanya nilai akhir.
Di sisi dosen ada panel admin: statistik penyelesaian per level, monitor standings yang berjalan saat lomba, tabel skor per mahasiswa, manajemen akun, dan dua saklar penting yaitu mode permainan dan kunci website.
Yang paling menyita waktu justru bukan gameplay-nya, tapi memastikan skornya tidak bisa diakali. Semua kunci jawaban saya taruh sebagai properti protected di komponen Livewire, jadi tidak pernah ikut terkirim ke browser. Front-end hanya mengirim pilihan pemain ke method seperti attemptMatch atau checkIteration, dan server yang memutuskan benar atau salah, memotong nyawa, sekaligus menghitung skor. Jawaban baru dibuka ke layar setelah pemain menang, lewat properti terpisah untuk tabel pembahasan.
Masalah kedua muncul dari mode Champions. Kalau satu level hanya boleh dimainkan sekali, pemain yang sadar akan kalah bisa saja menekan F5 atau menutup tab supaya skornya tidak tersimpan. Saya menyelesaikannya dengan menandai sesi bermain di server: saat level dimulai, aplikasi menyimpan penanda beserta waktu mulai dan skor parsial yang diperbarui tiap jawaban benar. Kalau halaman dibuka lagi dan penanda itu masih ada, skor parsial langsung difinalisasi dan level terkunci. Di sisi browser, F5 dicegat modal konfirmasi, dan berpindah tab saat mengerjakan memotong nyawa lewat Page Visibility API.
Level 4 adalah bagian yang paling lama dikerjakan. Peta dibangun dengan Three.js: terrain, jaringan jalan, gedung outlet, dan tiga truk yang benar-benar berjalan dari simpul ke simpul. Supaya truk mengikuti jalan dan bukan terbang lurus, saya menulis graf jalan dengan A* sendiri di level4-pathfinding.js. Validasi urutan rute tetap dikerjakan server dengan pengecekan strict: outlet yang diklik harus persis outlet berikutnya pada rute yang benar, ditambah pengecekan kapasitas kendaraan.
Satu kendala kecil yang sempat membuat aplikasi rusak adalah bundling Livewire dan Alpine secara manual di satu entry Vite. Begitu saya coba memecah tiap level jadi entry terpisah, Livewire dan Alpine ikut termuat dua kali dan Alpine melempar error redefine property. Sejak itu semua level saya daftarkan dari satu file app.js saja. Untuk backup Excel di fitur reset skor, saya memilih menulis file .xlsx sendiri memakai ZipArchive bawaan PHP daripada menambah dependency baru hanya untuk satu tabel tujuh kolom.
Saya mengerjakan seluruh bagiannya sendiri: migrasi dari versi PHP native, skema database, keempat gameplay beserta perhitungan skornya, peta 3D, panel admin, sampai penyiapan deploy ke hosting.
Aplikasinya sudah dideploy ke hosting dengan domainnya sendiri dan data pemain dari versi sebelumnya ikut dipindahkan lewat seeder import. Mode Champions dipakai saat sesi lomba, mode Casual untuk latihan biasa.
Yang belum selesai, tiga bonus game di career map masih berupa kartu Coming Soon, lencana bonusnya juga menunggu game itu ada. Rencana berikutnya menambah bonus game tersebut dan memindahkan angka soal tiap level ke database supaya dosen bisa mengganti kasus tanpa menyentuh kode.