How to make a cozy walking game in three.js with AI
Short answer: set up a Vite project with three.js, let an AI coding agent (Claude Code, Codex or Cursor) write the code one feature at a time, build a little meadow from free CC0 models (Kenney, Quaternius, Poly Haven), give your character a free walk and idle animation from Mixamo, add a follow camera and a calm ambient loop, then upload the build to itch.io as an HTML game. Everything here is free except, possibly, the coding agent. Checked Oct 26, 2026.
What you will build
A tiny cozy walking game: one character, one pretty place, no enemies and no way to lose. The player walks around a meadow with trees and rocks, the camera follows gently, soft music plays, and maybe there are a few lanterns to find. It is small on purpose. A walking game skips the hardest parts of game design, so your first 3D game actually gets finished.
New to three.js? Read How to make a browser game with three.js and AI first. It covers picking an agent, the general Vite setup and hosting options. This guide is the next step: a complete little game that ties together free models, AI 3D tools, Mixamo animation and publishing.
What you need (all free)
- three.js: the free, open source (MIT) 3D library. The latest release when we checked on Oct 26, 2026 was r186 (npm package
three0.186.1), the same version our code sample was tested with. - Node.js and Vite: Vite runs the dev server and builds the game. Our test used Vite 8.3.5, which needs Node.js 20.19+ or 22.12+ according to the Vite guide.
- An AI coding agent: Cursor has a limited free plan and ChatGPT Free includes limited Codex access. Claude Code needs a paid Claude plan (Pro is $20/mo, checked Oct 25, 2026). See Claude Code vs Codex vs Cursor for game dev.
- Blender: free and open source, used once to combine your animations into one file.
- A free Adobe ID for Mixamo, and a free itch.io account to publish.
three.js
Free, open source (MIT) JavaScript 3D library for WebGL and WebGPU that runs games and scenes directly in the browser.
Pricing: Free. Beginner rating: 3/5. A code library, not an editor, but AI coding agents write three.js well and you test in any browser.
Free, runs in any modern browser, and AI agents write it well.
Step 1: Set up the project and agent notes
Install Node.js, then run these commands from the Vite guide and the three.js installation manual:
npm create vite@latest cozy-walk -- --template vanilla
cd cozy-walk
npm install
npm install three
npm run dev Add a vite.config.js so asset paths stay relative. itch.io serves your game from a subfolder, and paths that start with / break there:
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
base: './', // relative paths so the build works on itch.io
}); Then give your agent a short notes file. Claude Code reads CLAUDE.md, Codex reads AGENTS.md, and Cursor supports project rules. The notes keep the agent on the right three.js version and stop it from adding random frameworks:
# Cozy walking game: project notes
- Stack: Vite (vanilla JavaScript) + three.js (npm "three" 0.186.1, release r186).
- Import addons from 'three/addons/...'. Use THREE.Timer, not THREE.Clock (deprecated since r183).
- Game code lives in src/main.js. Models in public/models/, sounds in public/sounds/.
- Load assets with relative paths like './models/player.glb' (the game ships to itch.io).
- player.glb has two animation clips named "Idle" and "Walk".
- Mood: calm and cozy. No enemies, no timer, no game over.
- One feature per change. Do not add frameworks or npm packages without asking.
- Run: npm run dev. Build: npm run build (outputs dist/). Step 2: Build the world from free CC0 models
Free model kits give you a matching art style in minutes. We checked each license on the official site on Oct 26, 2026:
- Kenney: Kenney's support page says all assets on its asset pages are public domain (CC0), commercial use is fine and credit is not required. We downloaded the Nature Kit (330 assets): it has a
Models/GLTF formatfolder with 329.glbfiles (trees, rocks, paths, tents and more) that load straight into three.js. Kenney also has free CC0 audio packs. - Quaternius: Quaternius's FAQ says all models are CC0, free for commercial, educational and personal projects without credit, and you can modify them. File formats vary by pack, so check each pack for glTF or GLB. Many packs include animated characters.
- Poly Haven: every asset is CC0, per its license page. Models download as
.gltfwith separate texture files rather than one.glb. GLTFLoader loads both, just keep the textures next to the.gltffile. Poly Haven models are realistic and heavier, so use them sparingly in a low poly scene. - Poly Pizza: not all CC0. Each model shows its own license. The ones we checked were either Public Domain (CC0) or CC-BY 3.0, which needs credit, and Poly Pizza's terms say you follow the Creative Commons license shown at download time. Many models offer glTF. Keep a
CREDITS.txtfor anything that is not CC0.
Copy the files you want into public/models/, then ask the agent to place them. A good first prompt:
Load trees and rocks from public/models with GLTFLoader and scatter about 40 of them randomly on the ground plane, at least 3 units from the center so the player starts in a clearing. Use a fixed random seed so the layout is the same every time. Keep the total under 60 models.
Kenney
Thousands of free 2D and 3D game assets, UI and audio packs. Kenney states all assets on its asset pages are public domain (CC0), commercial use allowed, attribution not required.
Pricing: Free. Beginner rating: 5/5. Consistent style, no sign up, and the CC0 license means nothing to track.
CC0 kits with ready GLB files and a consistent, cozy low poly style.
Quaternius
Free low poly 3D model packs, many rigged and animated. Quaternius says its assets are CC0, usable in commercial projects without credit and modifiable in any way.
Pricing: Free. Beginner rating: 5/5. Ready made themed packs with a matching style and no license strings.
CC0 low poly nature packs and animated characters.
More libraries are in free game assets for beginners. For a sky, our skybox and game level guide covers free CC0 HDRIs.
Step 3 (optional): Add a few AI generated props
Want one special object no kit has, like a mossy shrine or a crooked mailbox? Generate it with an AI 3D tool, but read the free plan rules first. From each official pricing page, checked Oct 26, 2026:
- Meshy Free: 100 credits a month, no credit card. The plan comparison lists 10 Meshy 6 Lite model downloads a month on Free. Free outputs are CC BY 4.0, which Meshy describes as commercial use with attribution, so credit Meshy on your game page. Meshy's downloads include
.glb. - Tripo Free: 200 credits a month, which Tripo says is about 13 models, with limited exports. Free models are public and for non-commercial use only. Fine for practice, but do not ship them in a game you sell or take donations for.
AI models are often heavy and oddly scaled. Ask your agent: Log the bounding box size of each loaded model and scale it so trees are about 4 units tall and props about 1 unit. If a model has far too many triangles, Blender's Decimate modifier reduces them. Full comparison: Best free AI 3D model generators for game assets and Meshy vs Tripo.
Step 4: Give your character a walk and idle animation
You need a humanoid character in a neutral pose (a T-pose or A-pose works best). Use one from a free CC0 kit, or generate one with an AI tool whose free plan allows your use. Then:
- Rig it in Mixamo. Adobe's Mixamo FAQ (checked Oct 26, 2026) says Mixamo is free with an Adobe ID, with no Creative Cloud subscription, and its characters and animations are royalty free for personal, commercial and non-profit projects, including video games. The auto rigger only works on bipedal humanoids, and Mixamo only keeps your last character, so save the rigged one to your computer.
- Download two clips. Pick an idle animation and a walk animation and download each one as FBX. For the walk, tick In Place if the clip offers it, so the character walks on the spot and your code does the moving. Download options are not listed on Adobe's help pages, so the option names here are unverified.
- Combine them in Blender. Import both FBX files (File, Import, FBX). Each clip comes in as an Action. Rename the actions
IdleandWalk, make sure both belong to the same armature (push each one down to an NLA track or stash it, because Blender's glTF exporter only exports actions linked to an object), and delete the extra imported character. - Export one GLB. File, Export, glTF 2.0, and choose glTF Binary (.glb). Save it as
public/models/player.glb.
Stuck? How to animate a 3D character for free goes deeper on Mixamo, free AI motion capture and Blender, and Mixamo vs Cascadeur compares the two free animation tools.
Mixamo
Free Adobe service that auto rigs characters and applies ready made animations.
Pricing: Free. Beginner rating: 5/5. Free, drag and drop rigging and animations.
Free auto rigging and a big animation library for humanoids, royalty free in games.
Step 5: Movement, animation and a third person camera
This is the whole game loop in one file. Put it in src/main.js, and replace the template's index.html body with just <script type="module" src="/src/main.js"></script>. It loads player.glb, plays Idle or Walk depending on whether you are moving, turns the character to face where it walks, eases the camera behind it, and loops an ambient track after your first click or key press.
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// Scene: soft sky color, fog and warm light for a cozy look
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xbfd8e8);
scene.fog = new THREE.Fog(0xbfd8e8, 15, 60);
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 200);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.HemisphereLight(0xfff4e0, 0x6b8f5a, 2));
const sun = new THREE.DirectionalLight(0xffe2b0, 2);
sun.position.set(10, 20, 5);
scene.add(sun);
const ground = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), new THREE.MeshStandardMaterial({ color: 0x8fbf6a }));
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
// Player: a GLB with "Idle" and "Walk" clips (see Step 4)
const player = new THREE.Group();
scene.add(player);
let mixer, idle, walk, current;
new GLTFLoader().load('./models/player.glb', (gltf) => {
player.add(gltf.scene);
mixer = new THREE.AnimationMixer(gltf.scene);
console.log('Clips:', gltf.animations.map((c) => c.name));
idle = mixer.clipAction(THREE.AnimationClip.findByName(gltf.animations, 'Idle'));
walk = mixer.clipAction(THREE.AnimationClip.findByName(gltf.animations, 'Walk'));
current = idle;
idle.play();
}, undefined, (err) => console.error('Model failed to load', err));
function playClip(next) {
if (!next || next === current) return;
next.reset().play();
current.crossFadeTo(next, 0.25, false);
current = next;
}
// Input: WASD or arrow keys
const keys = {};
addEventListener('keydown', (e) => { keys[e.code] = true; startMusic(); });
addEventListener('keyup', (e) => { keys[e.code] = false; });
// Ambient loop: browsers only allow sound after the player clicks or presses a key
const listener = new THREE.AudioListener();
camera.add(listener);
const music = new THREE.Audio(listener);
new THREE.AudioLoader().load('./sounds/ambient.mp3', (buffer) => {
music.setBuffer(buffer);
music.setLoop(true);
music.setVolume(0.4);
});
function startMusic() {
if (music.buffer && !music.isPlaying) music.play();
}
addEventListener('pointerdown', startMusic);
// Third person camera: sits behind and above the player and eases toward that spot
const camOffset = new THREE.Vector3(0, 3, -6);
const camTarget = new THREE.Vector3();
const move = new THREE.Vector3();
const timer = new THREE.Timer();
timer.connect(document);
renderer.setAnimationLoop((time) => {
timer.update(time);
const dt = Math.min(timer.getDelta(), 0.1);
move.set(0, 0, 0);
if (keys.KeyW || keys.ArrowUp) move.z += 1;
if (keys.KeyS || keys.ArrowDown) move.z -= 1;
if (keys.KeyA || keys.ArrowLeft) move.x += 1;
if (keys.KeyD || keys.ArrowRight) move.x -= 1;
if (move.lengthSq() > 0) {
move.normalize().multiplyScalar(3 * dt); // walking speed: 3 units per second
player.position.add(move);
player.rotation.y = Math.atan2(move.x, move.z); // face the way you walk
playClip(walk);
} else {
playClip(idle);
}
if (mixer) mixer.update(dt);
camTarget.copy(player.position).add(camOffset);
camera.position.lerp(camTarget, 1 - Math.exp(-5 * dt));
camera.lookAt(player.position.x, player.position.y + 1, player.position.z);
renderer.render(scene, camera);
});
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
}); Tested: we built this exact file with Vite 8.3.5 and three 0.186.1 on Oct 26, 2026, ran the build in headless Chromium, and held W and A. The test model (a placeholder box with clips named Idle and Walk) turned, walked and switched clips, the camera followed, and the page threw no errors. We did not listen to the audio in the test, and we did not test it with a real Mixamo export.
How it works, briefly:
- AnimationMixer plays the clips. The three.js docs say to call
updateevery frame with the time since the last frame, fromClockorTimer.Clockis marked deprecated since r183, so the sample usesTHREE.Timer. - crossFadeTo blends Idle and Walk over a quarter second so the switch is smooth.
- The camera moves a fraction of the way to its target spot every frame, which feels soft and floaty, a good fit for a cozy game.
- If your clips are not called Idle and Walk, the console prints their real names. Use those, or rename them in Blender.
Step 6: Ambient sound
Sound does most of the cozy work. Put a looping track (birds, wind, soft music) in public/sounds/ambient.mp3. The sample uses three.js's AudioListener and Audio, and starts playback on the first click or key press because browsers block sound until the player interacts with the page. For sounds that get louder as you walk closer, like a stream or a campfire, ask for PositionalAudio attached to an object.
Where to get sounds for free: Kenney's CC0 audio packs, or AI music and sound tools. Check each tool's free plan for commercial use in Best free AI tools for game sound effects and music.
Step 7: Cozy polish, one prompt at a time
Ask for one change, play it, keep it or undo it. Prompts that work well for this kind of game:
- Stop the player walking through trees and rocks. Give each one a simple circle collider and push the player out of it.
- Add 5 glowing lanterns hidden around the map. When the player walks near one, it lights up and a small counter shows 1 of 5. When all 5 are lit, show "Thanks for walking" and keep the game running.
- Let me rotate the camera around the player by dragging with the mouse, and make W always walk away from the camera.
- Add a slow day to dusk cycle over 5 minutes: change the sky color, fog color and sun color together.
- Add soft footstep sounds from public/sounds that play in time with the Walk animation.
When something breaks, open the browser console (F12), copy the red error and paste it to the agent with what you were doing. That one habit fixes most problems.
Step 8: Publish free on itch.io
- Run
npm run build. Check it withnpm run preview. - Zip the contents of
dist/, soindex.htmlsits inside the ZIP. File names are case sensitive on itch.io, soPlayer.glbandplayer.glbare different files. - On itch.io, click Create new game, pick HTML Game as the kind of game, upload the ZIP, set a viewport size, and fill in the Generative AI disclosure if any art, sound or code came from AI.
- Preview the private page, play it there, then set it to Public.
Our step by step guide How to publish your first game on itch.io covers the page, pricing and AI disclosure in detail. Put your credits (Meshy, any CC-BY Poly Pizza models) in the page description.
Common pitfalls
- Old tutorial code. Older examples import from
three/examples/jsm/...and useTHREE.Clock. Current docs usethree/addons/..., and Clock is deprecated since r183. - Character sliding forward on its own. The walk clip has root motion. Download it In Place, if offered.
- Only one animation in the GLB. Blender exported just the active action. Push both actions to NLA tracks or stash them, then export again.
- Black or missing model on itch.io. An absolute path like
/models/player.glb. Use./models/player.glbandbase: './'. - Slow loading. Too many or too heavy models. Prefer low poly kits and keep AI models small.
What we could not verify
- Mixamo's download formats and options are not listed on Adobe's help pages. FBX download is described on Cascadeur's Mixamo help page, not Adobe's, and the In Place option is unverified.
- We did not run the Blender steps or test a real Mixamo export in the code sample, only a placeholder model with Idle and Walk clips.
- We did not check the commercial terms of every individual Poly Pizza or Quaternius pack. Read the license shown on each one.
- Coding agent prices come from our directory entries, checked Oct 2026, not rechecked for this guide.
Sources (checked Oct 26, 2026)
- three.js AnimationMixer, Timer, Clock and PositionalAudio docs, and three on npm
- Kenney support (license), Quaternius FAQ, Poly Haven license and Poly Pizza terms
- Meshy pricing and Tripo pricing
- Adobe Mixamo FAQ
- itch.io: Uploading HTML5 games
FAQ
What is a cozy walking game?
A small, calm game where the fun is moving through a pretty place: no enemies, no timer, no way to lose. You walk, look around, maybe find a few things. It is a great first 3D project because the hard parts of game design (balance, difficulty, combat) mostly disappear, and you can finish it in a weekend or two.
Can I make this with no money?
Yes. three.js, Vite, Node.js, Blender, Mixamo (with a free Adobe ID), the Kenney, Quaternius and Poly Haven libraries and an itch.io page are all free. The only part that can cost money is the AI coding agent. Cursor has a limited free plan and ChatGPT Free includes limited Codex access, while Claude Code needs a paid Claude plan (Pro is $20/mo, checked Oct 25, 2026).
Can I use free AI generated models in a game on itch.io?
It depends on the tool. Meshy's pricing page (checked Oct 26, 2026) says free plan outputs are CC BY 4.0, so you can use them, even commercially, if you credit Meshy. Tripo's pricing page lists its free plan as public models and non-commercial use, so do not use free Tripo models in a game you sell or take donations for. Fill in itch.io's Generative AI disclosure either way.
How do I get a Mixamo animation into three.js?
Rig your humanoid character in Mixamo, download an idle clip and a walk clip, import both FBX files into Blender, give the actions clear names like Idle and Walk, and export one glTF Binary (.glb) file. three.js loads it with GLTFLoader and plays each clip through an AnimationMixer. three.js also has an FBXLoader if you want to skip Blender, but one GLB is simpler to manage.
Why does my character slide or walk away from the camera on its own?
The walk clip probably moves the character forward by itself (root motion) while your code also moves it. If Mixamo offers an In Place option for the walk clip, tick it before downloading, so the character walks on the spot and only your code moves it. Adobe's help pages do not document Mixamo's download options, so treat this as unverified.
Why is there no sound when my game starts?
Browsers block audio until the player interacts with the page. Start your ambient loop on the first click or key press, as the code sample on this page does.
How is this different from your other three.js guide?
Our guide How to make a browser game with three.js and AI covers the general setup: Vite, picking an agent, loading a single GLB and hosting. This guide builds one specific game on top of that: a world made from free CC0 kits, an animated character from Mixamo, a third person camera and ambient sound, then publishing on itch.io.
