Skip to content
 
 

Repository files navigation

Old San Juan Kart

An arcade kart racer built in Three.js, set in San Juan, Puerto Rico. Two circuits:

  • Viejo San Juan — a tight arcade lap on blue adoquín cobbles past El Morro, the city walls and the Puerta de San Juan.
  • Expreso Las Américas — a divided expressway from El Morro out to Hato Rey, with civilian traffic to pick your way through. Out on the right-hand carriageway, U-turn, back on the other one.

▶ Play: https://nasilvae.github.io/old-san-juan-kart/

Every asset is generated procedurally at runtime — textures, geometry, audio and the city itself. There are no binary art files in this repository.

Controls

Action Keys
Accelerate W /
Brake / reverse S /
Steer A D /
Hop & drift Shift
Use item E
Look back C
Mute M

A gamepad works too, and touch devices get on-screen controls automatically: a relative analog steering pad under the left thumb, and gas / brake / item buttons under the right. Play it in landscape.

There is deliberately no drift button on touch — a phone only has two thumbs and one of them is steering. Instead, blip the gas: lift and re-press it while the wheel is turned and the kart snaps into a slide, which holds for as long as you stay on the gas and cashes in its mini-turbo the moment you straighten up.

Mobile

The game detects the device on load and picks a quality tier, which drives pixel ratio, antialiasing (MSAA on mobile instead of SMAA — tile GPUs resolve it almost free), bloom resolution, colour-grade sample count, shadow map size, ocean tessellation, traffic density, physics rate and draw distance. Append ?quality=high, ?quality=mid or ?quality=low to the URL to force a tier.

iOS gets a fixed mid tier. Android is scored at runtime from core count, deviceMemory, panel pixel count and the GPU string, because core count alone is a poor proxy — plenty of budget chips ship eight small cores.

?course=viejo or ?course=expreso skips straight to a circuit.

Running locally

npm install
npm run dev

Then open the URL Vite prints (default http://localhost:5173).

npm run build     # production build into dist/
npm run preview   # serve the production build

What's in here

Path Purpose
src/core/ Renderer, input and audio
src/world/ Track splines, courses, terrain, city and highway scenery, traffic, sky, procedural textures
src/kart/ Kart physics and the kart model
src/ai/ Bot drivers — racing line, corner speed, drifting
src/items/ Item boxes and projectiles
src/race/ Lap timing, standings, respawns
src/ui/ HUD, menus, results
src/fx/ Particles

A couple of pieces worth calling out:

  • src/world/clearance.js bakes a per-track-index barrier from the actual city geometry, using a vertical occupancy bitmask so overhangs aren't mistaken for walls. This is what stops karts clipping through facades.
  • src/world/courses.js describes each circuit as data — control points, surface, edge treatment, scenery builder, laps, traffic. The expressway is generated by divided(), which offsets a one-way corridor to either side and joins the ends with U-turns; because both carriageways come from the same spline, right-hand driving and oncoming traffic fall out of the geometry for free rather than needing to be special-cased.
  • src/world/track.js is the single source of truth for track geometry. Note that its right vector is banked — it has a Y component — which matters for anything sampling the road surface off the centreline.

Deployment

Pushing to main triggers .github/workflows/deploy.yml, which builds the site and publishes it to GitHub Pages.

License

Released under the MIT License — © 2026 Nathaniel Silva.

You are free to use, copy, modify, merge, publish, distribute, sublicense and sell copies of this software, provided the copyright notice and permission notice are included. The software is provided "as is", without warranty of any kind, express or implied; see LICENSE for the full text.

Notices

  • This is an independent, non-commercial fan project. It is not affiliated with, endorsed by, or sponsored by Nintendo or any other company, and it contains no assets from any commercial game.
  • Landmarks such as El Morro, the Puerta de San Juan, the Capitolio and the Tótem Telúrico are stylised, low-poly interpretations of real public landmarks, recreated from scratch for this project. No company logos, branding or trade dress are reproduced.
  • Viejo San Juan is a fictional circuit. It is inspired by the historic quarter and passes recognisable landmarks, but its layout does not follow the real street plan.
  • Expreso Las Américas does follow the real corridor from El Morro to Hato Rey (PR-25 → Ave. Fernández Juncos/PR-1 → Expreso Las Américas/PR-18 → Ave. Ing. Manuel Domenech), heavily simplified and compressed to a racable length. The route was authored by hand from written driving directions — no map data, tiles or extracts were used, so no map licence (ODbL or otherwise) applies. Road geography is factual and not subject to copyright.
  • Three.js is used under its own MIT license, and the UI fonts (Bungee, Rubik) are used under the SIL Open Font License 1.1. No binary assets ship with this repository — every texture, sound, music cue and 3D model is generated by code at runtime. Full details, including the music and likeness rationale, are in THIRD-PARTY-NOTICES.md.

About

Stateloop publishing fork of nasilvae/old-san-juan-kart. Original game and MIT license by its upstream authors.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages