Skip to content

Commit 0e0f6df

Browse files
committed
explore updates
1 parent 701a527 commit 0e0f6df

File tree

16 files changed

+1438
-114
lines changed

16 files changed

+1438
-114
lines changed

src/components/game/IslandExplorer.tsx

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Uses vanilla Three.js engine for better performance
33

44
import { useState } from 'react'
5+
56
import { VanillaGameScene } from './scene/VanillaGameScene'
67
import { IntroOverlay } from './ui/IntroOverlay'
78
import { GameHUD } from './ui/GameHUD'
@@ -16,16 +17,40 @@ import { CompassIndicator } from './ui/CompassIndicator'
1617
import { GameOverOverlay } from './ui/GameOverOverlay'
1718
import { WinOverlay } from './ui/WinOverlay'
1819
import { StatsHUD } from './ui/StatsHUD'
20+
import { GameMachineProvider } from './machines/GameMachineProvider'
21+
import { ProgressionSync } from './machines/ProgressionSync'
22+
import { BadgeOverlay } from './ui/BadgeOverlay'
23+
24+
const LOADING_MESSAGES = [
25+
['Convincing the waves to behave...', 'They never listen'],
26+
['Teaching fish to avoid the boat...', 'Mixed results so far'],
27+
['Polishing the cannon balls...', 'Shiny = more damage, right?'],
28+
['Bribing the wind gods...', 'They only accept doubloons'],
29+
['Untangling the anchor chain...', 'Who even tied this?'],
30+
['Inflating the ocean...', 'It was looking a bit flat'],
31+
['Waking up the sea monsters...', 'Just kidding, letting them sleep'],
32+
['Calibrating the compass...', 'North is... that way. Probably.'],
33+
['Stocking up on seasickness bags...', 'Better safe than sorry'],
34+
['Negotiating with seagulls...', 'They want crackers'],
35+
['Waterproofing the treasure maps...', 'Learned that lesson the hard way'],
36+
['Training the AI pirates...', 'They keep missing on purpose'],
37+
['Generating procedural waves...', 'Each one is unique and special'],
38+
['Hiding easter eggs...', 'You will never find them all'],
39+
['Rendering exactly 7 million polygons...', 'Give or take a few'],
40+
]
1941

2042
function LoadingOverlay() {
43+
const [messageIndex] = useState(() =>
44+
Math.floor(Math.random() * LOADING_MESSAGES.length),
45+
)
46+
const [headline, subtext] = LOADING_MESSAGES[messageIndex]
47+
2148
return (
2249
<div className="absolute inset-0 bg-gradient-to-b from-sky-400 to-cyan-600 flex items-center justify-center z-50">
2350
<div className="text-center">
2451
<div className="w-16 h-16 mx-auto mb-4 border-4 border-white/30 border-t-white rounded-full animate-spin" />
25-
<p className="text-white text-lg font-medium">Loading assets...</p>
26-
<p className="text-white/60 text-sm mt-2">
27-
Preparing ocean, boats, and islands
28-
</p>
52+
<p className="text-white text-lg font-medium">{headline}</p>
53+
<p className="text-white/60 text-sm mt-2">{subtext}</p>
2954
</div>
3055
</div>
3156
)
@@ -35,38 +60,42 @@ export default function IslandExplorer() {
3560
const [isLoading, setIsLoading] = useState(true)
3661

3762
return (
38-
<div className="relative w-full h-[calc(100dvh-var(--navbar-height))] bg-sky-500">
39-
{/* Loading overlay */}
40-
{isLoading && <LoadingOverlay />}
63+
<GameMachineProvider>
64+
<ProgressionSync />
65+
<div className="relative w-full h-[calc(100dvh-var(--navbar-height))] bg-sky-500">
66+
{/* Loading overlay */}
67+
{isLoading && <LoadingOverlay />}
4168

42-
{/* 3D Scene */}
43-
<div className="absolute inset-0">
44-
<VanillaGameScene onLoadingChange={setIsLoading} />
45-
</div>
69+
{/* 3D Scene */}
70+
<div className="absolute inset-0">
71+
<VanillaGameScene onLoadingChange={setIsLoading} />
72+
</div>
4673

47-
{/* Vignette overlay for depth */}
48-
<div
49-
className="absolute inset-0 pointer-events-none"
50-
style={{
51-
background:
52-
'radial-gradient(ellipse at center, transparent 40%, rgba(0,20,40,0.3) 100%)',
53-
}}
54-
/>
74+
{/* Vignette overlay for depth */}
75+
<div
76+
className="absolute inset-0 pointer-events-none"
77+
style={{
78+
background:
79+
'radial-gradient(ellipse at center, transparent 40%, rgba(0,20,40,0.3) 100%)',
80+
}}
81+
/>
5582

56-
{/* UI Overlays */}
57-
<IntroOverlay />
58-
<UpgradeOverlay />
59-
<CompleteOverlay />
60-
<GameOverOverlay />
61-
<WinOverlay />
62-
<GameHUD />
63-
<StatsHUD />
64-
<Minimap />
65-
<IslandIndicator />
66-
<CompassIndicator />
67-
<TouchControls />
68-
<Shop />
69-
<DebugPanel />
70-
</div>
83+
{/* UI Overlays */}
84+
<IntroOverlay />
85+
<UpgradeOverlay />
86+
<CompleteOverlay />
87+
<GameOverOverlay />
88+
<WinOverlay />
89+
<BadgeOverlay />
90+
<GameHUD />
91+
<StatsHUD />
92+
<Minimap />
93+
<IslandIndicator />
94+
<CompassIndicator />
95+
<TouchControls />
96+
<Shop />
97+
<DebugPanel />
98+
</div>
99+
</GameMachineProvider>
71100
)
72101
}

src/components/game/engine/GameEngine.ts

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ export class GameEngine {
364364
const initialState = useGameStore.getState()
365365

366366
// Handle loading directly into battle stage (page reload while in battle)
367+
console.log('[Game Init] State:', {
368+
stage: initialState.stage,
369+
phase: initialState.phase,
370+
showcaseUnlocked: initialState.showcaseUnlocked,
371+
showcaseIslandsCount: initialState.showcaseIslands.length,
372+
worldBoundary: initialState.worldBoundary,
373+
})
367374
if (initialState.stage === 'battle' && initialState.phase === 'playing') {
368375
// Generate expanded islands if needed
369376
if (initialState.expandedIslands.length === 0) {
@@ -382,10 +389,21 @@ export class GameEngine {
382389
}
383390

384391
if (initialState.showcaseUnlocked && showcaseIslands.length === 0) {
392+
console.log(
393+
'[Game Init] Showcase was unlocked but no islands - fetching...',
394+
)
385395
// Fetch and generate showcase islands async
386396
fetchGameShowcases().then((showcases) => {
397+
console.log(
398+
'[Game Init] Fetched showcases for reload:',
399+
showcases.length,
400+
)
387401
if (showcases.length > 0) {
388402
const generated = generateShowcaseIslands(showcases)
403+
console.log(
404+
'[Game Init] Generated showcase islands:',
405+
generated.length,
406+
)
389407
initialState.setShowcaseIslands(generated)
390408
this.islands.setIslands(
391409
initialState.islands,
@@ -401,6 +419,11 @@ export class GameEngine {
401419
)
402420
}
403421
})
422+
} else {
423+
console.log('[Game Init] Showcase state:', {
424+
showcaseUnlocked: initialState.showcaseUnlocked,
425+
showcaseIslandsCount: showcaseIslands.length,
426+
})
404427
}
405428

406429
this.islands.setIslands(
@@ -530,8 +553,19 @@ export class GameEngine {
530553
}
531554

532555
// Showcase unlock (generate showcase islands - NOT corner islands yet)
556+
// Debug: Log showcase state on every subscription tick
557+
if (state.showcaseUnlocked !== prevShowcaseUnlocked) {
558+
console.log('[Game] Showcase state changed:', {
559+
showcaseUnlocked: state.showcaseUnlocked,
560+
prevShowcaseUnlocked,
561+
showcaseIslandsCount: state.showcaseIslands.length,
562+
})
563+
}
533564
if (state.showcaseUnlocked && !prevShowcaseUnlocked) {
534565
prevShowcaseUnlocked = true
566+
console.log(
567+
'[Game] Showcase unlocked! Expanding world and generating showcase islands...',
568+
)
535569

536570
// Expand world boundary for showcase zone
537571
state.setWorldBoundary(520)
@@ -541,24 +575,32 @@ export class GameEngine {
541575

542576
// Fetch and generate showcase islands async (no corner islands yet)
543577
if (state.showcaseIslands.length === 0) {
578+
console.log('[Game] Fetching showcase data...')
544579
fetchGameShowcases().then((showcases) => {
580+
console.log('[Game] Fetched showcases:', showcases.length)
545581
if (showcases.length > 0) {
546582
const generated = generateShowcaseIslands(showcases)
547-
state.setShowcaseIslands(generated)
583+
console.log(
584+
'[Game] Generated showcase islands:',
585+
generated.length,
586+
)
587+
// Get fresh state for current islands
588+
const currentState = useGameStore.getState()
589+
currentState.setShowcaseIslands(generated)
548590

549591
// Update islands entity with showcase islands
550592
this.islands.setIslands(
551-
state.islands,
552-
state.expandedIslands,
593+
currentState.islands,
594+
currentState.expandedIslands,
553595
generated,
554-
state.cornerIslands,
596+
currentState.cornerIslands,
555597
)
556598
// Update ocean gradients
557599
this.updateOceanIslandPositions(
558-
state.islands,
559-
state.expandedIslands,
600+
currentState.islands,
601+
currentState.expandedIslands,
560602
generated,
561-
state.cornerIslands,
603+
currentState.cornerIslands,
562604
)
563605
}
564606
})

src/components/game/engine/systems/BoatControlSystem.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,26 @@ import { getPointerState } from '../../ui/TouchControls'
99

1010
import type { ShipStats } from '../../utils/upgrades'
1111

12-
const MIN_BOAT_SPEED = 3
13-
const MAX_BOAT_SPEED = 10
14-
const MIN_REVERSE_SPEED = 1.5
15-
const MAX_REVERSE_SPEED = 5
12+
// Base speed increased - coins no longer affect speed
13+
const BASE_BOAT_SPEED = 8
14+
const BASE_REVERSE_SPEED = 4
1615
const BASE_TURN_SPEED = 2.2
1716
const DRAG = 0.96
18-
const BASE_ACCELERATION = 0.12
17+
const BASE_ACCELERATION = 0.15
1918
const BOAT_RADIUS = 0.8
20-
const MAX_COINS = 50
2119

2220
function getMaxSpeed(
23-
coinsCollected: number,
2421
isReverse: boolean,
2522
hasSpeedBoost: boolean,
2623
shipStats: ShipStats,
24+
permSpeedBoosts: number,
2725
): number {
28-
const ratio = Math.min(coinsCollected / MAX_COINS, 1)
29-
let speed: number
30-
if (isReverse) {
31-
speed = MIN_REVERSE_SPEED + ratio * (MAX_REVERSE_SPEED - MIN_REVERSE_SPEED)
32-
} else {
33-
speed = MIN_BOAT_SPEED + ratio * (MAX_BOAT_SPEED - MIN_BOAT_SPEED)
34-
}
26+
// Base speed, no longer affected by coins
27+
let speed = isReverse ? BASE_REVERSE_SPEED : BASE_BOAT_SPEED
3528
// Apply sail speed upgrade multiplier
3629
speed *= shipStats.sailSpeed
30+
// Apply purchased permanent speed boosts (+10% each)
31+
speed *= Math.pow(1.1, permSpeedBoosts)
3732
// Apply speed boost from shop item
3833
return hasSpeedBoost ? speed * 2 : speed
3934
}
@@ -99,7 +94,9 @@ export class BoatControlSystem {
9994
}
10095
if (e.code === 'Space' && !e.repeat) {
10196
e.preventDefault()
102-
if (shipStats.gatlingGuns) {
97+
const { purchasedBoosts } = useGameStore.getState()
98+
// Track space held for gatling or rapid fire (auto-loader)
99+
if (shipStats.gatlingGuns || purchasedBoosts.rapidFire) {
103100
this.spaceHeld = true
104101
}
105102
fireCannon()
@@ -147,9 +144,9 @@ export class BoatControlSystem {
147144
cornerIslands,
148145
stage,
149146
rockColliders,
150-
coinsCollected,
151147
shipStats,
152148
speedBoostEndTime,
149+
purchasedBoosts,
153150
setBoatPosition,
154151
setBoatRotation,
155152
setBoatVelocity,
@@ -167,27 +164,36 @@ export class BoatControlSystem {
167164
fireGatling()
168165
}
169166

167+
// Fire side cannons while space is held (auto-loader)
168+
if (this.spaceHeld && purchasedBoosts.rapidFire) {
169+
const { fireCannon } = useGameStore.getState()
170+
fireCannon()
171+
}
172+
170173
const dt = Math.min(delta, 0.1)
171174

172175
const hasSpeedBoost = !!(
173176
speedBoostEndTime && Date.now() < speedBoostEndTime
174177
)
175178
const maxForwardSpeed = getMaxSpeed(
176-
coinsCollected,
177179
false,
178180
hasSpeedBoost,
179181
shipStats,
182+
purchasedBoosts.permSpeed,
180183
)
181184
const maxReverseSpeed = getMaxSpeed(
182-
coinsCollected,
183185
true,
184186
hasSpeedBoost,
185187
shipStats,
188+
purchasedBoosts.permSpeed,
186189
)
187190

188-
// Apply upgrade multipliers
191+
// Apply upgrade multipliers + purchased permanent boosts
189192
const turnSpeed = BASE_TURN_SPEED * shipStats.turnRate
190-
const acceleration = BASE_ACCELERATION * shipStats.acceleration
193+
const acceleration =
194+
BASE_ACCELERATION *
195+
shipStats.acceleration *
196+
Math.pow(1.15, purchasedBoosts.permAccel)
191197

192198
const pointer = getPointerState()
193199

0 commit comments

Comments
 (0)