threejs-game

Three.js Game Development Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "threejs-game" with this command: npx skills add natea/fitfinder/natea-fitfinder-threejs-game

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

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

  • Start with basic scene setup

  • Learn the coordinate system

  • Understand the game loop

  • Practice with simple shapes before models

For Game Development

  • Plan your game architecture

  • Implement input handling first

  • Build a simple player controller

  • Add gameplay mechanics incrementally

  • Optimize performance throughout

For Advanced Features

  • Integrate physics engines

  • Implement advanced shaders

  • Add post-processing effects

  • 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

pair programming

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-multi-repo

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-release-management

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-code-review

No summary provided by upstream source.

Repository SourceNeeds Review