Skip to content

Latest commit

ย 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฑ MarziusKill โ€” A Haunted 8-Ball Story

Final project for the Interactive Graphics course, Sapienza University of Rome


๐ŸŽฎ Play the Game

Go to the GitHub Page.


๐Ÿ“ Game Description

MarziusKill is a first-person 3D billiards game set inside a haunted pub. The player takes the role of MARZIUS, entering an apparently abandoned bar where a supernatural opponent, KILL, is waiting for one last game of 8-ball.

The project combines a custom billiards simulation with full player interaction, 8-ball rules, a shot-planning CPU opponent, a physically navigable pub environment, cinematic sequences, procedural visual effects, and spatial audio.

Two game modes are available:

  • SOLO RUNOUT โ€” clear the table and legally pocket the 8-ball within a difficulty-dependent move budget.
  • VS KILL โ€” play a complete 8-ball match against KILL, whose planning depth and execution accuracy depend on the selected difficulty.

No external physics engine is used: ball dynamics, spin, cue impact, rail response, pocket capture, ball return, and shot prediction are implemented in JavaScript.


๐Ÿ“ Project Structure

src/
โ”œโ”€โ”€ assets/         # GLB asset loading and billiards-object mapping
โ”œโ”€โ”€ audio/          # Centralized Web Audio system
โ”œโ”€โ”€ bot/            # KILL planning, simulation and difficulty profiles
โ”œโ”€โ”€ config/         # Physics, gameplay and presentation constants
โ”œโ”€โ”€ events/         # Shot/gameplay event definitions
โ”œโ”€โ”€ game/           # Match state, 8-ball rules, ball-in-hand and Solo mode
โ”œโ”€โ”€ graphics/       # Scene, pub, lighting, cinematics, VFX and controllers
โ”œโ”€โ”€ input/          # Keyboard and pointer input handling
โ”œโ”€โ”€ objects/        # Cue rig and ball scene objects
โ”œโ”€โ”€ physics/        # Custom rigid-ball, rail, pocket and return physics
โ”œโ”€โ”€ systems/        # Shot, trajectory, cue-clearance and table systems
โ”œโ”€โ”€ ui/             # Main menu, pause menu, rules and gameplay HUD
โ”œโ”€โ”€ main.js         # Application bootstrap and game orchestration
โ””โ”€โ”€ style.css       # UI styling

public/
โ”œโ”€โ”€ models/         # Billiards and pub GLB assets
โ”œโ”€โ”€ textures/       # Pool-table and pub PBR textures
โ””โ”€โ”€ audio/          # Runtime sound effects, ambience and jukebox music

๐Ÿ•น๏ธ Game Modes

Solo Runout

KILL remains a spectator while the player clears the table.

Difficulty Move Limit
Easy 42
Medium 32
Hard 24

Every shot costs 1 move. A foul adds 2 extra moves, and each pocketed ball belonging to the wrong assigned group adds 1 extra move. Reaching the move limit before legally pocketing the 8-ball results in defeat.

Vs KILL

A complete two-player 8-ball match against the CPU.

KILL uses the same table geometry and physics systems as the player-facing simulation. Difficulty changes how many shot routes are explored and how accurately the selected shot is executed:

  • Easy โ€” reduced search, chooses among several good candidates, and introduces aim/power error.
  • Medium โ€” deeper search with small execution error.
  • Hard โ€” widest search profile with no artificial aim or power error.

๐Ÿ“œ Core 8-Ball Rules

The rules enforced by the game include:

  • The cue ball starts in the kitchen for the opening break.
  • A break is legal if at least one object ball is pocketed or at least four distinct object balls contact rails.
  • An illegal break reracks the table and gives the incoming player ball-in-hand in the kitchen.
  • A legal-break scratch keeps the layout and gives the incoming player ball-in-hand in the kitchen.
  • Pocketing the 8-ball on the break respots it and leaves the table open.
  • Solids are 1โ€“7 and stripes are 9โ€“15.
  • The first legally pocketed solid or stripe after the break assigns groups.
  • Normal shots enforce a legal first contact followed by a rail contact or pocket.
  • Pocketed balls remain down even when the shot is a foul.
  • Normal fouls give the incoming player ball-in-hand anywhere on valid cloth.
  • The pocket is called only for the final 8-ball shot.
  • Pocketing the 8-ball early, off the table, while scratching/fouling, or in the wrong called pocket results in defeat.

The complete in-game summary is also available from RULES in both the main menu and pause menu.


๐Ÿšฆ Controls

Menus

Key / Input Action
Mouse Select menu entries
W / S or โ†‘ / โ†“ Move selection
A / D or โ† / โ†’ Navigate supported menu choices
Enter / Space Confirm
Esc Back / Pause / Resume

Gameplay

State Key / Input Action
Free view Q / E Walk around the table
Free view W A S D Look around
Free view Enter Move into aiming position
Aim Left mouse drag Rotate/elevate the cue
Aim W A S D Move the cue-ball contact point and apply spin
Aim / Power Hold V Show predicted trajectory
Aim / Power Hold J Top-down table view
Aim / Power Hold K High three-quarter table view
Aim Enter Start the power meter
Aim Space Return to free view
Power Enter Shoot at the currently displayed power
Power Space Return to aim
Ball in hand Mouse drag Place the cue ball on valid cloth
Ball in hand Enter Confirm placement
Called 8-ball pocket W A S D Select the target pocket
Called 8-ball pocket Enter Confirm the called pocket

๐Ÿ› ๏ธ Technical Features

Hierarchical Models

The project uses runtime transformation hierarchies rather than imported animation clips.

  • Cue rig โ€” aimPivot โ†’ elevationPivot โ†’ contactOffsetPivot โ†’ rollPivot โ†’ strokePivot โ†’ cue. Each layer controls a separate component of cue orientation, contact offset, spin alignment, and stroke.
  • Doors and windows โ€” imported static meshes are attached to JavaScript-controlled pivots so opening and closing animations propagate through the hierarchy.
  • Cue rack / cinematic cues โ€” individual cue anchors support pickup, return, floating, aiming, and attack sequences while preserving the rack hierarchy.
  • Triangle/prism VFX โ€” grouped procedural meshes, edge geometry, light sources, and transforms are animated as coordinated structures.

Custom Billiards Physics

The physics simulation runs with a fixed 240 Hz timestep and is implemented without an external physics engine.

  • Sphere-sphere collision detection and impulse response.
  • Cue-ball strike from cue direction, elevation, contact point, and shot power.
  • Linear and angular velocity with off-center hits and side/top/back spin.
  • Sliding-to-rolling behaviour and rolling resistance.
  • Rail collision against the real table layout.
  • Six independent pocket mouths derived from the authored pocket geometry.
  • Gravity-driven pocket drop and capture.
  • Internal ball-return transport using the hidden BallReturn asset rather than teleporting pocketed balls.
  • Ball-in-hand validation against cushions, pocket mouths, table bounds, and other balls.

Cue Interaction and Shot Preview

The player can independently control:

  • horizontal cue direction;
  • cue elevation;
  • exact contact point on the cue ball;
  • shot power.

A custom trajectory system predicts the cue-ball path on demand and uses the current table state, spin parameters, cushions, balls, and pockets without changing the live simulation.

KILL โ€” CPU Shot Planning

KILL does not use scripted shots. The planner:

  1. finds currently legal target balls;
  2. generates pocket routes and ghost-ball contact geometry;
  3. rejects blocked cue-ball and object-ball paths;
  4. checks cue clearance;
  5. simulates candidate shots with the same core physics systems used by the game;
  6. scores legality, pots, scratches, 8-ball outcomes, break quality, and cue-ball position;
  7. selects and executes a shot according to the chosen difficulty profile.

The bot also handles legal ball-in-hand placement automatically.

Lighting and Textures

  • PBR materials use combinations of base color, normal, roughness, metallic, and height-derived source maps where applicable.
  • The pool table is lit by three THREE.SpotLight sources aligned with the imported three-shade fixture.
  • Additional warm and violet pub lighting separates the table from the surrounding haunted environment.
  • Imported pub assets retain their authored PBR materials where available.
  • Dynamic lights and emissive effects are used during supernatural VFX and cinematics.

User Interaction

The game combines keyboard and pointer input across several interaction states:

  • free first-person movement around the table;
  • independent head movement;
  • cue aiming and elevation;
  • spin/contact-point selection;
  • oscillating shot-power selection;
  • trajectory and alternate camera views;
  • ball-in-hand drag placement;
  • called-pocket selection for the 8-ball;
  • main menu, rules, pause, restart, and rematch flows.

Animations

All gameplay and cinematic animations are implemented in JavaScript; no imported animation clips are used.

Examples include:

  • cue backswing, strike, recovery, pickup, return and fall;
  • player/KILL camera movement and walking;
  • KILL cue materialization and dematerialization;
  • door and window opening/closing;
  • triangle apparition/disappearance and rack reset;
  • prism growth, pulse and fade;
  • pocket flames and called-pocket beacons;
  • cue-ball placement transitions;
  • scoreboard chalk writing;
  • victory and defeat cinematics;
  • floating rack cues and final cue attack sequence.

Procedural and Runtime Graphics

Several visible elements are generated or updated at runtime:

  • trajectory lines and collision preview;
  • shot-power HUD;
  • KILL thinking/progress UI;
  • pocket and beacon VFX;
  • triangular prism geometry and edges;
  • scoreboard text rendered to a CanvasTexture;
  • final cinematic scoreboard messages.

Audio

A centralized AudioManager built on the Web Audio API handles:

  • separate game, music, cinematic, and UI buses;
  • browser-safe audio unlocking after user interaction;
  • positional/attenuated sound sources;
  • impact-scaled ball and rail volumes;
  • collision cooldowns and subtle playback-rate variation;
  • synchronized cue, ball, rail, window, door, footsteps, chalk, triangle, prism, KILL and cinematic effects;
  • a positional jukebox that starts after the opening cinematic;
  • an abrupt vinyl-stop transition before either ending cinematic;
  • separate spectral ambience for the opening and ending sequences.

๐Ÿ“š Libraries and APIs Used

  • Three.js โ€” WebGL rendering, scene graph, cameras, lights, materials, textures and 3D math.
  • GLTFLoader โ€” loading the billiards and pub GLB assets.
  • Web Audio API โ€” runtime audio graph, spatialization and synchronized sound playback.
  • Vite โ€” development server and production build tooling.

No external physics engine or imported animation library is used.


๐Ÿ’ป Running Locally

Requirements:

  • a recent Node.js installation;
  • a modern browser with WebGL and Web Audio support.

Install dependencies and start the development server:

npm install
npm run dev

Create a production build with:

npm run build

Preview the production build locally with:

npm run preview

๐Ÿ‘ฅ Authors

Name Student ID Email
Livio Marzio della Penna 2041721 dellapenna.2041721@studenti.uniroma1.it

๐Ÿ“ƒ Assets and Credits

Third-party 3D models, textures, music, and sound effects are documented in ATTRIBUTIONS.md.

All imported 3D models are used as static source assets; game and cinematic animation is implemented in JavaScript.

About

final-project-marziuskill created by GitHub Classroom

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages