# 🎮 KICKSTARTER DEMO - COMPLETE IMPLEMENTATION GUIDE **Target:** First Playable Demo **Timeline:** 3-5 days (6-8 work hours) **Status:** Assets 100% ready! ✅ **Last Updated:** Dec 30, 2025 21:35 --- ## 📋 **PREREQUISITES (ALREADY DONE!)** ✅ 99 PNG assets generated (dual style A + B) ✅ Background removal complete (transparent PNGs) ✅ DEMO_MAP_PLAN.md created (8×8 layout spec) ✅ PRIORITY_TRACKER.csv complete ✅ Git commit ready **Current Progress:** 10% (assets ready, code not started) --- ## 🗓️ **3-DAY IMPLEMENTATION TIMELINE** ### **DAY 1: TILED MAP + ASSET LOADING** (3 hours) - ⏳ Task 1: Build Tiled map (2 hours) - ⏳ Task 2: Phaser asset loading (1 hour) ### **DAY 2: ANIMATIONS + MOVEMENT** (4 hours) - ⏳ Task 3: Create animations (1.5 hours) - ⏳ Task 4: Player controls (1.5 hours) - ⏳ Task 5: Camera & collision (1 hour) ### **DAY 3: GAMEPLAY + POLISH** (3 hours) - ⏳ Task 6: Farming mechanics (1.5 hours) - ⏳ Task 7: UI implementation (1 hour) - ⏳ Task 8: Demo script (30 min) **TOTAL:** 10 hours → **FIRST PLAYABLE DEMO!** 🎉 --- # 📅 DAY 1: TILED MAP + ASSET LOADING --- ## 🗺️ **TASK 1: BUILD TILED MAP** (2 hours) ### **Step 1.1: Open Tiled Editor** (5 min) **Check if Tiled is installed:** ```bash which tiled # If not found: brew install tiled ``` **Launch Tiled:** ```bash tiled & # OR use Applications → Tiled ``` --- ### **Step 1.2: Create New Map** (10 min) **In Tiled:** 1. File → New → New Map 2. Settings: - **Orientation:** Orthogonal - **Tile layer format:** CSV - **Tile render order:** Right Down - **Map size:** 8 × 8 tiles - **Tile size:** 64 × 64 pixels 3. Save as: `maps/demo_micro_farm.tmx` **Result:** Empty 512×512px map --- ### **Step 1.3: Create Tilesets** (30 min) **Tileset 1: Terrain** (`terrain_demo.tsx`) 1. Map → New Tileset 2. Name: `terrain_demo` 3. Type: Collection of Images 4. Add tiles: - `assets/images/demo/terrain/grass_tile_styleA.png` - `assets/images/demo/terrain/dirt_tile_styleA.png` - `assets/images/demo/terrain/tilled_dry_styleA.png` - `assets/images/demo/terrain/tilled_watered_styleA.png` 5. Save tileset: `maps/tilesets/terrain_demo.tsx` **Tileset 2: Crops** (`crops_demo.tsx`) 1. Map → New Tileset 2. Name: `crops_demo` 3. Add tiles: - `wheat_stage0_styleA.png` through `wheat_stage4_styleA.png` 5. Save: `maps/tilesets/crops_demo.tsx` **Tileset 3: Objects** (`objects_demo.tsx`) 1. Map → New Tileset 2. Name: `objects_demo` 3. Add tiles: - `tent_styleA.png` - `campfire_styleA.png` - `dead_tree_styleA.png` - `rock_styleA.png` 4. Save: `maps/tilesets/objects_demo.tsx` **NOTE:** Start with Style A only, can duplicate for B later! --- ### **Step 1.4: Create Layers** (10 min) **In Layers panel, create (top to bottom):** 1. **"Collision"** (Object Layer) 2. **"Spawns"** (Object Layer) 3. **"Decorations"** (Object Layer) 4. **"Buildings"** (Object Layer) 5. **"Crops"** (Tile Layer) 6. **"Tilled Soil"** (Tile Layer) 7. **"Base Terrain"** (Tile Layer) ← Start here! --- ### **Step 1.5: Paint Base Terrain** (15 min) **Select "Base Terrain" layer:** 1. Select `grass_tile_styleA` from terrain tileset 2. Use **Bucket Fill** tool (G) 3. Fill entire 8×8 map with grass **Add dirt path (optional):** 1. Select `dirt_tile_styleA` 2. Use **Brush** tool (B) 3. Paint a few dirt tiles for variety **Result:** Grassy map with optional dirt patches --- ### **Step 1.6: Paint Tilled Soil** (10 min) **Select "Tilled Soil" layer:** 1. Select `tilled_dry_styleA` 2. Paint 2×2 patch at positions (1,1) to (2,2) 3. This is the farmable area **Layout:** ``` 0 1 2 3 4 5 6 7 1 [ ][🟫][🟫][ ][ ][ ][ ][ ] 2 [ ][🟫][🟫][ ][ ][ ][ ][ ] ``` --- ### **Step 1.7: Add Buildings & Decorations** (15 min) **Select "Buildings" layer (Object Layer):** 1. Insert → Insert Tile (T) 2. Select `tent_styleA` 3. Place at position (6,1) - 384px, 64px 4. Right-click tent → Object Properties: - Name: `tent` - Type: `building` - Custom property: `collision = true` **Select "Decorations" layer:** 1. Place `campfire_styleA` at (6,5) 2. Place `dead_tree_styleA` at (0,0) 3. Place `rock_styleA` at (4,0) 4. Set Type: `decoration` for each --- ### **Step 1.8: Add Spawn Points** (10 min) **Select "Spawns" layer (Object Layer):** **Kai spawn:** 1. Insert → Insert Rectangle (R) 2. Draw 32×32 box at position (2,5) - 128px, 320px 3. Object Properties: - Name: `kai_spawn` - Type: `player` - Custom: `facing = "south"` **Zombie spawn:** 1. Insert Rectangle at (4,4) - 256px, 256px 2. Properties: - Name: `zombie_1` - Type: `npc_zombie` - Custom: `ai = "idle_dig_loop"` --- ### **Step 1.9: Add Collision Objects** (10 min) **Select "Collision" layer:** **Draw collision rectangles around:** 1. Tent (64×64 box) 2. Dead tree (48×64 box) 3. Rock (40×32 box) Set `Type: collision` for all --- ### **Step 1.10: Export Map** (5 min) 1. File → Export As → JSON 2. Save to: `maps/demo_micro_farm.json` 3. Verify file exists and opens in text editor **TASK 1 COMPLETE!** ✅ Tiled map ready! --- ## 📦 **TASK 2: PHASER ASSET LOADING** (1 hour) ### **Step 2.1: Create Asset Manifest** (20 min) **Create:** `src/demo/assets.js` ```javascript // Asset manifest for demo export const DemoAssets = { // Tilemap tilemap: { key: 'demo_map', url: 'maps/demo_micro_farm.json' }, // Terrain tiles terrain: [ { key: 'grass_A', url: 'assets/images/demo/terrain/grass_tile_styleA.png' }, { key: 'dirt_A', url: 'assets/images/demo/terrain/dirt_tile_styleA.png' }, { key: 'tilled_dry_A', url: 'assets/images/demo/terrain/tilled_dry_styleA.png' }, { key: 'tilled_wet_A', url: 'assets/images/demo/terrain/tilled_watered_styleA.png' } ], // Kai frames kai: { idle_south: [ 'assets/images/demo/characters/kai_idle_south_1_styleA.png', 'assets/images/demo/characters/kai_idle_south_2_styleA.png', 'assets/images/demo/characters/kai_idle_south_3_styleA.png', 'assets/images/demo/characters/kai_idle_south_4_styleA.png' ], walk_south: [ 'assets/images/demo/characters/kai_walk_south_1_styleA.png', 'assets/images/demo/characters/kai_walk_south_2_styleA.png', 'assets/images/demo/characters/kai_walk_south_3_styleA.png', 'assets/images/demo/characters/kai_walk_south_4_styleA.png' ], idle_north: [ 'assets/images/demo/characters/kai_idle_north_1_styleA.png', 'assets/images/demo/characters/kai_idle_north_2_styleA.png', 'assets/images/demo/characters/kai_idle_north_3_styleA.png', 'assets/images/demo/characters/kai_idle_north_4_styleA.png' ], idle_east: [ 'assets/images/demo/characters/kai_idle_east_1_styleA.png', 'assets/images/demo/characters/kai_idle_east_4_styleA.png' // Just 2 for now ], idle_west: [ 'assets/images/demo/characters/kai_idle_west_1_styleB.png', 'assets/images/demo/characters/kai_idle_west_2_styleA.png', 'assets/images/demo/characters/kai_idle_west_3_styleA.png', 'assets/images/demo/characters/kai_idle_west_4_styleA.png' ], hoe: 'assets/images/demo/characters/kai_hoe_action_styleA.png', watering: 'assets/images/demo/characters/kai_watering_styleA.png' }, // Crops wheat: [ 'assets/images/demo/crops/wheat_stage0_styleA.png', 'assets/images/demo/crops/wheat_stage1_styleA.png', 'assets/images/demo/crops/wheat_stage2_styleA.png', 'assets/images/demo/crops/wheat_stage3_styleA.png', 'assets/images/demo/crops/wheat_stage4_styleA.png' ], // NPCs zombie: { idle: 'assets/images/demo/characters/zombie_idle_1_styleA.png', dig: 'assets/images/demo/characters/zombie_dig_1_styleA.png' }, // Buildings tent: 'assets/images/demo/buildings/tent_styleA.png', // Environment campfire: 'assets/images/demo/environment/campfire_styleA.png', tree: 'assets/images/demo/environment/dead_tree_styleA.png', rock: 'assets/images/demo/environment/rock_styleA.png', // UI ui: { health_full: 'assets/images/demo/ui/health_bar_full_styleA.png', health_half: 'assets/images/demo/ui/health_bar_half_styleA.png', slot_empty: 'assets/images/demo/ui/inventory_slot_empty_styleA.png', slot_selected: 'assets/images/demo/ui/inventory_slot_selected_styleA.png', dialogue_box: 'assets/images/demo/ui/dialogue_box_styleA.png', kai_portrait: 'assets/images/demo/ui/kai_portrait_styleA.png' }, // Items items: { hoe: 'assets/images/demo/items/wooden_hoe_styleA.png', watering_can: 'assets/images/demo/items/watering_can_styleA.png', wheat_seeds: 'assets/images/demo/items/wheat_seeds_styleA.png', wheat_bundle: 'assets/images/demo/items/wheat_bundle_styleA.png' }, // Effects effects: { water_drops: 'assets/images/demo/effects/water_anim_1_styleA.png', water_splash: 'assets/images/demo/effects/water_anim_2_styleA.png' } }; ``` --- ### **Step 2.2: Create Demo Scene** (20 min) **Create:** `src/scenes/DemoScene.js` ```javascript import Phaser from 'phaser'; import { DemoAssets } from '../demo/assets.js'; export default class DemoScene extends Phaser.Scene { constructor() { super({ key: 'DemoScene' }); } preload() { console.log('Loading demo assets...'); // Load tilemap this.load.tilemapTiledJSON( DemoAssets.tilemap.key, DemoAssets.tilemap.url ); // Load Kai frames this.loadKaiFrames(); // Load environment this.load.image('tent', DemoAssets.tent); this.load.image('campfire', DemoAssets.campfire); this.load.image('tree', DemoAssets.tree); this.load.image('rock', DemoAssets.rock); // Load wheat stages DemoAssets.wheat.forEach((url, i) => { this.load.image(`wheat_${i}`, url); }); // Load zombie this.load.image('zombie_idle', DemoAssets.zombie.idle); this.load.image('zombie_dig', DemoAssets.zombie.dig); // Load UI Object.keys(DemoAssets.ui).forEach(key => { this.load.image(`ui_${key}`, DemoAssets.ui[key]); }); // Progress bar (optional) this.load.on('progress', (value) => { console.log(`Loading: ${Math.floor(value * 100)}%`); }); } loadKaiFrames() { // Idle south DemoAssets.kai.idle_south.forEach((url, i) => { this.load.image(`kai_idle_s_${i}`, url); }); // Walk south DemoAssets.kai.walk_south.forEach((url, i) => { this.load.image(`kai_walk_s_${i}`, url); }); // Idle north DemoAssets.kai.idle_north.forEach((url, i) => { this.load.image(`kai_idle_n_${i}`, url); }); // Idle east DemoAssets.kai.idle_east.forEach((url, i) => { this.load.image(`kai_idle_e_${i}`, url); }); // Idle west DemoAssets.kai.idle_west.forEach((url, i) => { this.load.image(`kai_idle_w_${i}`, url); }); // Actions this.load.image('kai_hoe', DemoAssets.kai.hoe); this.load.image('kai_water', DemoAssets.kai.watering); } create() { console.log('Demo scene created!'); // Create map this.createMap(); // Test: show grass in center this.add.image(256, 256, 'kai_idle_s_0'); this.add.text(10, 10, 'Demo Scene Loaded!', { fontSize: '24px', color: '#00ff00' }); } createMap() { const map = this.make.tilemap({ key: 'demo_map' }); // We'll implement this fully in Day 2 console.log('Map loaded:', map); } } ``` --- ### **Step 2.3: Update Main Config** (10 min) **Edit:** `src/main.js` or `src/index.js` ```javascript import Phaser from 'phaser'; import DemoScene from './scenes/DemoScene.js'; const config = { type: Phaser.AUTO, width: 800, height: 600, parent: 'game-container', backgroundColor: '#2d2d2d', physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: true // Turn off later } }, scene: [DemoScene] }; const game = new Phaser.Game(config); ``` --- ### **Step 2.4: Test Loading** (10 min) **Run dev server:** ```bash npm run dev # OR npm start ``` **Open browser:** `http://localhost:8080` **Expected result:** - ✅ "Demo Scene Loaded!" text visible - ✅ Kai idle frame shows in center - ✅ Console shows "Loading: 100%" - ✅ No errors in console **If errors:** - Check file paths in `assets.js` - Verify PNGs exist in `/assets/images/demo/` - Check Phaser version compatibility **TASK 2 COMPLETE!** ✅ Assets loading! --- # 📅 DAY 2: ANIMATIONS + MOVEMENT --- ## 🎬 **TASK 3: CREATE ANIMATIONS** (1.5 hours) ### **Step 3.1: Animation Setup** (30 min) **Add to DemoScene.js `create()` method:** ```javascript create() { console.log('Creating animations...'); this.createMap(); this.createAnimations(); this.createPlayer(); this.createNPCs(); this.createCamera(); this.createControls(); } createAnimations() { // Kai idle south this.anims.create({ key: 'kai_idle_south', frames: [ { key: 'kai_idle_s_0', duration: 500 }, { key: 'kai_idle_s_1', duration: 500 }, { key: 'kai_idle_s_2', duration: 500 }, { key: 'kai_idle_s_3', duration: 500 } ], frameRate: 2, repeat: -1 }); // Kai walk south this.anims.create({ key: 'kai_walk_south', frames: [ { key: 'kai_walk_s_0' }, { key: 'kai_walk_s_1' }, { key: 'kai_walk_s_2' }, { key: 'kai_walk_s_3' } ], frameRate: 8, repeat: -1 }); // Kai idle north this.anims.create({ key: 'kai_idle_north', frames: [ { key: 'kai_idle_n_0', duration: 500 }, { key: 'kai_idle_n_1', duration: 500 }, { key: 'kai_idle_n_2', duration: 500 }, { key: 'kai_idle_n_3', duration: 500 } ], frameRate: 2, repeat: -1 }); // Kai idle east this.anims.create({ key: 'kai_idle_east', frames: [ { key: 'kai_idle_e_0', duration: 700 }, { key: 'kai_idle_e_1', duration: 700 } ], frameRate: 1.5, repeat: -1 }); // Kai idle west this.anims.create({ key: 'kai_idle_west', frames: [ { key: 'kai_idle_w_0', duration: 500 }, { key: 'kai_idle_w_1', duration: 500 }, { key: 'kai_idle_w_2', duration: 500 }, { key: 'kai_idle_w_3', duration: 500 } ], frameRate: 2, repeat: -1 }); // Kai hoe action this.anims.create({ key: 'kai_hoe', frames: [{ key: 'kai_hoe' }], frameRate: 1, repeat: 0 }); // Kai watering action this.anims.create({ key: 'kai_water', frames: [{ key: 'kai_water' }], frameRate: 1, repeat: 0 }); // Zombie animations this.anims.create({ key: 'zombie_idle', frames: [{ key: 'zombie_idle' }], frameRate: 1, repeat: -1 }); this.anims.create({ key: 'zombie_dig', frames: [{ key: 'zombie_dig' }], frameRate: 1, repeat: 0 }); console.log('✅ Animations created!'); } ``` --- ### **Step 3.2: Create Player Sprite** (30 min) ```javascript createPlayer() { // Find spawn point from tilemap const map = this.make.tilemap({ key: 'demo_map' }); const spawnLayer = map.getObjectLayer('Spawns'); const kaiSpawn = spawnLayer.objects.find(obj => obj.name === 'kai_spawn'); // Create player sprite this.player = this.physics.add.sprite( kaiSpawn.x + 16, // Center in spawn box kaiSpawn.y + 16, 'kai_idle_s_0' ); // Set physics properties this.player.setCollideWorldBounds(true); this.player.body.setSize(32, 48); // Collision box this.player.body.setOffset(16, 16); // Center collision // Start idle animation this.player.play('kai_idle_south'); // Player state this.player.facing = 'south'; this.player.isMoving = false; console.log('✅ Player created at:', kaiSpawn.x, kaiSpawn.y); } ``` --- ### **Step 3.3: Create NPCs** (30 min) ```javascript createNPCs() { const map = this.make.tilemap({ key: 'demo_map' }); const spawnLayer = map.getObjectLayer('Spawns'); const zombieSpawn = spawnLayer.objects.find(obj => obj.name === 'zombie_1'); if (zombieSpawn) { this.zombie = this.physics.add.sprite( zombieSpawn.x + 16, zombieSpawn.y + 16, 'zombie_idle' ); this.zombie.play('zombie_idle'); // Zombie AI loop this.time.addEvent({ delay: 5000, callback: () => { this.zombie.play('zombie_dig'); this.time.delayedCall(1000, () => { this.zombie.play('zombie_idle'); }); }, loop: true }); console.log('✅ Zombie created!'); } } ``` **TASK 3 COMPLETE!** ✅ Animations working! --- ## 🎮 **TASK 4: PLAYER CONTROLS** (1.5 hours) ### **Step 4.1: Setup Input** (20 min) ```javascript createControls() { // WASD keys this.keys = { W: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W), A: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A), S: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S), D: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D), E: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), H: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.H), SPACE: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE) }; // Cursor keys (arrows) this.cursors = this.input.keyboard.createCursorKeys(); console.log('✅ Controls setup!'); } ``` --- ### **Step 4.2: Movement Logic** (40 min) ```javascript update() { if (!this.player) return; this.handleMovement(); } handleMovement() { const speed = 160; let velocityX = 0; let velocityY = 0; let newFacing = this.player.facing; // Check input if (this.keys.W.isDown || this.cursors.up.isDown) { velocityY = -speed; newFacing = 'north'; } else if (this.keys.S.isDown || this.cursors.down.isDown) { velocityY = speed; newFacing = 'south'; } if (this.keys.A.isDown || this.cursors.left.isDown) { velocityX = -speed; newFacing = 'west'; } else if (this.keys.D.isDown || this.cursors.right.isDown) { velocityX = speed; newFacing = 'east'; } // Apply velocity this.player.setVelocity(velocityX, velocityY); // Normalize diagonal speed this.player.body.velocity.normalize().scale(speed); // Update animations this.updatePlayerAnimation(velocityX, velocityY, newFacing); } updatePlayerAnimation(vx, vy, facing) { const isMoving = vx !== 0 || vy !== 0; // Update facing if direction changed if (facing !== this.player.facing) { this.player.facing = facing; } // Play appropriate animation if (isMoving) { // Only have walk south for now if (facing === 'south') { this.player.play('kai_walk_south', true); } else { // Use idle for other directions until we have walk anims this.player.play(`kai_idle_${facing}`, true); } this.player.isMoving = true; } else { // Idle this.player.play(`kai_idle_${facing}`, true); this.player.isMoving = false; } } ``` --- ### **Step 4.3: Test Movement** (30 min) **Test checklist:** - ✅ WASD moves Kai in 4 directions - ✅ Arrow keys also work - ✅ Kai stops when keys released - ✅ Idle animation plays when stopped - ✅ Walk south animation plays when moving down - ✅ Facing direction updates correctly **TASK 4 COMPLETE!** ✅ Player controls working! --- ## 📷 **TASK 5: CAMERA & COLLISION** (1 hour) ### **Step 5.1: Camera Follow** (20 min) ```javascript createCamera() { // Set world bounds this.physics.world.setBounds(0, 0, 512, 512); // Camera follows player this.cameras.main.startFollow(this.player); this.cameras.main.setBounds(0, 0, 512, 512); this.cameras.main.setZoom(1.5); // Zoom in slightly console.log('✅ Camera setup!'); } ``` --- ### **Step 5.2: Collision Setup** (40 min) ```javascript createMap() { const map = this.make.tilemap({ key: 'demo_map' }); // NOTE: Tilesets must match names in Tiled! const terrainTileset = map.addTilesetImage('terrain_demo'); // Create layers this.terrainLayer = map.createLayer('Base Terrain', terrainTileset, 0, 0); this.tilledLayer = map.createLayer('Tilled Soil', terrainTileset, 0, 0); // Add collision objects from Collision layer const collisionLayer = map.getObjectLayer('Collision'); this.collisionGroup = this.physics.add.staticGroup(); collisionLayer.objects.forEach(obj => { const rect = this.add.rectangle( obj.x + obj.width/2, obj.y + obj.height/2, obj.width, obj.height, 0xff0000, 0 // Invisible ); this.physics.add.existing(rect, true); this.collisionGroup.add(rect); }); console.log('✅ Map created with collision!'); } // In create(), after createPlayer(): createCollision() { // Player vs collision objects this.physics.add.collider(this.player, this.collisionGroup); console.log('✅ Collision setup!'); } ``` **TASK 5 COMPLETE!** ✅ Camera + collision working! **DAY 2 COMPLETE!** ✅ Movement demo playable! --- # 📅 DAY 3: GAMEPLAY + POLISH --- ## 🌾 **TASK 6: FARMING MECHANICS** (1.5 hours) ### **Step 6.1: Farmable Tiles System** (30 min) ```javascript create() { // ... existing code ... this.createFarmSystem(); } createFarmSystem() { // Track farmable tiles this.farmTiles = []; const map = this.make.tilemap({ key: 'demo_map' }); // Find tilled soil tiles (positions 1,1 to 2,2) for (let x = 1; x <= 2; x++) { for (let y = 1; y <= 2; y++) { this.farmTiles.push({ x: x, y: y, worldX: x * 64 + 32, worldY: y * 64 + 32, planted: false, watered: false, stage: -1, crop: null }); } } console.log('✅ Farm system ready! Tiles:', this.farmTiles.length); } ``` --- ### **Step 6.2: Plant Seeds** (30 min) ```javascript update() { if (!this.player) return; this.handleMovement(); this.handleActions(); } handleActions() { // E key to plant if (Phaser.Input.Keyboard.JustDown(this.keys.E)) { this.attemptPlant(); } // SPACE to water if (Phaser.Input.Keyboard.JustDown(this.keys.SPACE)) { this.attemptWater(); } // H to harvest if (Phaser.Input.Keyboard.JustDown(this.keys.H)) { this.attemptHarvest(); } } attemptPlant() { // Find nearby farmable tile const nearbyTile = this.farmTiles.find(tile => { const dist = Phaser.Math.Distance.Between( this.player.x, this.player.y, tile.worldX, tile.worldY ); return dist < 64 && !tile.planted; }); if (nearbyTile) { // Play hoe animation this.player.play('kai_hoe'); // Plant seed after animation this.time.delayedCall(500, () => { nearbyTile.planted = true; nearbyTile.stage = 0; // Create crop sprite nearbyTile.crop = this.add.sprite( nearbyTile.worldX, nearbyTile.worldY, 'wheat_0' ); console.log('🌱 Planted wheat!'); // Return to idle this.player.play(`kai_idle_${this.player.facing}`); }); } } ``` --- ### **Step 6.3: Water & Grow** (30 min) ```javascript attemptWater() { const nearbyTile = this.farmTiles.find(tile => { const dist = Phaser.Math.Distance.Between( this.player.x, this.player.y, tile.worldX, tile.worldY ); return dist < 64 && tile.planted && !tile.watered; }); if (nearbyTile) { // Play watering animation this.player.play('kai_water'); this.time.delayedCall(500, () => { nearbyTile.watered = true; // Start growth timer (10 seconds for demo) this.growCrop(nearbyTile); console.log('💧 Watered crop!'); this.player.play(`kai_idle_${this.player.facing}`); }); } } growCrop(tile) { // Grow through 5 stages over 10 seconds const growthInterval = 2000; // 2 seconds per stage const growTimer = this.time.addEvent({ delay: growthInterval, callback: () => { tile.stage++; if (tile.stage <= 4) { // Update sprite tile.crop.setTexture(`wheat_${tile.stage}`); console.log(`🌾 Wheat grew to stage ${tile.stage}`); } else { // Fully grown! growTimer.remove(); console.log('✨ Wheat ready to harvest!'); } }, repeat: 4 // Stages 1-4 (0 already set) }); } attemptHarvest() { const nearbyTile = this.farmTiles.find(tile => { const dist = Phaser.Math.Distance.Between( this.player.x, this.player.y, tile.worldX, tile.worldY ); return dist < 64 && tile.stage === 4; }); if (nearbyTile) { // Remove crop nearbyTile.crop.destroy(); // Reset tile nearbyTile.planted = false; nearbyTile.watered = false; nearbyTile.stage = -1; nearbyTile.crop = null; // Add to inventory (we'll implement UI next) console.log('✅ Harvested wheat!'); } } ``` **TASK 6 COMPLETE!** ✅ Farming loop works! --- ## 🎨 **TASK 7: UI IMPLEMENTATION** (1 hour) ### **Step 7.1: Create UI Layer** (30 min) ```javascript create() { // ... existing code ... this.createUI(); } createUI() { // Health bar this.healthBar = this.add.image(20, 20, 'ui_health_full'); this.healthBar.setOrigin(0, 0); this.healthBar.setScrollFactor(0); // Fixed to camera // Inventory bar const invY = this.cameras.main.height - 80; this.inventorySlots = []; for (let i = 0; i < 5; i++) { const slot = this.add.image( this.cameras.main.width/2 - 100 + i*50, invY, 'ui_slot_empty' ); slot.setScrollFactor(0); this.inventorySlots.push(slot); } // Select first slot this.selectedSlot = 0; this.inventorySlots[0].setTexture('ui_slot_selected'); // Tutorial text this.tutorialText = this.add.text( this.cameras.main.width/2, 30, 'Use WASD to move!', { fontSize: '18px', color: '#ffffff', backgroundColor: '#000000', padding: { x: 10, y: 5 } } ); this.tutorialText.setOrigin(0.5, 0); this.tutorialText.setScrollFactor(0); console.log('✅ UI created!'); } ``` --- ### **Step 7.2: Update Tutorial Text** (30 min) ```javascript showTutorial(message, duration = 3000) { this.tutorialText.setText(message); this.tutorialText.setAlpha(1); // Fade out after duration this.tweens.add({ targets: this.tutorialText, alpha: 0, duration: 500, delay: duration }); } // Update attemptPlant(): attemptPlant() { // ... existing code ... if (nearbyTile) { this.showTutorial('🌱 Wheat planted! Press SPACE to water!'); // ... rest of code } else { this.showTutorial('❌ No farmable tile nearby!', 1500); } } // Similar for water and harvest... ``` **TASK 7 COMPLETE!** ✅ UI working! --- ## 🎬 **TASK 8: DEMO SCRIPT** (30 min) ### **Step 8.1: Auto-Demo Mode** (30 min) ```javascript create() { // ... existing code ... // Start demo script after 3 seconds this.time.delayedCall(3000, () => { this.startDemoScript(); }); } startDemoScript() { // Tutorial sequence const script = [ { delay: 0, action: () => this.showTutorial('Use WASD to move around!', 3000) }, { delay: 5000, action: () => this.panToZombie() }, { delay: 8000, action: () => this.panToPlayer() }, { delay: 10000, action: () => this.showTutorial('Press E near tilled soil to plant!', 3000) }, { delay: 15000, action: () => this.showTutorial('This is just 1% of DolinaSmrti...', 3000) }, { delay: 20000, action: () => this.showEnding() } ]; script.forEach(step => { this.time.delayedCall(step.delay, step.action); }); } panToZombie() { this.cameras.main.pan( this.zombie.x, this.zombie.y, 2000, 'Sine.easeInOut' ); this.showTutorial('Workers till the fields...', 2000); this.zombie.play('zombie_dig'); } panToPlayer() { this.cameras.main.pan( this.player.x, this.player.y, 2000, 'Sine.easeInOut' ); } showEnding() { const endText = this.add.text( this.cameras.main.width/2, this.cameras.main.height/2, 'DOLINASMRTI\n\nComing 2025\n\nSupport us on Kickstarter!', { fontSize: '32px', color: '#ffffff', align: 'center', backgroundColor: '#000000', padding: { x: 30, y: 20 } } ); endText.setOrigin(0.5); endText.setScrollFactor(0); endText.setAlpha(0); this.tweens.add({ targets: endText, alpha: 1, duration: 2000 }); } ``` **TASK 8 COMPLETE!** ✅ Demo script done! **DAY 3 COMPLETE!** ✅✅✅ --- # 🎉 DEMO COMPLETE CHECKLIST ## ✅ **Assets** (Day 0) - [x] 99 PNG files generated - [x] Background removal complete - [x] Git committed ## ✅ **Tiled Map** (Day 1) - [ ] 8×8 map created - [ ] Tilesets added - [ ] Layers configured - [ ] Spawn points set - [ ] Collision objects placed - [ ] Exported as JSON ## ✅ **Asset Loading** (Day 1) - [ ] Asset manifest created - [ ] DemoScene created - [ ] All assets loading - [ ] No console errors ## ✅ **Animations** (Day 2) - [ ] Kai idles (4 directions) - [ ] Kai walk south - [ ] Kai actions (hoe, water) - [ ] Zombie animations ## ✅ **Movement** (Day 2) - [ ] WASD controls - [ ] 4-directional movement - [ ] Idle/walk transitions - [ ] Facing direction ## ✅ **Camera** (Day 2) - [ ] Follows player - [ ] Bounded to map - [ ] Smooth panning ## ✅ **Collision** (Day 2) - [ ] World bounds - [ ] Object collision - [ ] Player collision box ## ✅ **Farming** (Day 3) - [ ] Plant seeds (E key) - [ ] Water crops (SPACE) - [ ] Growth stages (10 sec) - [ ] Harvest wheat (H key) ## ✅ **UI** (Day 3) - [ ] Health bar displayed - [ ] Inventory slots - [ ] Tutorial text - [ ] Item icons ## ✅ **Demo Script** (Day 3) - [ ] Auto tutorial - [ ] Camera pans - [ ] Ending sequence --- # 🚀 LAUNCH CHECKLIST ## **Before Recording Video:** - [ ] Test full farming loop - [ ] Test all controls - [ ] Verify all animations - [ ] Check for bugs - [ ] Disable debug mode - [ ] Clean console output ## **Video Recording:** - [ ] 1920×1080 resolution - [ ] 60 FPS - [ ] 3-5 minute runtime - [ ] Show both art styles - [ ] Add voiceover - [ ] Add music - [ ] Export to MP4 ## **Kickstarter Page:** - [ ] Embed video - [ ] Add screenshots - [ ] Write story - [ ] Set funding goals - [ ] Create reward tiers - [ ] Publish! --- # 📞 TROUBLESHOOTING ## **Assets not loading?** - Check file paths in `assets.js` - Verify PNGs exist - Check browser console errors ## **Animations not playing?** - Verify animation keys match - Check frame keys exist - Enable Phaser debug mode ## **Player not moving?** - Check physics enabled - Verify velocity applied - Test input detection ## **Collision not working?** - Check static group setup - Verify collision enabled - Check collision bounds --- **ESTIMATED TOTAL TIME:** 10 hours **DIFFICULTY:** Medium **REQUIRED SKILLS:** JavaScript, Phaser.js basics, Tiled **YOU CAN DO THIS! 🎮✨** **Let's build the demo and launch that Kickstarter! 🚀**