Skip to content

Commit 3fa7bd3

Browse files
G-Fourteenclaude
andcommitted
Fix tutorial markets, M key toggle, merchant gold, and TTS fallback
- game.js: Add toggleMarket() function for M key toggle - game.js: Update M key handler to use toggleMarket() - npc-merchants.js: Add MIN_MERCHANT_GOLD = 500 for minimum gold - npc-merchants.js: Fix calculateMerchantWealth to ensure min gold - npc-voice.js: Remove browser TTS fallback - Kokoro AI only - tutorial-manager.js: Add merchant generation for tutorial locations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c7aa852 commit 3fa7bd3

4 files changed

Lines changed: 57 additions & 36 deletions

File tree

src/js/core/game.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6209,6 +6209,24 @@ function closeMarket() {
62096209
changeState(GameState.PLAYING);
62106210
}
62116211

6212+
// 🖤 TOGGLE MARKET - open if closed, close if open 💀
6213+
function toggleMarket() {
6214+
const marketPanel = document.getElementById('market-panel');
6215+
const isVisible = marketPanel && (
6216+
marketPanel.classList.contains('active') ||
6217+
marketPanel.classList.contains('show') ||
6218+
marketPanel.style.display === 'block' ||
6219+
marketPanel.style.display === 'flex' ||
6220+
game.state === GameState.MARKET
6221+
);
6222+
6223+
if (isVisible) {
6224+
closeMarket();
6225+
} else {
6226+
openMarket();
6227+
}
6228+
}
6229+
62126230
function updateMarketHeader() {
62136231
const location = GameWorld.locations[game.currentLocation.id];
62146232
if (!location) return;
@@ -8250,10 +8268,9 @@ function handleKeyPress(event) {
82508268
break;
82518269
case 'm':
82528270
case 'M':
8253-
if (game.state === GameState.PLAYING) {
8254-
openMarket();
8255-
} else if (game.state === GameState.MARKET) {
8256-
closeMarket();
8271+
// Toggle market - works from most states
8272+
if (game.state === GameState.PLAYING || game.state === GameState.MARKET) {
8273+
toggleMarket();
82578274
}
82588275
break;
82598276
case 't':

src/js/npc/npc-merchants.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -154,35 +154,39 @@ const NPCMerchantSystem = {
154154

155155
// tally this puppet's wealth by counting their inventory - gold equals stock value
156156
calculateMerchantWealth(merchant) {
157-
if (!merchant || !merchant.location) return;
157+
if (!merchant || !merchant.location) return 0;
158+
159+
// Minimum starting gold so merchants can always trade
160+
const MIN_MERCHANT_GOLD = 500;
158161

159162
const location = GameWorld?.locations?.[merchant.location];
160-
if (!location || !location.marketPrices) return;
161163

162164
let totalInventoryValue = 0;
163165
let startingStock = {};
164166

165167
// sum the value of every item this merchant hoards - their net worth
166-
Object.entries(location.marketPrices).forEach(([itemId, marketData]) => {
167-
const item = ItemDatabase?.getItem?.(itemId);
168-
if (item && marketData.stock > 0) {
169-
const itemValue = (marketData.price || item.basePrice || 10) * marketData.stock;
170-
totalInventoryValue += itemValue;
171-
172-
// Track starting stock for day if not already tracked
173-
if (!marketData.startingDayStock) {
174-
marketData.startingDayStock = marketData.stock;
168+
if (location && location.marketPrices) {
169+
Object.entries(location.marketPrices).forEach(([itemId, marketData]) => {
170+
const item = ItemDatabase?.getItem?.(itemId);
171+
if (item && marketData.stock > 0) {
172+
const itemValue = (marketData.price || item.basePrice || 10) * marketData.stock;
173+
totalInventoryValue += itemValue;
174+
175+
// Track starting stock for day if not already tracked
176+
if (!marketData.startingDayStock) {
177+
marketData.startingDayStock = marketData.stock;
178+
}
179+
startingStock[itemId] = marketData.startingDayStock;
175180
}
176-
startingStock[itemId] = marketData.startingDayStock;
177-
}
178-
});
181+
});
182+
}
179183

180-
// Merchant gold = total inventory value (they can afford to buy back their stock)
181-
merchant.maxGold = totalInventoryValue;
182-
merchant.currentGold = merchant.currentGold ?? totalInventoryValue;
184+
// Merchant gold = total inventory value, but minimum 500 gold so they can trade
185+
merchant.maxGold = Math.max(MIN_MERCHANT_GOLD, totalInventoryValue);
186+
merchant.currentGold = merchant.currentGold ?? merchant.maxGold;
183187
merchant.startingStock = startingStock;
184188

185-
return totalInventoryValue;
189+
return merchant.maxGold;
186190
},
187191

188192
// does this hollow merchant have enough gold? check their wallet before purchasing

src/js/npc/npc-voice.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,23 +1197,15 @@ RELATIONSHIP MEMORY:
11971197
const status = typeof KokoroTTS !== 'undefined'
11981198
? (KokoroTTS.isLoading && KokoroTTS.isLoading() ? 'loading' : 'not initialized')
11991199
: 'not loaded';
1200-
console.log(`🎙️ KokoroTTS ${status}, falling back to browser TTS`);
1200+
console.log(`🎙️ KokoroTTS ${status} - no voice output (browser TTS disabled)`);
1201+
// No fallback to browser TTS - Kokoro only!
1202+
return;
12011203
}
1202-
// Fall through to browser TTS as fallback when Kokoro not ready
12031204
}
12041205

1205-
// 🔊 BROWSER TTS (basic computer voice OR fallback from Kokoro)
1206-
console.log('🎙️ Using browser TTS');
1207-
const chunks = this.splitTextIntoChunks(cleanText, 1000);
1208-
1209-
const voice = voiceOverride || this.settings.voice;
1210-
chunks.forEach(chunk => {
1211-
this.voiceQueue.push({ text: chunk, voice: voice });
1212-
});
1213-
1214-
if (!this.isPlayingVoice) {
1215-
this.playNextVoiceChunk();
1216-
}
1206+
// 🎙️ Kokoro engine not selected, skip voice
1207+
console.log('🎙️ Voice engine not kokoro, skipping voice output');
1208+
return;
12171209

12181210
} catch (error) {
12191211
// voice playback failed - continue without voice

src/js/systems/tutorial/tutorial-manager.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ const TutorialManager = {
319319
console.log('🎓 Tutorial market prices initialized');
320320
}
321321

322+
// CRITICAL: Regenerate merchants for tutorial locations!
323+
// Without this, market shows "Unknown" merchant with 0 gold
324+
if (typeof NPCMerchantSystem !== 'undefined') {
325+
NPCMerchantSystem.generateMerchants();
326+
NPCMerchantSystem.initializeMerchantEconomy();
327+
console.log('🎓 Tutorial merchants generated');
328+
}
329+
322330
// FIX: Refresh game.currentLocation to prevent stale object references
323331
// After tutorial world reload, the old location reference may be invalid
324332
if (typeof game !== 'undefined' && game.currentLocation?.id) {

0 commit comments

Comments
 (0)