A first-person horror game set in a small, dark, decommissioned hospital. The player wakes in the dark with a failing flashlight, must find four rings hidden across the rooms, and reach the exit before the figure that hunts the wards catches them.
Final project for Interactive Graphics (Prof. Marco Schaerf, Sapienza
University of Rome, DIAG). Built with three.js r184,
tween.js, PointerLockControls and
lil-gui. All animation is written by hand in JavaScript; no animation clips are
imported from external files.
Live (GitHub Pages):
Run locally (ES modules require a server, not file://):
# from the project root
python3 -m http.server 8000
# then open http://localhost:8000| Input | Action |
|---|---|
| Click | Lock the pointer / start |
W A S D / arrows |
Move |
| Mouse | Look |
F |
Toggle flashlight |
E |
Pick up items, open doors, use the keypad, hide |
| Left click | Shoot |
Esc |
Pause / release the pointer |
Collect the four rings, then reach the green exit. The rings are obtained in different ways: one from a wall keypad (the code is the digits of pi, hinted by two posters), one inside the locked room (which needs a key), one from a blood bag hanging from the ceiling, and one from a locked crate. The key and the last two rings are released by shooting their container.
A humanoid figure patrols the building. Pointing the flashlight at it makes it notice the player and give chase faster, so the dark is sometimes safer than the beam. The revolver only staggers the figure, it cannot kill it. Lockers can be used to hide. Three difficulty levels (Easy, Normal, Hard) change the figure speed, the number of figures, the battery drain and the amount of ammunition.
- Engine: three.js r184 (
WebGLRenderer) - Tweening:
@tweenjs/tween.js - Camera / input:
PointerLockControls - Debug / settings UI:
lil-gui - Build: none. Plain
index.htmlwith an ES module import map. During development the libraries load from a CDN; for submission they are vendored into/liband the import map is repointed to local paths.
index.html entry point: import map, HUD overlay, intro screen
editor.html standalone prop-placement sandbox
src/
main.js bootstrap: renderer, scene, camera, game loop
world.js grid level: walls, textures, lights, doors, collision, pathfinding
figure.js hierarchical hunting figure: rig + hand-coded animation
monsters.js monster instances, health, stagger, respawn
ai.js figure behaviour: wander / chase, navigation, lunge
player.js PointerLockControls, movement, collision, flashlight, battery
game.js rules: rings, key, puzzles, win/lose, difficulty, pickups
gun.js view-model pistol, hitscan firing, recoil, muzzle flash
importModels.js placed GLB props (grounded, oriented) + live editor
clues.js puzzle clue posters
assets.js texture / model / audio loading with procedural fallbacks
ui.js HUD, screens, lil-gui panels
decals.js floor blood decals
audio.js ambient drone, footsteps, one-shot cues
assets/ textures (color/normal/roughness), audio, models
lib/ vendored libraries (for submission)
docs/ technical report and user manual