Template·three·v1.0.0·ISC
Rock Em Sock Em
Rock Em Sock Em — a Three.js starter mirrored from OpusGameLabs/game-creator.
#template#three#rock#em#sock#em
Preview
Edit on StackBlitzInstall
npx create-gamecn my-game --template rock-em-sock-emSource preview
Compatibility
| Engines | three >=0.160.0 |
| Frameworks | vanilla |
| Languages | javascript |
| Bundlers | vite |
| Platforms | web, mobile-web |
Files installed
- .gitignore
- design-brief.md(docs)
- index.html
- package.json
- progress.md(docs)
- public/assets/models/blue-bomber-rigged.glb(asset)
- public/assets/models/blue-bomber-rigged.meta.json
- public/assets/models/blue-bomber-run.glb(asset)
- public/assets/models/blue-bomber-walk.glb(asset)
- public/assets/models/blue-bomber.glb(asset)
- public/assets/models/blue-bomber.meta.json
- public/assets/models/boxing-ring.glb(asset)
- public/assets/models/boxing-ring.meta.json
- public/assets/models/red-rocker-rigged.glb(asset)
- public/assets/models/red-rocker-rigged.meta.json
- public/assets/models/red-rocker-run.glb(asset)
- public/assets/models/red-rocker-walk.glb(asset)
- public/assets/models/red-rocker.glb(asset)
- public/assets/models/red-rocker.meta.json
- src/core/Constants.js
- src/core/EventBus.js
- src/core/Game.js
- src/core/GameState.js
- src/entities/HealthBar.js
- src/entities/Robot.js
- src/level/AssetLoader.js
- src/level/LevelBuilder.js
- src/main.js
- src/systems/AISystem.js
- src/systems/AnimationSystem.js
- src/systems/CombatSystem.js
- src/systems/InputSystem.js
- src/ui/Menu.js
- vite.config.js
- gamecn.json
Notes
Concept
A 3D boxing game inspired by the classic Mattel toy. Two robots face each other in a boxing ring. The player controls the Blue Bomber; the Red Rocker is AI-controlled. Each robot can throw left and right punches, and block. Each hit to the opponent's head raises their head mechanism slightly. After enough hits, the opponent's head pops up and the round is won.
Core Mechanics
Punching
- Two punch types: left (A key / left tap) and right (D key / right tap)
- Punches have a short wind-up animation (0.25s) with hit detection at the midpoint
- Cooldown between punches (0.4s) prevents button mashing
- Cannot punch while blocking
Blocking
- Hold W / Up Arrow, or tap the top 30% of screen on mobile
- Reduces incoming damage by 75% (from 12 to 3)
- Cannot punch while blocking (must release block first)
Head Health
- Each robot has 100 head health points
- Unblocked punch deals 12 damage
- Blocked punch deals 3 damage
- When health reaches 0, the head pops upward (knockout animation)
Combo System
- Consecutive unblocked hits within 1.5s build a combo
- Combo counter resets on miss or getting hit
- Tracks best combo across rounds
- Spectacle events fire at combo >= 3
Win/Lose Conditions
Win (Round)
- Reduce opponent's head health to 0
- Opponent's head pops up = round won
- Score increments by 1
- After 2-second delay, new round starts with full health
Lose (Game Over)
- Player's head health reaches 0
- Player's head pops up = knocked out
- Game over screen shows rounds won and best score
- Restart button begins fresh game
Entity Interactions
Blue Bomber (Player)
- Positioned at +Z in the ring (closer to camera)
- Faces -Z (toward opponent)
- Controlled by keyboard (A/D/W) and touch zones
- Blue body (#2266cc), darker blue accents (#1a4f99), blue gloves (#3388ee)
- Stocky robot built from Box, Cylinder, and Sphere geometries
Red Rocker (AI Opponent)
- Positioned at -Z in the ring (far side)
- Faces +Z (toward player)
- AI-controlled with timing patterns
- Red body (#cc2222), darker red accents (#991a1a), red gloves (#ee3333)
- Same stocky robot build as Blue Bomber, mirrored
- AI becomes slightly more aggressive as player wins more rounds
Boxing Ring
- Raised platform (6x6 units) with brown base and light canvas surface
- Four corner posts with colored turnbuckle caps (alternating red/blue)
- Three rows of white ropes on each side
- Dark arena floor surrounding the ring
Health Bars
- 3D floating bars above each robot's head
- Green for player, orange for opponent
- Turns red below 30% health
- Billboarded to always face the camera
Visual Identity
Arena Atmosphere
- Dark background (#1a1a2e) — arena/stadium feel
- Overhead spotlight illuminating the ring
- Colored rim lights: blue glow behind player, red glow behind opponent
- Directional light for shadows
Robots
- Stocky, toy-like proportions (wide body, big head, round gloves)
- Built entirely from Three.js primitives (no external models needed initially)
- Clear color distinction: all-blue vs all-red
- Eyes with white sclera and dark pupils for personality
- Chest plate accent in lighter shade for visual interest
- Head sits on a "spring" (gap between head and body) for the pop-up mechanic
Camera
- Fixed third-person view behind the player
- Positioned slightly above and behind (y: 3.5, z: 4.5)
- Looking slightly down at the action (y: 1.8, z: -1.0)
- No orbit controls — static framing for clarity
Animations
- Idle: subtle body bob
- Punch: glove extends forward on sine curve, slight upward arc
- Block: both arms raise to protect head, move inward
- Head pop: head group translates upward 0.6 units (spring mechanism)
Controls
Desktop
| Key | Action |
|---|---|
| A / Left Arrow | Left punch |
| D / Right Arrow | Right punch |
| W / Up Arrow | Block (hold) |
Mobile (Touch)
| Zone | Action |
|---|---|
| Left half of screen (bottom 70%) | Left punch |
| Right half of screen (bottom 70%) | Right punch |
| Top 30% of screen | Block (hold) |
Technical Notes
- Engine: Three.js (WebGLRenderer)
- No external model files — robots built from primitives
- EventBus architecture — all systems communicate via events
- GameState singleton tracks all combat state
- Constants.js holds every configuration value
- Restart-safe: full cleanup on reset, new robot groups created each round
- Mobile-first: touch input wired from the start
- Safe zone: HTML overlays respect 75px Play.fun widget at top
Game Concept
- Name: rock-em-sock-em
- Engine: Three.js
- Description: Rock 'Em Sock 'Em Robots — 3D boxing game. Blue Bomber vs Red Rocker in a ring. Punch to knock opponent's head up.
Step 1: Scaffold
- Entities: Robot.js (builds both Blue Bomber + Red Rocker from primitives), HealthBar.js
- Systems: InputSystem.js, CombatSystem.js, AISystem.js, AnimationSystem.js
- Events: game:start/over/restart, round:won/reset, player:punchLeft/Right/blockStart/End, opponent:punchLeft/Right/blockStart/End, hit:player/opponent, headPop:player/opponent, score:changed, spectacle:entrance/action/hit/combo
- Constants keys: RING, ROBOT, COMBAT, AI, CAMERA, COLORS, HEALTH_BAR
- Scoring: rounds won by player (knocking opponent's head up)
- Fail condition: AI knocks player's head up (head health reaches 0)
- Input: A/Left = left punch, D/Right = right punch, W/Up = block, touch zones
Step 1.5: 3D Assets
- Source: Meshy AI (text-to-3d) — 3 static GLB models in
public/assets/models/ - Models:
blue-bomber.glb(17 MB) — Blue Bomber player robot, static mesh, PBR texturesred-rocker.glb(24 MB) — Red Rocker opponent robot, static mesh, PBR texturesboxing-ring.glb(11 MB) — Boxing ring platform with ropes
- Integration approach: GLB models loaded via AssetLoader.js
loadModel()(regular.clone(true), not SkeletonUtils — these are static, not rigged) - Animation: Models are NOT skeletal/rigged. Existing AnimationSystem.js programmatic animations (punch lunge, block tilt, head pop, idle bob) adapted to animate the whole GLB model as a single unit via a wrapper group pattern
- Wrapper group pattern: Each GLB model is wrapped in a
THREE.Groupthat starts at position (0,0,0). AnimationSystem targets the wrapper for position/rotation offsets. The actual model retains its centering transform inside the wrapper. - Fallback: Every GLB load is wrapped in try/catch. On failure, the original primitive geometry (BoxGeometry, CylinderGeometry, SphereGeometry) is built as fallback
- Preloading: All 3 models preloaded via
preloadAll()in Game.js before game starts. Render loop runs immediately but game logic waits forthis.readyflag - Constants: Added
MODELSconfig to Constants.js with path, scale, rotationY for each model - Files changed:
src/core/Constants.js— Added MODELS configsrc/entities/Robot.js— Now async, loads GLB with wrapper group, keeps primitive fallbacksrc/level/LevelBuilder.js— Now async viabuild()method, loads boxing ring GLB, keeps primitive fallbacksrc/systems/AnimationSystem.js— Dual-path animations: GLB (whole-model lunge/tilt/pop) vs primitives (per-part glove/arm/head)src/core/Game.js— Preloads all models on startup, async init/createRobots, ready flag for render loopsrc/level/AssetLoader.js— Unchanged (already had loadModel + preloadAll)
Decisions / Known Issues
- Robots now use Meshy AI GLB models with primitive fallback
- Camera is fixed behind player, no OrbitControls
- AI uses timing-based patterns with configurable aggression
- GLB models are static (no skeleton) — all animation is programmatic via wrapper group transforms
- Model scale values (1.0 for robots, 1.5 for ring) may need tuning after visual review
- Large model files (17-24 MB) — acceptable for prototype, could be optimized later with mesh decimation
Related
- 3D Asset TestTemplate
3D Asset Test — a Three.js starter mirrored from OpusGameLabs/game-creator.
- Castle SiegeTemplate
Castle Siege — a Three.js starter mirrored from OpusGameLabs/game-creator.
- Crowd DashTemplate
Crowd Dash — a Three.js starter mirrored from OpusGameLabs/game-creator.
- Flappy Bird 3DTemplate
Flappy Bird 3D — a Three.js starter mirrored from OpusGameLabs/game-creator.