Final project for the Interactive Graphics course, Sapienza University of Rome
⏳ The game may take a while to load, assets are heavy and patience is the virtue of the strong. Hang tight, it's worth it.
▶ Click here to read the Technical Report and User Manual
Dungeon Explorer is a first-person action-adventure game set in a medieval dungeon. The player must explore interconnected rooms, solve environmental puzzles by interacting with the surrounding world (pulling levers, lighting torches, and destroying obstacles) and defeat a guardian enemy to reach the exit
The codebase is organized into 5 modules, each with a clear and distinct responsibility.
js/
├── core/ # Engine bootstrap and global state
├── player/ # Player controller, input and collision
├── systems/ # Game logic per area / room
├── ui/ # HUD, inventory and overlays
└── world/ # 3D objects, props and interactive elements
Each room requires completing a specific interaction to unlock the passage to the next:
- Room 1 — Pick up the axe, destroy the barrel, pull the lever, light the unlit wall torch
- Corridor — Dodge the swinging pendulum traps in the first section; avoid the rolling boulder in the second
- Room 2 — Step on the pressure plate (which locks the entrance door), defeat the ogre to open the exit
| Key / Input | Action |
|---|---|
W A S D |
Move |
Shift |
Sprint |
| Mouse | Look around |
E |
Interact / Pick up item |
Left click |
Attack (only with axe or sword equipped) |
Right click (hold) |
Block with shield (only with shield equipped) |
C |
Open controls |
F |
Open / Close inventory |
| Mouse (in inventory) | Drag items between slots |
mouse scroll |
Switch weapons |
Q |
Switch item for utiliy slot |
X |
Open Achievements |
The game includes a custom achievement system built entirely in JavaScript, without external libraries, structured in three tiers:
- Base achievements — unlocked by completing specific in-game actions (picking up items, lighting torches, pulling levers, reading the note, defeating the mob, winning without dying).
- Super achievements — unlocked automatically when all required base achievements are collected (e.g. Collector, Warrior, Fire Man, SpeedRunner).
- Final achievement — 100% Platinum, unlocked only when every base and super achievement has been obtained.
Unlocking an achievement enqueues a toast notification. A queue ensures that multiple simultaneous unlocks are displayed one after the other without overlap, with color coding distinguishing the three tiers: green for base, purple for super, gold for final.
- Corridor pendulums —
root(ceiling anchor) →pendulumGroup(chain + blade) hierarchy; sinusoidal animation implemented in JavaScript rotates only the parent node, propagating to all children - Double door —
door.group→leftPivot/rightPivot→ door leaves; the opening animation rotates only the pivot nodes, the leaves follow through transform inheritance - Procedural barrel —
root→barrelCore+staveGroup+middleRingGroup+ rings + rivets; progressive destruction acts on specific hierarchical layers (staveGroup.visible,middleRingGroup.visible)
- Full PBR textures on floors, walls, and ceilings: albedo, normal map, roughness map; displacement map on floors only (96×96 vertex subdivision)
- PointLights on all wall torches and chandelier with multi-frequency flicker
- SpotLight on the held torch (hand-carried pickup), providing a directional warm cone of light
- Raycast interaction system (key
E) for picking up objects and activating mechanisms - Torch system: proximity-based ignition from ignition sources (lit wall torch → portable torch and vice versa)
- AABB collision detection with walls for player movement
- Combat system: axe/sword hitbox via raycast, timed damage windows, shield block system
- Inventory with typed slots and drag-and-drop between slots
- Pressure plate trigger that locks the Room 2 entrance door on contact
- Respawn system after player death
- Axe swing animation (eased rotation on root node)
- Sword swing animation (eased rotation on root node)
- Torch flame animation (scaling + sinusoidal rotation + ember particles)
- Torch lighting animation (
_litProgresswith ease-out curveMath.pow(p, 0.55), clamped deltaTime) - Pendulum animation (sinusoidal oscillation using
Math.sin(t)and deltaTime) - Rolling boulder animation (translation + self-axis rotation)
- Door opening animation (gradual pivot rotation using
moveTowards) - Lever animation (rotation on pivot node)
- Barrel destruction animation (progressive layer-based deformation over hit stages)
- Mob death and dissolve animation (opacity fade on
transparentmaterials)
- Dungeon (rooms, corridors, geometry) —
THREE.BoxGeometry/PlaneGeometry - Barrel — cylinder + staves + rings + rivets, entirely built with
THREE.CylinderGeometry/BoxGeometry/TorusGeometry - Pendulums — ceiling anchor + chain links + blade using
THREE.ExtrudeGeometry - Boulder —
THREE.SphereGeometry
To ensure fast loading times and smooth performance in the browser, several optimization passes were applied to the project's assets.
All 3D models (.glb / .gltf) were optimized using gltf-transform, an industry-standard CLI tool for GLTF asset processing.
All PBR texture maps (albedo, normal, roughness, displacement) were downscaled from 4K (4096×4096) to 1K (1024×1024) using Squoosh, reducing texture memory footprint by approximately 93% with no perceptible visual difference at typical in-game viewing distances.
Textures optimized:
stone_floor— diffuse, displacement, normal (GL), roughnessrock_wall_08— diffuse, normal (GL), roughness
All WebGL shader variants are pre-compiled during the loading screen using renderer.compileAsync(). This eliminates GPU compilation spikes on first use, ensuring smooth and consistent frame rates from the very first frame of gameplay.
All game sounds are preloaded in parallel during the loading phase via AudioLoader, preventing any audio latency or stuttering on first interaction.
- Three.js — WebGL rendering, scene management, materials, lights, animations
- GLTFLoader — 3D model loading (ogre, door, torches, ecc...)
- Web Audio API — ambient and gameplay audio system
| Name | Student ID | |
|---|---|---|
| Agostini Antonio | 1995653 | agostini.1995653@studenti.uniroma1.it |
| Istoc Julia Claudia | 2058878 | istoc.2058878@studenti.uniroma1.it |
The source code is released under the MIT License.
Third-party assets (3D models, textures, audio) and their respective licenses are listed in CREDITS.md.