Architecture
This portfolio is built on Angular 19 and Phaser.js 3 game framework. Angular serves as the
"shell" – it handles routing, modals, the translation system (i18n) and DOM communication.
Inside, the Phaser scene runs in HTML5 Canvas via WebGL renderer, handling map rendering, the
player, NPCs and all visual effects.
The application is divided into multiple layers: the game scene, entity classes (Player, NPC,
Monster), Angular components for UI overlay (menus, modals, minimap), Web Workers for heavy
computations (pathfinding, smoke effects) and services for communication between the Angular
and Phaser worlds.
An interesting aspect is that Angular and Phaser live side by side – Angular renders an HTML
layer above the canvas element, so modals, menus and text are regular DOM, while the game
underneath runs in a GPU-accelerated WebGL context. Communication between them happens through
shared Angular services and global callback functions.
Phaser.js
At the heart of this portfolio is
Phaser.js 3
– an open-source game framework for HTML5 games used by thousands of developers worldwide.
Phaser can render via WebGL and Canvas 2D, handles physics, animations, sprite sheets, tile
maps, audio and input from keyboard, mouse and touch – all in the browser without plugins.
In this project, Phaser manages the entire game loop – 60 times per second it updates player
and NPC positions, evaluates map collisions, renders tile map layers, manages the camera and
animates hundreds of sprites. Thanks to the WebGL renderer, it's hardware-accelerated and runs
smoothly even on mobile devices.
Phaser was chosen for its mature tile map support (the foundation of the pixel art world),
built-in camera system with smooth scrolling, rich animation engine and active community. The
framework is modular – I only use what I need, and the rest (physics, particles) is handled by
custom implementations optimized for this specific project.
Chunk System
The game map contains thousands of tiles (16×16 pixels), which would mean enormous memory
consumption if loaded all at once. That's why the map is divided into small chunks – square
blocks that are dynamically loaded and released based on the player's position.
The Chunk Manager tracks the camera position and calculates which chunks should be visible.
When the player moves to a new area, chunks out of range are destroyed (including their tile
layers and collision data) and new ones are created. This way, only the player's surroundings
are kept in memory, dramatically reducing RAM consumption.
After every map edit in the Tiled editor, a build script is executed that cuts the map into
individual chunk files, cleans up unused tilesets and optimizes data for fast runtime loading.
NPC System
NPC characters have their own viewport culling – when they leave the visible camera area,
their sprite is completely destroyed (including wheels, brake lights and blinkers for cars).
When they return to the field of view, they're recreated with full state. This saves hundreds
of GPU draw calls.
Pathfinding runs in a Web Worker using the EasyStar.js library. NPC routes are pre-calculated,
so the worker doesn't need to compute paths in real-time and the main thread stays unblocked.
Each NPC has defined waypoints and behaves according to its type – some walk, others drive
cars with functional blinkers and brake lights.
Special NPC types include ghosts, dancers, monsters and crowds of people. The Crowd Manager
controls groups of NPCs that appear and disappear based on map areas. Cars have a complete
visual system – 4 independent wheels, brake lights with glow effect and a blinker system that
activates before and after each turn.
Tiled Editor
The entire game map is designed in Tiled – an open-source editor for creating tile-based maps.
The map consists of multiple layers: terrain, buildings, decorations, collision layer and
object layers for NPC routes, markers and zones.
Tiled saves the map in TMX format (XML). After every edit, a custom build pipeline processes
the TMX file – cuts the map into chunks, extracts collision data, cleans unused tiles from
tilesets and generates optimized JSON files for runtime.
Object layers in Tiled are used to define game elements: NPC spawn points, their routes
(series of waypoints), darkness zones, content marker positions and crowd management areas.
This way, a designer can visually place game elements directly in the editor without needing
to modify code.
Optimization
Performance is a priority at every level. Chunk loading ensures only the player's surroundings
are in memory. NPC viewport culling destroys and creates sprites based on visibility.
Pathfinding runs in a separate Web Worker, so the game stays smooth even on weaker mobile
devices.
Assets are loaded lazily – textures, sounds and sprite sheets are downloaded only when needed,
not at application startup. Images use the modern WebP format with PNG fallback. Fonts have
pre-generated fallback metrics to prevent layout shifts during loading.
The entire website is optimized for mobile devices – touch controls via virtual joystick,
responsive UI layer, dynamic viewport (100dvh for correct height on iOS) and efficient
rendering. On desktop, Phaser uses WebGL for hardware acceleration, while on weaker devices it
automatically switches to Canvas 2D renderer.