Awesome-omni-skill threejs-game
Three.js game development. Use for 3D web games, WebGL rendering, game mechanics, physics integration, character controllers, camera systems, lighting, animations, and interactive 3D experiences in the browser.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/threejs-game" ~/.claude/skills/diegosouzapw-awesome-omni-skill-threejs-game && rm -rf "$T"
manifest:
skills/development/threejs-game/SKILL.mdsource content
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
for 60fpsrequestAnimationFrame - 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
- 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