Most political satire in India is either stand-up comedy or angry Twitter threads. I wanted to see what happens when you turn contemporary Indian electoral politics into a fast-paced, retro 2D platformer. That's Elected & Neglected (subtitled "Vikas Daudta Hai"). You play as an ambitious political candidate sprinting through three grueling stages—Rally Grounds, Corporate Corridors, and the Road to Parliament—dodging media megaphones, jumping over division politics, smashing electoral bond mystery blocks to grab cash, and desperately racing to reach Parliament House before the countdown timer hits zero.
The game is built on Phaser (the lockfile resolved to runtime v4.1.0, despite package.json specifying ^3.88.2) using Phaser's Arcade Physics engine with a heavy downward pull of gravity: { y: 980 }. The levels are massive—each world spans 4800 × 600 pixels rendered inside an 800 × 500 viewport using Phaser.Scale.FIT with auto-centering. I wanted the game playable everywhere, so I wired a triple-target deployment pipeline: Vite 8 for instant in-browser web play, an Electron 42 desktop shell (com.meghmalhar.electedandneglected) configured for an unlocked 1280×720 desktop window, and a Capacitor 8 native Android wrapper centered around MainActivity.java.
Building the game was fun, but debugging physics and state management across procedural side-scrollers gave me a massive appreciation for real game developers. I ended up documenting every quirk in a 1,014-line PROJECT_AUDIT.md file in the repo. Some of the most notable hurdles:
- The Lockfile Drift Trap: My
package.jsonhad Phaser pegged at^3.88.2and Vite at^6.3.5, but npm resolved Phaser 4.1.0 and Vite 8.0.12 into the lockfile. Certain Arcade Physics collision callbacks behaved subtly differently between minor releases, causing sprites to occasionally stick to the edge of floating tile platforms. - Terrain Re-randomization on Death: When a player dies with remaining lives, the game calls
scene.restart(). But because level generation logic lived directly insidecreate(), restarting re-rolled the pseudo-random terrain gaps, enemy spawn coordinates, and electoral bond blocks. Retrying the level literally gave you a different physical obstacle course every single life. - The Brutal Spawn Loop: In early builds, there were zero respawn invulnerability frames (i-frames). If a wandering enemy or moving projectile hit you near your respawn anchor at
x = 120, you would respawn and immediately take lethal damage before player input even registered. - Inert Vote Tokens: I created a custom HUD counter that tracked collected vote tokens with satisfying audio chimes. But during the initial crunch, I forgot to hook the token tally into the final scoring multipliers or
WinSceneconditions—so votes were essentially cosmetic vanity tokens while cash (₹) was the only metric that actually powered your campaign. - Predictable Shell Vectors: Shell projectile velocity was calculated as
Math.sign(this.player.x - ex) * diff.patrol. Because the player always initialized atx = 120, the opening trajectory of every projectile in level 1 was 100% deterministic.
It's ridiculous, chaotic, politically cheeky, and taught me how complex even a seemingly simple 2D platformer becomes once physics, multi-target packaging, and state machines collide.