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

1356 lines
30 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🎮 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! 🚀**