diff --git a/ASSET_NAMING_STANDARDS.md b/ASSET_NAMING_STANDARDS.md new file mode 100644 index 000000000..de3d70061 --- /dev/null +++ b/ASSET_NAMING_STANDARDS.md @@ -0,0 +1,266 @@ +# 📐 ASSET NAMING & ORGANIZATION STANDARDS +**Created:** January 4, 2026 +**Purpose:** Standardized naming for all game assets + +--- + +## 🎨 SPRITE NAMING CONVENTION + +### **Format:** +``` +{category}_{name}_{variation}_{timestamp}.png +``` + +### **Examples:** +``` +interior_bed_sleepingbag_1767523722494.png +interior_bed_wooden_1767523739033.png +interior_bed_kingsize_1767523753754.png +mine_elevator_cage_1767524542789.png +npc_baker_idle_1767524000000.png +``` + +--- + +## 📁 CATEGORY PREFIXES + +### **Interior Objects:** +``` +interior_{object_name}.png +``` +Examples: +- `interior_bed_wooden.png` +- `interior_table_small.png` +- `interior_kitchen_stove.png` +- `interior_alchemy_bottle.png` + +### **Buildings:** +``` +building_{name}_{type}.png +``` +Examples: +- `building_bakery_exterior.png` +- `building_barbershop_exterior.png` +- `building_lawyer_office.png` + +### **Mine Assets:** +``` +mine_{object_name}.png +``` +Examples: +- `mine_entrance_portal.png` +- `mine_elevator_cage.png` +- `mine_ore_vein_copper.png` + +### **NPCs:** +``` +npc_{name}_{state}.png +``` +Examples: +- `npc_baker_idle.png` +- `npc_barber_working.png` +- `npc_lawyer_sitting.png` + +### **UI Elements:** +``` +ui_{element_name}.png +``` +Examples: +- `ui_sleep_button.png` +- `ui_crafting_menu_bg.png` +- `ui_shop_window.png` + +### **Terrain:** +``` +terrain_{type}_{variant}.png +``` +Examples: +- `terrain_grass_dark_01.png` +- `terrain_stone_cursed_02.png` +- `terrain_water_purple.png` + +### **Weapons & Tools:** +``` +weapon_{name}_{tier}.png +tool_{name}_{tier}.png +``` +Examples: +- `weapon_sword_steel.png` +- `weapon_scythe_cursed.png` +- `tool_pickaxe_wooden.png` +- `tool_hoe_iron.png` + +--- + +## 📦 DIRECTORY STRUCTURE + +``` +/assets/images/ +├── STYLE_32_SESSION_JAN_04/ # Current session +│ ├── interior_*.png # All interior objects +│ ├── mine_*.png # Mine equipment +│ ├── building_*.png # Building exteriors +│ ├── npc_*.png # NPC sprites +│ └── ui_*.png # UI elements +│ +├── buildings/ # Legacy organized by type +│ ├── bakery/ +│ ├── barbershop/ +│ └── lawyer_office/ +│ +├── npcs/ # NPC-specific assets +│ ├── baker/ +│ ├── barber/ +│ └── lawyer/ +│ +├── ui/ # UI components +│ ├── menus/ +│ ├── buttons/ +│ └── icons/ +│ +└── tilesets/ # Tileset images + ├── interior_objects.png # Combined tileset + └── mine_assets.png # Combined mine tileset +``` + +--- + +## 🏷️ FILENAME COMPONENTS + +### **1. Category** (Required) +- Identifies asset type +- Lowercase, singular +- Examples: `interior`, `building`, `npc`, `ui`, `mine` + +### **2. Name** (Required) +- Descriptive object name +- Lowercase, underscores for spaces +- Examples: `bed`, `crafting_table`, `stone_crusher` + +### **3. Variation** (Optional) +- Distinguishes similar items +- Examples: `wooden`, `small`, `kingsize`, `tier1` + +### **4. State/Animation** (Optional for NPCs) +- Character state or animation frame +- Examples: `idle`, `walking`, `working`, `sitting` + +### **5. Timestamp** (Auto-generated) +- Unix timestamp from generation +- Format: 13 digits +- Example: `1767523722494` + +--- + +## 📏 SIZE STANDARDS + +### **Interior Objects:** +``` +Small items: 32x32px (bottles, tools) +Medium items: 64x64px (chests, chairs) +Large items: 96x96px (beds, ovens, crushers) +Tall items: 64x96px (wardrobes, shelves) +Wide items: 96x64px (counters, tables) +Floor decals: 96x96px (ritual circle) +Vertical: 32x128px (ladders) +Horizontal: 128x32px (rails, tracks) +``` + +### **Buildings:** +``` +Small: 128x128px (shops) +Medium: 192x192px (houses) +Large: 256x256px (town hall) +``` + +### **NPCs:** +``` +Standard: 48x64px (chibi characters) +Large: 64x96px (bosses, special NPCs) +``` + +### **UI Elements:** +``` +Icons: 32x32px (inventory items) +Buttons: 128x48px (action buttons) +Panels: 400x300px (menus, dialogs) +``` + +--- + +## ✅ CLEAN FILENAME EXAMPLES + +### **Good:** +``` +✅ interior_bed_wooden.png +✅ mine_ore_vein_gold.png +✅ npc_baker_idle.png +✅ building_bakery_exterior.png +✅ ui_sleep_menu_bg.png +``` + +### **Bad:** +``` +❌ BedWooden.png (CamelCase) +❌ interior-bed-wooden.png (dashes instead of underscores) +❌ bed_wooden_interior.png (wrong order) +❌ wooden bed.png (spaces) +❌ bed2.png (not descriptive) +``` + +--- + +## 🔄 RENAMING SCRIPT + +**Batch rename generated files:** +```bash +# Remove timestamps from final assets +for file in interior_*_*.png; do + # Extract base name (remove timestamp) + newname=$(echo "$file" | sed 's/_[0-9]\{13\}\.png/.png/') + mv "$file" "$newname" +done +``` + +**Example output:** +``` +interior_bed_wooden_1767523722494.png → interior_bed_wooden.png +interior_table_small_1767523769657.png → interior_table_small.png +``` + +--- + +## 📋 ASSET CHECKLIST + +Before committing new assets: + +- [ ] Correct category prefix used +- [ ] Descriptive, clear name +- [ ] Lowercase with underscores +- [ ] Correct size (multiple of 32px) +- [ ] Chroma green background (#00FF00) +- [ ] Style 32 compliance (5px outlines, noir aesthetic) +- [ ] Placed in correct directory +- [ ] Documented in manifest + +--- + +## 📚 MANIFEST FORMAT + +**Track all assets in `ASSET_MANIFEST.md`:** + +```markdown +## Interior Objects + +| Filename | Size | Category | Status | Notes | +|----------|------|----------|--------|-------| +| interior_bed_sleepingbag.png | 64x48 | Home | ✅ Complete | Basic tier | +| interior_bed_wooden.png | 96x64 | Home | ✅ Complete | Mid tier | +| interior_bed_kingsize.png | 128x96 | Home | ✅ Complete | Premium tier | +``` + +--- + +**Created:** January 4, 2026 +**Version:** 1.0 +**Status:** Official Standard ✅ diff --git a/SYSTEMS_INTEGRATION_GUIDE.md b/SYSTEMS_INTEGRATION_GUIDE.md new file mode 100644 index 000000000..9c6ef82ed --- /dev/null +++ b/SYSTEMS_INTEGRATION_GUIDE.md @@ -0,0 +1,504 @@ +# 🔌 SYSTEMS INTEGRATION GUIDE +**Created:** January 4, 2026 +**Purpose:** How to integrate new game systems into Phaser 3 + +--- + +## 📦 INITIALIZED SYSTEMS + +### **Sleep System Integration** + +**1. Import & Initialize:** +```javascript +// In GameScene.js or MainGameScene.js +import SleepSystem from '../systems/SleepSystem.js'; + +create() { + // Initialize sleep system + this.sleepSystem = new SleepSystem(this); + + // Register with game state + this.game.registry.set('sleepSystem', this.sleepSystem); +} +``` + +**2. Hook into Player Interaction:** +```javascript +// When player interacts with bed +onBedInteraction(bedSprite) { + const bedInfo = this.sleepSystem.getCurrentBedInfo(); + + // Show sleep UI + this.showSleepMenu({ + bedName: bedInfo.name, + energyRegen: bedInfo.energyRegen, + canSleep: bedInfo.canSleep + }); +} + +// When player clicks "Sleep" button +onSleepButtonClick() { + const result = this.sleepSystem.sleep(); + + if (result.success) { + // Hide UI + this.hideSleepMenu(); + + // Play sleep animation/fade + this.cameras.main.fadeOut(1000, 0, 0, 0); + + // Wait for sleep to complete + this.sleepSystem.on('wakeUp', (data) => { + this.cameras.main.fadeIn(1000); + this.showMessage(`Good morning! +${data.energyRestored} Energy`); + }); + } else { + this.showMessage(result.message); + } +} +``` + +**3. Bed Purchase Integration:** +```javascript +onBedShopInteraction() { + const beds = this.sleepSystem.bedTypes; + + // Show shop UI with available beds + this.showBedShop(beds); +} + +onPurchaseBed(bedType) { + const result = this.sleepSystem.purchaseBed(bedType); + + if (result.success) { + this.showMessage(result.message); + + // Trigger furniture placement (drag-and-drop) + this.startFurniturePlacement(bedType); + } else { + this.showMessage(result.message); + } +} +``` + +**4. Update Loop:** +```javascript +update(time, delta) { + // Sleep system doesn't need frequent updates + // (handled by events and timers) +} +``` + +--- + +### **Crafting Tables Integration** + +**1. Import & Initialize:** +```javascript +import CraftingTablesSystem from '../systems/CraftingTablesSystem.js'; + +create() { + this.craftingSystem = new CraftingTablesSystem(this); + this.game.registry.set('craftingSystem', this.craftingSystem); +} +``` + +**2. Hook into Crafting Table Interaction:** +```javascript +onCraftingTableInteraction(tableSprite) { + const uiData = this.craftingSystem.getCraftingUIData(); + + // Show crafting menu + this.showCraftingMenu({ + currentTable: uiData.currentTable, + recipes: uiData.availableRecipes, + isCrafting: uiData.isCrafting, + currentCraft: uiData.currentCraft + }); +} +``` + +**3. Recipe Selection:** +```javascript +onRecipeClick(recipeId) { + const canCraft = this.craftingSystem.canCraft(recipeId); + + if (canCraft.canCraft) { + // Show craft confirmation + this.showCraftConfirmation(recipeId); + } else { + // Show why can't craft + if (canCraft.missingIngredients) { + this.showMissingIngredients(canCraft.missingIngredients); + } else { + this.showMessage(canCraft.reason); + } + } +} + +onConfirmCraft(recipeId, quantity) { + const result = this.craftingSystem.craft(recipeId, quantity); + + if (result.success) { + this.showMessage(result.message); + + // Show crafting progress bar + this.showCraftingProgress(result.craftJob); + } else { + this.showMessage(result.message); + } +} +``` + +**4. Crafting Progress UI:** +```javascript +update(time, delta) { + // Update crafting system + this.craftingSystem.update(delta / 1000); // Convert ms to seconds + + // Update crafting progress bar + if (this.craftingSystem.currentCraft) { + const progress = 1 - (this.craftingSystem.currentCraft.timeRemaining / + this.craftingSystem.currentCraft.totalTime); + this.updateCraftingProgressBar(progress); + } +} + +// Listen for crafting events +create() { + this.craftingSystem.game.on('craftingStarted', (data) => { + this.showMessage(`Crafting ${data.quantity}x ${data.recipe.name}...`); + }); + + this.craftingSystem.game.on('craftingCompleted', (data) => { + this.playSound('craft_complete'); + this.showItemGain(data.recipe.output.item, data.quantity); + }); +} +``` + +**5. Large Table Purchase:** +```javascript +onLargeTableShopInteraction() { + const largeTable = this.craftingSystem.tables.LARGE; + + if (largeTable.unlocked) { + this.showMessage('You already own the Large Planning Table!'); + } else { + this.showPurchaseConfirmation({ + item: 'Large Planning Table', + cost: largeTable.cost, + requirements: largeTable.requirements + }); + } +} + +onConfirmLargeTablePurchase() { + const result = this.craftingSystem.purchaseLargeTable(); + + if (result.success) { + this.showMessage(result.message); + this.startFurniturePlacement('large_table'); + } else { + this.showMessage(result.message); + } +} +``` + +--- + +### **Bakery Shop Integration** + +**1. Import & Initialize:** +```javascript +import BakeryShopSystem from '../systems/BakeryShopSystem.js'; + +create() { + this.bakerySystem = new BakeryShopSystem(this); + this.game.registry.set('bakerySystem', this.bakerySystem); + + // Check if bakery should be unlocked (from save file) + if (this.player.ownedBuildings.includes('bakery')) { + this.bakerySystem.isUnlocked = true; + this.bakerySystem.isOpen = true; + } +} +``` + +**2. Bakery Entrance Interaction:** +```javascript +onBakeryEnterInteraction() { + // Check if unlocked + if (!this.bakerySystem.isUnlocked) { + this.showBuildingUnlockUI('bakery'); + return; + } + + // Check if open + if (!this.bakerySystem.isOpen) { + const hours = this.bakerySystem.getShopUIData().openingHours; + this.showMessage(`Bakery is closed. Open: ${hours}`); + return; + } + + // Enter bakery + this.scene.start('BakeryInteriorScene'); +} +``` + +**3. Bakery Interior Scene:** +```javascript +// BakeryInteriorScene.js +import Phaser from 'phaser'; + +export default class BakeryInteriorScene extends Phaser.Scene { + constructor() { + super({ key: 'BakeryInteriorScene' }); + } + + create() { + // Load interior tilemap + this.map = this.make.tilemap({ key: 'bakery_interior' }); + + // Get bakery system + this.bakerySystem = this.game.registry.get('bakerySystem'); + + // Show shop UI + this.showShopUI(); + + // Baker NPC + this.baker = this.add.sprite(200, 150, 'npc_baker'); + this.baker.setInteractive(); + this.baker.on('pointerdown', () => this.talkToBaker()); + } + + showShopUI() { + const shopData = this.bakerySystem.getShopUIData(); + + // Create shop menu + this.shopMenu = this.add.container(400, 300); + + // Display inventory items + Object.values(shopData.inventory).forEach((item, index) => { + const itemButton = this.createShopItem(item, index); + this.shopMenu.add(itemButton); + }); + } + + createShopItem(item, index) { + const y = index * 60; + + const button = this.add.container(0, y); + + // Item name + const nameText = this.add.text(0, 0, item.name, { + fontSize: '18px', + color: '#ffffff' + }); + + // Price + const priceText = this.add.text(200, 0, `${item.price}g`, { + fontSize: '16px', + color: '#ffdd00' + }); + + // Stock + const stockText = this.add.text(300, 0, `Stock: ${item.stock}`, { + fontSize: '14px', + color: '#aaaaaa' + }); + + button.add([nameText, priceText, stockText]); + button.setInteractive(new Phaser.Geom.Rectangle(0, 0, 400, 50), Phaser.Geom.Rectangle.Contains); + button.on('pointerdown', () => this.onBuyItem(item.id)); + + return button; + } + + onBuyItem(itemId) { + // Show quantity selector + this.showQuantitySelector(itemId, (quantity) => { + const result = this.bakerySystem.buyItem(itemId, quantity); + + if (result.success) { + this.playSound('purchase'); + this.refreshShopUI(); + this.showMessage(`Purchased! ${result.totalPrice}g`); + } else { + this.showMessage(result.message); + } + }); + } + + talkToBaker() { + const baker = this.bakerySystem.baker; + const dialogueOptions = baker.dialogue; + + // Random greeting + const greeting = Phaser.Utils.Array.GetRandom(dialogueOptions.greeting); + + this.showDialogue(baker.name, greeting, [ + { + text: 'Buy items', + action: () => this.showShopUI() + }, + { + text: 'Order birthday cake', + action: () => this.showBirthdayCakeMenu() + }, + { + text: 'About baking competition', + action: () => this.showCompetitionInfo() + }, + { + text: 'Leave', + action: () => this.scene.start('TownSquareScene') + } + ]); + } +} +``` + +**4. Gift System Integration:** +```javascript +onGiftItemToNPC(itemId, npcId) { + // Check if item is from bakery + const bakeryItem = this.bakerySystem.inventory[itemId]; + + if (bakeryItem) { + const result = this.bakerySystem.giftItem(itemId, npcId); + + if (result.success) { + this.showNPCReaction(npcId, result.reaction); + this.playHeartAnimation(npcId, result.heartsAdded); + } + } +} +``` + +**5. Time-based Updates:** +```javascript +// In main game loop +update(time, delta) { + // Check if hour has changed + if (this.timeSystem.hasHourChanged()) { + this.bakerySystem.update(); + + // Check if bakery just opened/closed + const bakeryData = this.bakerySystem.getShopUIData(); + if (bakeryData.isOpen !== this.lastBakeryState) { + this.onBakeryStatusChange(bakeryData.isOpen); + this.lastBakeryState = bakeryData.isOpen; + } + } +} +``` + +--- + +## 🎮 COMPLETE GAME INTEGRATION + +**Main Game Scene Setup:** +```javascript +// MainGameScene.js +import SleepSystem from '../systems/SleepSystem.js'; +import CraftingTablesSystem from '../systems/CraftingTablesSystem.js'; +import BakeryShopSystem from '../systems/BakeryShopSystem.js'; + +export default class MainGameScene extends Phaser.Scene { + create() { + // Initialize all systems + this.sleepSystem = new SleepSystem(this); + this.craftingSystem = new CraftingTablesSystem(this); + this.bakerySystem = new BakeryShopSystem(this); + + // Register globally + this.game.registry.set('sleepSystem', this.sleepSystem); + this.game.registry.set('craftingSystem', this.craftingSystem); + this.game.registry.set('bakerySystem', this.bakerySystem); + + // Set up event listeners + this.setupSystemEvents(); + } + + setupSystemEvents() { + // Sleep events + this.sleepSystem.game.on('wakeUp', (data) => { + this.onPlayerWakeUp(data); + }); + + // Crafting events + this.craftingSystem.game.on('craftingCompleted', (data) => { + this.onCraftingComplete(data); + }); + + // Bakery events (if needed) + // ... + } + + update(time, delta) { + const deltaSeconds = delta / 1000; + + // Update systems + this.sleepSystem.update(deltaSeconds); + this.craftingSystem.update(deltaSeconds); + this.bakerySystem.update(); + } +} +``` + +**Save/Load Integration:** +```javascript +// Save game state +saveGame() { + const saveData = { + player: this.player.getSaveData(), + sleepSystem: { + playerBed: this.sleepSystem.playerBed, + unlockedBeds: Object.values(this.sleepSystem.bedTypes) + .filter(bed => bed.unlocked) + .map(bed => bed.id) + }, + craftingSystem: { + currentTable: this.craftingSystem.currentTable.id, + unlockedRecipes: this.craftingSystem.unlockedRecipes, + largeTableUnlocked: this.craftingSystem.tables.LARGE.unlocked + }, + bakerySystem: { + isUnlocked: this.bakerySystem.isUnlocked, + birthdayOrders: this.bakerySystem.birthdayCakeOrders + } + }; + + localStorage.setItem('game_save', JSON.stringify(saveData)); +} + +// Load game state +loadGame() { + const saveData = JSON.parse(localStorage.getItem('game_save')); + + if (saveData) { + // Restore sleep system + saveData.sleepSystem.unlockedBeds.forEach(bedId => { + const bedType = Object.keys(this.sleepSystem.bedTypes) + .find(key => this.sleepSystem.bedTypes[key].id === bedId); + if (bedType) { + this.sleepSystem.bedTypes[bedType].unlocked = true; + } + }); + + // Restore crafting system + this.craftingSystem.tables.LARGE.unlocked = saveData.craftingSystem.largeTableUnlocked; + this.craftingSystem.unlockedRecipes = saveData.craftingSystem.unlockedRecipes; + + // Restore bakery system + this.bakerySystem.isUnlocked = saveData.bakerySystem.isUnlocked; + this.bakerySystem.birthdayCakeOrders = saveData.bakerySystem.birthdayOrders; + } +} +``` + +--- + +**Created:** January 4, 2026 +**Status:** Ready for implementation ✅