Files
novafarma/docs/KICKSTARTER_DEMO_IMPLEMENTATION_GUIDE.md
David Kotnik a072fd48b1 Evening Session: 82 NEW DEMO ASSETS + COMPLETE BG REMOVAL
PRIORITY TRACKER: 100% COMPLETE (41 assets x 2 styles = 82 PNGs)

P1 CRITICAL (46 PNGs): Kai walk south, actions, idle breathing, wheat cycle, tilled soil, zombie, tools
P2 HIGH (12 PNGs): Inventory items, UI elements
P3 MEDIUM (10 PNGs): Dialogue system, water effects
P4 LOW (6 PNGs): Environment decorations

BACKGROUND REMOVAL: 99/99 PNGs with perfect RGBA transparency!
BACKUP: Original white-bg versions saved to demo_originals_with_white_bg/

DOCUMENTATION:
- KICKSTARTER_DEMO_IMPLEMENTATION_GUIDE.md (complete 10hr roadmap)
- TONIGHT_TILED_QUICKSTART.md (2hr map building guide)
- DEMO_MAP_PLAN.md (8x8 layout spec)
- DEV_JOURNAL updated with evening session

API: Turtle Mode, 100% success rate, 0 errors, 120 minutes generation
ASSETS: 99 total transparent PNGs ready for Phaser.js integration
STATUS: READY FOR IMPLEMENTATION PHASE!

Session: 2.5 hours | Project total: 128 hours | Cost: 0 EUR
2025-12-30 22:00:39 +01:00

30 KiB
Raw Blame History

🎮 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:

which tiled
# If not found: brew install tiled

Launch Tiled:

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
  4. 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

// 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

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

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:

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:

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)

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)

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)

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)

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)

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)

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)

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)

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)

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)

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)

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)

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)

  • 99 PNG files generated
  • Background removal complete
  • 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! 🚀