Loading
Projects
  • Client:   Politeknik Negeri Batam
  • Web App
  • Date:   Apr 2026

Logistic of Champions: A Logistics Decision Simulation Game

Cover image of Logistic of Champions: A Logistics Decision Simulation Game

A web game for logistics students. Four levels of questions are played with lives and a time limit, complete with a leaderboard and an admin panel for lecturers.

Login (desktop)
Career map (desktop)

Background

Logistics topics such as transport mode selection, Vehicle Running Cost, the Gravity Location Model, and distribution routing are usually taught through calculation exercises. Students work on paper, hand it in, and get it marked. Politeknik Negeri Batam wanted the same material delivered another way: played, with a time limit, and with consequences for getting it wrong.

The first version of this game was written in plain PHP. The trouble was that adding a new level meant copying a lot of code, and lecturers had no way to monitor or control a session other than opening the database. I rebuilt the whole application in Laravel and added the admin side that had not existed before.

Solution

Players sign in with their student number and land on a career map, an illustrated road with four level pins. The next pin unlocks once the previous level has been played. Each level has a briefing screen with the scenario, then moves into questions with a set number of lives and a running timer. A wrong answer costs a life; run out of lives and the run ends with whatever score you have. Every run is saved as a score row, so lecturers see the full history rather than just a final mark.

On the lecturer's side there is an admin panel: completion statistics per level, a live standings monitor during a competition, a score table per student, account management, and two important switches, the game mode and the site lock.

Key features

  • A career map with four level pins that unlock in sequence, a Top 5 widget, and the player's total score
  • Level 1: matching four transport modes to their technical data sheets, with connecting lines drawn and vehicles moving along them
  • Level 2: calculating the four components of Vehicle Running Cost, then the total
  • Level 3: four iterations of the Gravity Location Model, with a six-store weight table to fill in within a 0.5 tolerance
  • Level 4: a 3D map with a warehouse, ten outlets, and three vehicles with a 250 box capacity, where the player arranges each vehicle's route
  • A leaderboard filtered per level, ordered by highest score, with fastest time as the tiebreaker
  • A Champions mode (one run per level, no retries) and a Casual mode for free practice
  • Admin panel: statistics dashboard, live monitor, score table, user management with a deletion archive, site lock, and a score reset that automatically creates an Excel backup

Technical challenges

What took the most time was not the gameplay but making sure scores could not be gamed. Every answer key lives as a protected property on the Livewire component, so it never travels to the browser. The front end only sends the player's choice to methods such as attemptMatch or checkIteration, and the server decides right or wrong, deducts a life, and computes the score. Answers are only revealed after the player wins, through a separate property for the explanation table.

The second problem came from Champions mode. If a level can only be played once, a player who knows they are losing could press F5 or close the tab so the score is never saved. I solved it by marking the play session on the server: when a level starts, the application stores a marker with the start time and a partial score that updates on every correct answer. If the page is opened again while that marker still exists, the partial score is finalised immediately and the level is locked. In the browser, F5 is intercepted by a confirmation modal, and switching tabs during a question costs a life through the Page Visibility API.

Level 4 was the longest piece of work. The map is built with Three.js: terrain, a road network, outlet buildings, and three trucks that genuinely drive from node to node. To make the trucks follow the roads instead of flying straight, I wrote the road graph with my own A* in level4-pathfinding.js. Route order validation is still done on the server with a strict check: the outlet clicked must be exactly the next outlet on the correct route, plus a vehicle capacity check.

One small obstacle that briefly broke the application was bundling Livewire and Alpine manually in a single Vite entry. As soon as I tried splitting each level into its own entry, Livewire and Alpine were loaded twice and Alpine threw a redefine property error. Since then every level is registered from one app.js. For the Excel backup in the score reset feature, I chose to write the .xlsx file myself with PHP's built-in ZipArchive rather than add a new dependency for a single seven-column table.

My role

I did every part myself: migrating from the plain PHP version, the database schema, all four gameplay modes and their scoring, the 3D map, the admin panel, and preparing the deployment to hosting.

Results and what comes next

The application is deployed on hosting with its own domain, and player data from the earlier version was moved across through an import seeder. Champions mode is used during competition sessions, Casual mode for ordinary practice.

What is not finished: the three bonus games on the career map are still Coming Soon cards, and their bonus badges are waiting on those games. The plan after this is to add those bonus games and move each level's question figures into the database, so lecturers can change the scenarios without touching code.

Tech stack

Laravel 13 PHP 8.3 Livewire 4 Alpine.js Tailwind CSS 4 Three.js Vite MySQL

Similar projects

Ready to bring your ideas to life? I'm here to help

© 2026 Axa Rajandrya. All rights reserved.

+
+