Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
natea avatar

Threejs Game

  • 391 installs
  • 4 repo stars
  • Updated October 26, 2025
  • natea/fitfinder

threejs-game is an agent skill that builds browser-based 3D games with Three.js and WebGL for developers who need interactive scenes, game loops, and player controls without a native game engine.

About

threejs-game in natea/fitfinder helps developers scaffold and implement browser games using Three.js and WebGL. The skill covers scene graphs, cameras, lighting, mesh loading, animation loops, collision basics, and keyboard or pointer input for playable 3D experiences in the browser. Agents use it when prototyping fitness games, interactive demos, or lightweight 3D products that ship as static sites or SPA bundles without Unity or Unreal. The workflow emphasizes performant render loops, asset loading patterns, and responsive canvas sizing for desktop and mobile viewports. Developers reach for threejs-game when converting a 2D concept into a WebGL prototype or adding a gamified 3D module to an existing JavaScript app. Catalog listing description is generic, but the skill slug threejs-game identifies Three.js browser game development as the concrete scope. Triggers include Three.js game requests, WebGL prototypes, 3D browser experiences, or interactive scene builds.

  • threejs-game
  • AI & Agent Building
  • AI-coding skill

Threejs Game by the numbers

  • 391 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #2,011 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/natea/fitfinder --skill threejs-game

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs391
repo stars4
Last updatedOctober 26, 2025
Repositorynatea/fitfinder

How do you build a browser game with Three.js?

Helps with ai & agent building tasks.

Who is it for?

Frontend developers prototyping 3D browser games or gamified WebGL experiences without installing a native game engine.

Skip if: Console or mobile AAA titles requiring Unity, Unreal, or native GPU pipelines beyond browser WebGL limits.

When should I use this skill?

User requests a Three.js game, WebGL 3D prototype, browser game loop, or interactive Three.js scene with player controls.

What you get

Three.js scene code, WebGL render loop, game assets, input handlers, and deployable browser game bundle.

  • Three.js game source
  • WebGL scene and loop
  • Deployable browser bundle

Files

SKILL.mdMarkdownGitHub ↗

Three.js Game Development Skill

Comprehensive assistance with Three.js game development using WebGL, covering 3D rendering, game mechanics, physics, animations, and interactive browser-based games.

When to Use This Skill

Activate this skill when:

  • Building 3D web games with Three.js
  • Implementing game mechanics (player movement, collisions, scoring)
  • Setting up cameras, lighting, and scene management
  • Loading 3D models (GLTF, OBJ, FBX)
  • Handling user input (keyboard, mouse, touch, gamepad)
  • Creating animations and character controllers
  • Integrating physics engines (Cannon.js, Ammo.js)
  • Optimizing 3D game performance
  • Working with shaders and materials for game visuals

Quick Reference

Basic Game Setup

import * as THREE from 'three';

// Create scene, camera, renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Game loop
function animate(time) {
  requestAnimationFrame(animate);

  // Update game logic here
  updatePlayer(time);
  updateEnemies(time);
  checkCollisions();

  renderer.render(scene, camera);
}

animate();

Player Controller (Third-Person)

class PlayerController {
  constructor(camera, target) {
    this.camera = camera;
    this.target = target;
    this.distance = 10;
    this.height = 5;
    this.rotationSpeed = 0.005;
    this.moveSpeed = 0.1;
  }

  update(input) {
    // Movement
    const forward = new THREE.Vector3(0, 0, -1).applyQuaternion(this.target.quaternion);
    const right = new THREE.Vector3(1, 0, 0).applyQuaternion(this.target.quaternion);

    if (input.forward) this.target.position.add(forward.multiplyScalar(this.moveSpeed));
    if (input.backward) this.target.position.add(forward.multiplyScalar(-this.moveSpeed));
    if (input.left) this.target.position.add(right.multiplyScalar(-this.moveSpeed));
    if (input.right) this.target.position.add(right.multiplyScalar(this.moveSpeed));

    // Rotation
    if (input.rotateLeft) this.target.rotation.y += this.rotationSpeed;
    if (input.rotateRight) this.target.rotation.y -= this.rotationSpeed;

    // Update camera position
    const offset = new THREE.Vector3(0, this.height, this.distance);
    offset.applyQuaternion(this.target.quaternion);
    this.camera.position.copy(this.target.position).add(offset);
    this.camera.lookAt(this.target.position);
  }
}

Input Handling

class InputManager {
  constructor() {
    this.keys = {};
    this.mouse = { x: 0, y: 0, buttons: {} };

    window.addEventListener('keydown', (e) => this.keys[e.code] = true);
    window.addEventListener('keyup', (e) => this.keys[e.code] = false);
    window.addEventListener('mousemove', (e) => {
      this.mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
      this.mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
    });
  }

  getInput() {
    return {
      forward: this.keys['KeyW'] || this.keys['ArrowUp'],
      backward: this.keys['KeyS'] || this.keys['ArrowDown'],
      left: this.keys['KeyA'] || this.keys['ArrowLeft'],
      right: this.keys['KeyD'] || this.keys['ArrowRight'],
      jump: this.keys['Space'],
      action: this.keys['KeyE'],
      rotateLeft: this.keys['KeyQ'],
      rotateRight: this.keys['KeyE']
    };
  }
}

Collision Detection (Raycasting)

function checkCollisions(player, obstacles) {
  const raycaster = new THREE.Raycaster();
  const directions = [
    new THREE.Vector3(1, 0, 0),   // right
    new THREE.Vector3(-1, 0, 0),  // left
    new THREE.Vector3(0, 0, 1),   // forward
    new THREE.Vector3(0, 0, -1),  // backward
  ];

  for (const direction of directions) {
    raycaster.set(player.position, direction);
    const intersects = raycaster.intersectObjects(obstacles);

    if (intersects.length > 0 && intersects[0].distance < 1.0) {
      return {
        collision: true,
        object: intersects[0].object,
        distance: intersects[0].distance,
        point: intersects[0].point
      };
    }
  }

  return { collision: false };
}

Loading 3D Models (GLTF)

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();

function loadCharacter(path) {
  return new Promise((resolve, reject) => {
    loader.load(
      path,
      (gltf) => {
        const model = gltf.scene;
        model.scale.set(1, 1, 1);
        scene.add(model);

        // Setup animations if available
        const mixer = new THREE.AnimationMixer(model);
        const animations = {};
        gltf.animations.forEach(clip => {
          animations[clip.name] = mixer.clipAction(clip);
        });

        resolve({ model, mixer, animations });
      },
      (progress) => {
        console.log(`Loading: ${(progress.loaded / progress.total * 100).toFixed(2)}%`);
      },
      (error) => reject(error)
    );
  });
}

// Usage
const character = await loadCharacter('/models/character.glb');
character.animations.idle.play();

Basic Physics (Gravity & Jumping)

class PhysicsBody {
  constructor(mesh) {
    this.mesh = mesh;
    this.velocity = new THREE.Vector3();
    this.onGround = false;
    this.gravity = -9.8;
    this.jumpPower = 5;
  }

  update(deltaTime) {
    // Apply gravity
    if (!this.onGround) {
      this.velocity.y += this.gravity * deltaTime;
    }

    // Apply velocity
    this.mesh.position.add(this.velocity.clone().multiplyScalar(deltaTime));

    // Ground check
    if (this.mesh.position.y <= 0) {
      this.mesh.position.y = 0;
      this.velocity.y = 0;
      this.onGround = true;
    }
  }

  jump() {
    if (this.onGround) {
      this.velocity.y = this.jumpPower;
      this.onGround = false;
    }
  }
}

Interactive Objects (Picking)

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

function onMouseClick(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(interactableObjects);

  if (intersects.length > 0) {
    const object = intersects[0].object;
    object.userData.onInteract?.();
  }
}

window.addEventListener('click', onMouseClick);

Health & Damage System

class Entity {
  constructor(mesh, maxHealth) {
    this.mesh = mesh;
    this.maxHealth = maxHealth;
    this.health = maxHealth;
    this.isDead = false;
  }

  takeDamage(amount) {
    if (this.isDead) return;

    this.health = Math.max(0, this.health - amount);

    if (this.health === 0) {
      this.die();
    }

    return this.health;
  }

  heal(amount) {
    this.health = Math.min(this.maxHealth, this.health + amount);
    return this.health;
  }

  die() {
    this.isDead = true;
    this.mesh.visible = false;
    // Trigger death animation, effects, etc.
  }
}

Key Concepts

Scene Graph

  • Organize game objects hierarchically
  • Use groups for complex objects
  • Parent-child transformations

Game Loop

  • Use requestAnimationFrame for 60fps
  • Calculate delta time for frame-independent movement
  • Separate update logic from rendering

Camera Systems

  • PerspectiveCamera: First/third-person games
  • OrthographicCamera: 2D/isometric games
  • Implement camera follow and smooth transitions

Lighting

  • AmbientLight: Base illumination
  • DirectionalLight: Sun/moonlight with shadows
  • PointLight: Torches, explosions
  • SpotLight: Flashlights, stage lights

Performance Optimization

  • Use instancing for repeated objects
  • Implement frustum culling
  • Use LOD (Level of Detail) for distant objects
  • Minimize draw calls
  • Use texture atlases
  • Enable shadow map optimization

Asset Loading

  • Preload all assets before game start
  • Show loading progress bar
  • Use LoadingManager for coordination
  • Cache loaded assets

Common Game Patterns

State Machine (Game States)

class GameStateMachine {
  constructor() {
    this.states = {
      menu: new MenuState(),
      playing: new PlayingState(),
      paused: new PausedState(),
      gameOver: new GameOverState()
    };
    this.currentState = this.states.menu;
  }

  changeState(stateName) {
    this.currentState.exit();
    this.currentState = this.states[stateName];
    this.currentState.enter();
  }

  update(deltaTime) {
    this.currentState.update(deltaTime);
  }
}

Object Pooling

class ObjectPool {
  constructor(factory, initialSize = 10) {
    this.factory = factory;
    this.available = [];
    this.inUse = [];

    for (let i = 0; i < initialSize; i++) {
      this.available.push(factory());
    }
  }

  acquire() {
    let obj = this.available.pop();
    if (!obj) obj = this.factory();
    this.inUse.push(obj);
    return obj;
  }

  release(obj) {
    const index = this.inUse.indexOf(obj);
    if (index > -1) {
      this.inUse.splice(index, 1);
      this.available.push(obj);
    }
  }
}

// Usage
const bulletPool = new ObjectPool(() => createBullet(), 20);
const bullet = bulletPool.acquire();
// ... use bullet
bulletPool.release(bullet);

Reference Files

Detailed documentation organized by topic:

  • getting_started.md - Three.js fundamentals, setup, and basic concepts
  • game_development.md - Game loop, player controllers, game mechanics
  • scene_graph.md - Scene organization, hierarchy, transformations
  • materials.md - Material types, shaders, visual effects
  • textures.md - Texture loading, UV mapping, atlases
  • lighting.md - Light types, shadows, HDR
  • cameras.md - Camera types, controls, viewport management
  • geometry.md - Built-in geometries, custom geometry, buffers
  • loading.md - Asset loading (models, textures, audio)
  • animation.md - Animation system, skeletal animation, tweens
  • interactivity.md - Raycasting, picking, UI integration
  • effects.md - Post-processing, particles, fog

Resources

Official Documentation

  • Three.js Manual: https://threejs.org/manual/
  • Three.js API: https://threejs.org/docs/
  • Three.js Examples: https://threejs.org/examples/

Physics Integration

  • Cannon.js: Lightweight 3D physics
  • Ammo.js: Full Bullet physics engine port
  • Rapier: High-performance physics

Useful Libraries

  • three-mesh-bvh: Fast raycasting
  • three-pathfinding: Navigation meshes
  • postprocessing: Advanced effects

Working with This Skill

For Beginners

1. Start with basic scene setup 2. Learn the coordinate system 3. Understand the game loop 4. Practice with simple shapes before models

For Game Development

1. Plan your game architecture 2. Implement input handling first 3. Build a simple player controller 4. Add gameplay mechanics incrementally 5. Optimize performance throughout

For Advanced Features

1. Integrate physics engines 2. Implement advanced shaders 3. Add post-processing effects 4. Build multiplayer networking

Notes

  • Three.js uses a right-handed coordinate system (X right, Y up, Z out)
  • Optimize early: profile regularly, minimize draw calls
  • Use development builds for debugging, production builds for release
  • Consider WebGL 2 features for modern browsers
  • Mobile performance requires careful optimization

Related skills

How it compares

Pick threejs-game for WebGL browser games in JavaScript; pick native mobile game skills when the target is App Store GPU performance rather than canvas WebGL.

FAQ

What does threejs-game build?

threejs-game scaffolds browser-based 3D games using Three.js and WebGL, including scenes, render loops, mesh loading, lighting, and input handlers deployable as web bundles.

When should developers use threejs-game?

threejs-game fits JavaScript developers who need lightweight 3D browser prototypes or gamified WebGL modules without adopting Unity, Unreal, or native mobile game engines.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.