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
30 KiB
🎮 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:
- File → New → New Map
- Settings:
- Orientation: Orthogonal
- Tile layer format: CSV
- Tile render order: Right Down
- Map size: 8 × 8 tiles
- Tile size: 64 × 64 pixels
- 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)
- Map → New Tileset
- Name:
terrain_demo - Type: Collection of Images
- Add tiles:
assets/images/demo/terrain/grass_tile_styleA.pngassets/images/demo/terrain/dirt_tile_styleA.pngassets/images/demo/terrain/tilled_dry_styleA.pngassets/images/demo/terrain/tilled_watered_styleA.png
- Save tileset:
maps/tilesets/terrain_demo.tsx
Tileset 2: Crops (crops_demo.tsx)
- Map → New Tileset
- Name:
crops_demo - Add tiles:
wheat_stage0_styleA.pngthroughwheat_stage4_styleA.png
- Save:
maps/tilesets/crops_demo.tsx
Tileset 3: Objects (objects_demo.tsx)
- Map → New Tileset
- Name:
objects_demo - Add tiles:
tent_styleA.pngcampfire_styleA.pngdead_tree_styleA.pngrock_styleA.png
- 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):
- "Collision" (Object Layer)
- "Spawns" (Object Layer)
- "Decorations" (Object Layer)
- "Buildings" (Object Layer)
- "Crops" (Tile Layer)
- "Tilled Soil" (Tile Layer)
- "Base Terrain" (Tile Layer) ← Start here!
Step 1.5: Paint Base Terrain (15 min)
Select "Base Terrain" layer:
- Select
grass_tile_styleAfrom terrain tileset - Use Bucket Fill tool (G)
- Fill entire 8×8 map with grass
Add dirt path (optional):
- Select
dirt_tile_styleA - Use Brush tool (B)
- 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:
- Select
tilled_dry_styleA - Paint 2×2 patch at positions (1,1) to (2,2)
- 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):
- Insert → Insert Tile (T)
- Select
tent_styleA - Place at position (6,1) - 384px, 64px
- Right-click tent → Object Properties:
- Name:
tent - Type:
building - Custom property:
collision = true
- Name:
Select "Decorations" layer:
- Place
campfire_styleAat (6,5) - Place
dead_tree_styleAat (0,0) - Place
rock_styleAat (4,0) - Set Type:
decorationfor each
Step 1.8: Add Spawn Points (10 min)
Select "Spawns" layer (Object Layer):
Kai spawn:
- Insert → Insert Rectangle (R)
- Draw 32×32 box at position (2,5) - 128px, 320px
- Object Properties:
- Name:
kai_spawn - Type:
player - Custom:
facing = "south"
- Name:
Zombie spawn:
- Insert Rectangle at (4,4) - 256px, 256px
- Properties:
- Name:
zombie_1 - Type:
npc_zombie - Custom:
ai = "idle_dig_loop"
- Name:
Step 1.9: Add Collision Objects (10 min)
Select "Collision" layer:
Draw collision rectangles around:
- Tent (64×64 box)
- Dead tree (48×64 box)
- Rock (40×32 box)
Set Type: collision for all
Step 1.10: Export Map (5 min)
- File → Export As → JSON
- Save to:
maps/demo_micro_farm.json - 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! 🚀