diff --git a/src/components/game/WebGPUGameCanvas.tsx b/src/components/game/WebGPUGameCanvas.tsx
index 189f08e0..85aae2fd 100644
--- a/src/components/game/WebGPUGameCanvas.tsx
+++ b/src/components/game/WebGPUGameCanvas.tsx
@@ -203,7 +203,7 @@ export function WebGPUGameCanvas() {
});
// Input handling hook
- const { selectionState, handleMouseDown, handleMouseMove, handleMouseUp, handleContextMenu } = useGameInput({
+ const { selectionState } = useGameInput({
containerRef,
cameraRef: refs.camera,
gameRef,
@@ -646,10 +646,6 @@ export function WebGPUGameCanvas() {
{/* Loading screen */}
{isLoading && (
diff --git a/src/components/game/hooks/useGameInput.ts b/src/components/game/hooks/useGameInput.ts
index 74d7394b..73c9402f 100644
--- a/src/components/game/hooks/useGameInput.ts
+++ b/src/components/game/hooks/useGameInput.ts
@@ -49,14 +49,6 @@ export interface UseGameInputProps {
export interface UseGameInputReturn {
selectionState: SelectionState;
- /** @deprecated Use InputManager.getInstance() directly */
- handleMouseDown: (e: React.MouseEvent) => void;
- /** @deprecated Use InputManager.getInstance() directly */
- handleMouseMove: (e: React.MouseEvent) => void;
- /** @deprecated Use InputManager.getInstance() directly */
- handleMouseUp: (e: React.MouseEvent) => void;
- /** @deprecated Use InputManager.getInstance() directly */
- handleContextMenu: (e: React.MouseEvent) => void;
}
// Default selection state for SSR or before initialization
@@ -185,39 +177,7 @@ export function useGameInput({
() => defaultSelectionState // Server snapshot
);
- // =============================================================================
- // LEGACY EVENT HANDLERS (for backwards compatibility)
- // =============================================================================
-
- // These are kept for backwards compatibility but are no longer needed
- // since InputManager handles events directly on the container
- const handleMouseDown = useCallback((e: React.MouseEvent) => {
- // Events are now handled by InputManager
- // This handler is kept for backwards compatibility
- }, []);
-
- const handleMouseMove = useCallback((e: React.MouseEvent) => {
- // Events are now handled by InputManager
- }, []);
-
- const handleMouseUp = useCallback((e: React.MouseEvent) => {
- // Events are now handled by InputManager
- }, []);
-
- const handleContextMenu = useCallback((e: React.MouseEvent) => {
- e.preventDefault();
- // Events are now handled by InputManager
- }, []);
-
- // =============================================================================
- // RETURN
- // =============================================================================
-
return {
selectionState,
- handleMouseDown,
- handleMouseMove,
- handleMouseUp,
- handleContextMenu,
};
}
diff --git a/src/data/maps/MapTypes.ts b/src/data/maps/MapTypes.ts
index 60cfc960..df4b8e40 100644
--- a/src/data/maps/MapTypes.ts
+++ b/src/data/maps/MapTypes.ts
@@ -74,28 +74,16 @@ export const TERRAIN_FEATURE_CONFIG: Record = {
- 0: 60, // Low ground
- 1: 140, // Mid ground
- 2: 220, // High ground
- };
- return mapping[level];
-}
+/** Standard elevation values for gameplay zones */
+export const ELEVATION_LOW = 60;
+export const ELEVATION_MID = 140;
+export const ELEVATION_HIGH = 220;
/**
* Convert 0-255 elevation to gameplay zone (low/mid/high)
@@ -249,22 +237,17 @@ export function createTerrainGrid(
width: number,
height: number,
defaultTerrain: TerrainType = 'ground',
- defaultElevation: ElevationLevel | Elevation = 1,
+ defaultElevation: Elevation = ELEVATION_MID,
defaultFeature: TerrainFeature = 'none'
): MapCell[][] {
const grid: MapCell[][] = [];
- // Convert legacy elevation if needed
- const elevation256 = typeof defaultElevation === 'number' && defaultElevation <= 2
- ? legacyElevationTo256(defaultElevation as ElevationLevel)
- : defaultElevation as Elevation;
-
for (let y = 0; y < height; y++) {
grid[y] = [];
for (let x = 0; x < width; x++) {
grid[y][x] = {
terrain: defaultTerrain,
- elevation: elevation256,
+ elevation: defaultElevation,
feature: defaultFeature,
textureId: Math.floor(Math.random() * 4), // Random texture variation
};
@@ -452,14 +435,9 @@ export function fillTerrainRect(
width: number,
height: number,
terrain: TerrainType,
- elevation?: ElevationLevel | Elevation,
+ elevation?: Elevation,
feature?: TerrainFeature
): void {
- // Convert legacy elevation if provided
- const elevation256 = elevation !== undefined
- ? (elevation <= 2 ? legacyElevationTo256(elevation as ElevationLevel) : elevation)
- : undefined;
-
for (let dy = 0; dy < height; dy++) {
for (let dx = 0; dx < width; dx++) {
const px = Math.floor(x + dx);
@@ -472,8 +450,8 @@ export function fillTerrainRect(
}
grid[py][px].terrain = terrain;
- if (elevation256 !== undefined) {
- grid[py][px].elevation = elevation256;
+ if (elevation !== undefined) {
+ grid[py][px].elevation = elevation;
}
if (feature !== undefined) {
grid[py][px].feature = feature;
@@ -491,14 +469,9 @@ export function fillTerrainCircle(
centerY: number,
radius: number,
terrain: TerrainType,
- elevation?: ElevationLevel | Elevation,
+ elevation?: Elevation,
feature?: TerrainFeature
): void {
- // Convert legacy elevation if provided
- const elevation256 = elevation !== undefined
- ? (elevation <= 2 ? legacyElevationTo256(elevation as ElevationLevel) : elevation)
- : undefined;
-
for (let y = -radius; y <= radius; y++) {
for (let x = -radius; x <= radius; x++) {
if (x * x + y * y <= radius * radius) {
@@ -512,8 +485,8 @@ export function fillTerrainCircle(
}
grid[py][px].terrain = terrain;
- if (elevation256 !== undefined) {
- grid[py][px].elevation = elevation256;
+ if (elevation !== undefined) {
+ grid[py][px].elevation = elevation;
}
if (feature !== undefined) {
grid[py][px].feature = feature;
@@ -577,7 +550,7 @@ export function createRampInTerrain(
* @param centerX - Center X of the platform
* @param centerY - Center Y of the platform
* @param radius - Radius of the buildable area
- * @param elevation - Elevation level (0, 1, or 2)
+ * @param elevation - Elevation value (0-255, use ELEVATION_LOW/MID/HIGH constants)
* @param cliffWidth - Width of the cliff ring around the platform (default 3)
*/
export function createRaisedPlatform(
@@ -585,10 +558,9 @@ export function createRaisedPlatform(
centerX: number,
centerY: number,
radius: number,
- elevation: ElevationLevel,
+ elevation: Elevation,
cliffWidth: number = 3
): void {
- const elevation256 = legacyElevationTo256(elevation);
const outerRadius = radius + cliffWidth;
for (let dy = -outerRadius; dy <= outerRadius; dy++) {
@@ -607,7 +579,7 @@ export function createRaisedPlatform(
// Inner buildable area
grid[py][px] = {
terrain: 'ground',
- elevation: elevation256,
+ elevation: elevation,
feature: 'none',
textureId: Math.floor(Math.random() * 4),
};
@@ -616,7 +588,7 @@ export function createRaisedPlatform(
if (!isRampOrNearRamp(grid, px, py, cliffWidth + 1)) {
grid[py][px] = {
terrain: 'unwalkable',
- elevation: elevation256,
+ elevation: elevation,
feature: 'cliff',
textureId: Math.floor(Math.random() * 4),
};
@@ -630,6 +602,7 @@ export function createRaisedPlatform(
/**
* Create a raised rectangular platform with cliff edges.
* Useful for bases that need non-circular shapes.
+ * @param elevation - Elevation value (0-255, use ELEVATION_LOW/MID/HIGH constants)
*/
export function createRaisedRect(
grid: MapCell[][],
@@ -637,10 +610,9 @@ export function createRaisedRect(
y: number,
width: number,
height: number,
- elevation: ElevationLevel,
+ elevation: Elevation,
cliffWidth: number = 3
): void {
- const elevation256 = legacyElevationTo256(elevation);
// Create outer cliff ring first
for (let dy = -cliffWidth; dy < height + cliffWidth; dy++) {
@@ -661,7 +633,7 @@ export function createRaisedRect(
// Inner buildable area
grid[py][px] = {
terrain: 'ground',
- elevation: elevation256,
+ elevation: elevation,
feature: 'none',
textureId: Math.floor(Math.random() * 4),
};
@@ -669,7 +641,7 @@ export function createRaisedRect(
// Cliff edge - buffer must be >= cliff width to ensure gap for ramps
grid[py][px] = {
terrain: 'unwalkable',
- elevation: elevation256,
+ elevation: elevation,
feature: 'cliff',
textureId: Math.floor(Math.random() * 4),
};
diff --git a/src/rendering/EnvironmentManager.ts b/src/rendering/EnvironmentManager.ts
index 8c974c65..968264c8 100644
--- a/src/rendering/EnvironmentManager.ts
+++ b/src/rendering/EnvironmentManager.ts
@@ -44,7 +44,7 @@ export class EnvironmentManager {
private waterMesh: WaterMesh | null = null;
private mapBorderFog: TSLMapBorderFog | null = null;
private particles: EnvironmentParticles | null = null;
- private legacyDecorations: MapDecorations | null = null;
+ private mapDecorations: MapDecorations | null = null;
// AAA decoration light manager - pools 50 lights for hundreds of emissive decorations
private decorationLightManager: DecorationLightManager | null = null;
// Centralized emissive decoration manager with animation and light attachment
@@ -269,8 +269,8 @@ export class EnvironmentManager {
}
// MapDecorations handles watch towers and destructibles (non-instanced objects)
- this.legacyDecorations = new MapDecorations(this.mapData, this.terrain, this.scene, this.decorationLightManager);
- this.scene.add(this.legacyDecorations.group);
+ this.mapDecorations = new MapDecorations(this.mapData, this.terrain, this.scene, this.decorationLightManager);
+ this.scene.add(this.mapDecorations.group);
}
/**
@@ -296,8 +296,8 @@ export class EnvironmentManager {
}
// Update emissive decoration pulsing animation
- if (this.legacyDecorations) {
- this.legacyDecorations.update(deltaTime);
+ if (this.mapDecorations) {
+ this.mapDecorations.update(deltaTime);
}
// Update emissive decoration manager (crystal pulsing, etc.)
@@ -781,7 +781,7 @@ export class EnvironmentManager {
if (this.waterMesh) this.scene.remove(this.waterMesh.group);
if (this.mapBorderFog) this.scene.remove(this.mapBorderFog.mesh);
if (this.particles) this.scene.remove(this.particles.points);
- if (this.legacyDecorations) this.scene.remove(this.legacyDecorations.group);
+ if (this.mapDecorations) this.scene.remove(this.mapDecorations.group);
// STEP 2: Now safe to dispose resources (no longer being rendered)
this.trees?.dispose();
@@ -794,7 +794,7 @@ export class EnvironmentManager {
this.waterMesh?.dispose();
this.mapBorderFog?.dispose();
this.particles?.dispose();
- this.legacyDecorations?.dispose();
+ this.mapDecorations?.dispose();
this.decorationLightManager?.dispose();
this.emissiveDecorationManager?.dispose();
this.emissiveLightPool?.dispose();
diff --git a/src/rendering/Terrain.ts b/src/rendering/Terrain.ts
index 868985b2..955b0e08 100644
--- a/src/rendering/Terrain.ts
+++ b/src/rendering/Terrain.ts
@@ -1,5 +1,5 @@
import * as THREE from 'three';
-import { MapData, MapCell, TerrainType, ElevationLevel, Elevation, TerrainFeature, TERRAIN_FEATURE_CONFIG } from '@/data/maps';
+import { MapData, MapCell, TerrainType, Elevation, TerrainFeature, TERRAIN_FEATURE_CONFIG } from '@/data/maps';
import { BiomeConfig, BIOMES, blendBiomeColors, BiomeType } from './Biomes';
import { TSLTerrainMaterial } from './tsl/TerrainMaterial';
import AssetManager from '@/assets/AssetManager';
diff --git a/src/utils/math.ts b/src/utils/math.ts
index 1d72a670..5082d03e 100644
--- a/src/utils/math.ts
+++ b/src/utils/math.ts
@@ -48,28 +48,6 @@ export function angle(x1: number, y1: number, x2: number, y2: number): number {
return Math.atan2(y2 - y1, x2 - x1);
}
-/**
- * @internal NON-DETERMINISTIC - DO NOT USE IN GAMEPLAY CODE
- * Uses Math.random() which breaks multiplayer sync. For gameplay randomness,
- * use SeededRandom instead. This function exists only for non-gameplay uses
- * like UI effects or debugging.
- * @deprecated Use SeededRandom.nextRange() for deterministic gameplay
- */
-export function randomRange(min: number, max: number): number {
- return min + Math.random() * (max - min);
-}
-
-/**
- * @internal NON-DETERMINISTIC - DO NOT USE IN GAMEPLAY CODE
- * Uses Math.random() which breaks multiplayer sync. For gameplay randomness,
- * use SeededRandom instead. This function exists only for non-gameplay uses
- * like UI effects or debugging.
- * @deprecated Use SeededRandom.nextInt() for deterministic gameplay
- */
-export function randomInt(min: number, max: number): number {
- return Math.floor(randomRange(min, max + 1));
-}
-
// Seeded random for deterministic gameplay
export class SeededRandom {
private seed: number;
diff --git a/tests/utils/math.test.ts b/tests/utils/math.test.ts
index 411cf038..a2c6f56c 100644
--- a/tests/utils/math.test.ts
+++ b/tests/utils/math.test.ts
@@ -8,8 +8,6 @@ import {
distanceXY,
normalize,
angle,
- randomRange,
- randomInt,
SeededRandom,
} from '@/utils/math';
@@ -47,16 +45,6 @@ describe('math utilities', () => {
expect(angle(0, 0, 0, 1)).toBe(Math.PI / 2);
});
- it('uses Math.random for non-deterministic helpers', () => {
- const originalRandom = Math.random;
- Math.random = () => 0.5;
-
- expect(randomRange(0, 10)).toBe(5);
- expect(randomInt(0, 9)).toBe(5);
-
- Math.random = originalRandom;
- });
-
it('generates deterministic sequences with SeededRandom', () => {
const rngA = new SeededRandom(42);
const rngB = new SeededRandom(42);