Skip to content

Instantly share code, notes, and snippets.

@benallfree
Last active April 1, 2025 04:26
Show Gist options
  • Save benallfree/9fefe083a5352a85ddf4ac24bb03f231 to your computer and use it in GitHub Desktop.
Save benallfree/9fefe083a5352a85ddf4ac24bb03f231 to your computer and use it in GitHub Desktop.
3D FPS web starter

I am building a mobile-first 3D FPS MMO web game. Please set up a basic project structure as follows:

  • Use bun for package management
  • Use Vite + Typescript for the frontend
  • Use bun + Typescript + expressjs for the backend
  • Use socket.io for communication

Features:

  • Opengraph - uses splash.jpg image
  • Splash page - displays spash.jpg and has a play button that is disabled until a socket connection is made
  • If ref is present, it goes straight into the game and skips the splash page
  • There is a HUD flex row (HUD tray) across the top that can hold various buttons and items.
  • The HUD Tray has a Mute toggle and a Debug toggle
  • Debug panel is an overlay that shows FPS. It is designed modularly so other debug items can be added to it. (Ie, DebugPanel.addItem(new DebugItemSubclass())
  • In desktop mode, WASD controls movement (forward/backward/strafe) while the mouse pointer lock controls lookaround
  • In mobile mode, it uses two nipplejs controls. the lower left mimics WASD and the lower right mimics mouse lookaround
  • After splash page, drop the player into an empty well lit 3d plane
  • Players joining should be visible as other avatars
  • background.mp3 plays the background music. if ref bypasses splash, the game starts in mute mode and pressing mute for the first time starts the audio
  • Deploy to fly.io on a 256mb instance in sjc region: fly.toml, Dockerfile, and .dockerignore

Rules:

  • Avoid frameworks (react, svelte, etc).
  • Embrace libraries (socket.io, nipple, etc)
  • Use early returns
  • Prefer factory functions and composition over classes and inheritance

Notes from previous attempts:

  • Nipplejs ships with TS definitions
  • if you make client and server as separate packages, be sure to create a bun workspace
  • make a bun dev root command that runs both the vite frontend and the nodejs backend
  • check for linter errors before stopping
  • server has no build step because bun runs the typescript directly
  • camera lookaround should have Z-axis lock (no rolling allowed)
  • movement should be delta-based and fps-independent
  • mobile lookaround should be delta-based and fps-independent

Please repeat back what you understand and pause before proceeding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment