User prompt
I can’t see rocks spawning. Debug and fix.
User prompt
Update with: if (LK.ticks - lastRockTime > 120 + Math.random() * 180) { lastRockTime = LK.ticks; var rock = game.addChild(new Rock()); rock.x = 2548; rock.y = 2732 + 200; // Place base below screen // Set the vertical scale independently for random height rock.children[0].scaleY = 3 + Math.random() * 4; // Random height between 3x and 7x rocks.push(rock); }
User prompt
Update with: var Rock = Container.expand(function() { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 0 // Anchor to top since we're stretching upward }); // Set scales independently rock.scaleX = 2; rock.scaleY = 2; // Start with a base scale self.update = function() { self.x -= 8; if (self.x < -self.width) { self.destroy(); } }; return self; });
User prompt
Update with: if (LK.ticks - lastRockTime > 120 + Math.random() * 180) { lastRockTime = LK.ticks; var rock = game.addChild(new Rock()); rock.x = 2548; rock.y = 2732 + 200; // Place base below screen // Scale rock rock.scale.x = 2; // Make it wider rock.scale.y = 3 + Math.random() * 4; // Random height between 3x and 7x original size rocks.push(rock); }
User prompt
Update with: var Rock = Container.expand(function() { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 1 // Anchor to bottom }); self.update = function() { self.x -= 8; if (self.x < -self.width) { self.destroy(); } }; return self; });
User prompt
Update with: // Rock spawning if (LK.ticks - lastRockTime > 120 + Math.random() * 180) { lastRockTime = LK.ticks; var rock = game.addChild(new Rock()); rock.x = 2548; // Start off right side // Position all rocks at bottom of screen rock.y = 2732 + 200; // Base is below screen bottom // Vary the height - rocks will stretch upward from the base var minHeight = 800; // Minimum height to poke above water var maxHeight = 1800; // Maximum height (about mid-screen) var rockHeight = minHeight + Math.random() * (maxHeight - minHeight); rock.setHeight(rockHeight); rocks.push(rock); }
User prompt
Update with: var Rock = Container.expand(function() { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 0 // Anchor to top since we're stretching upward }); // Make rocks wider rock.scale.x = 2; // Height will be set when spawned self.setHeight = function(targetHeight) { rock.height = targetHeight; self.width = rock.width * rock.scale.x; self.height = targetHeight; }; self.update = function() { self.x -= 8; if (self.x < -self.width) { self.destroy(); } }; return self; });
User prompt
Update with: if (LK.ticks - lastRockTime > 120 + Math.random() * 180) { lastRockTime = LK.ticks; var rock = game.addChild(new Rock()); rock.x = 2548; // Start off right side // Position rocks mostly underwater, with tops jutting out var baseY = 2732 * 0.85; // This matches the wave system's baseY var heightVariation = 300; // How much the height varies rock.y = baseY + heightVariation + Math.random() * heightVariation; rocks.push(rock); }
User prompt
Update with: var Rock = Container.expand(function() { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 1 // Anchor to bottom so it emerges from water }); // Make rocks much larger rock.scale.set(3, 3); // Triple the size self.width = rock.width * rock.scale.x; self.height = rock.height * rock.scale.y; self.update = function() { self.x -= 8; if (self.x < -self.width) { self.destroy(); } }; return self; });
Code edit (2 edits merged)
Please save this source code
User prompt
Add this class: var Rock = Container.expand(function() { var self = Container.call(this); var rock = self.attachAsset('island', { anchorX: 0.5, anchorY: 0 }); self.width = rock.width; self.height = rock.height; // Move right to left self.update = function() { self.x -= 8; // Adjust speed as needed // Remove if off screen if (self.x < -self.width) { self.destroy(); } }; return self; });
User prompt
Update with: // And optionally reduce the vertical rotation impact if (verticalSpeed < -2) { // Moving up verticalRotation = Math.min(0.3, -verticalSpeed * 0.005); // Changed from 0.01 } else if (verticalSpeed > 2) { // Moving down verticalRotation = Math.max(-0.4, -verticalSpeed * 0.005); // Changed from 0.01 }
User prompt
Update with: // Slow down the rotation response velocityRot += (baseRotation + waveRotation + verticalRotation - self.rotation) * 0.05; // Changed from 0.1 velocityRot *= 0.9; // Changed from 0.8 for less damping
User prompt
Update as needed with: // Calculate vertical movement speed var verticalSpeed = self.y - lastWaveY; // Add rotation based on vertical movement var verticalRotation = 0; if (verticalSpeed < -2) { // Moving up verticalRotation = Math.min(0.3, -verticalSpeed * 0.01); // Rotate forward when going up } else if (verticalSpeed > 2) { // Moving down verticalRotation = Math.max(-0.4, -verticalSpeed * 0.01); // Rotate back when falling }
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: var WaterParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('wave_point', { anchorX: 0.5, anchorY: 0.5 }); var speed, angle, scale; self.init = function (type) { // Reset properties scale = 1; self.type = type; if (type === 'trail') { speed = Math.random() * 8 + 6; angle = Math.PI + (Math.random() * 0.4 - 0.2); scale = 0.7; particleGraphics.alpha = 0.8; } else { speed = Math.random() * 12 + 8; angle = -Math.PI / 2 + (Math.random() * 1.4 - 0.7); scale = 1.2; particleGraphics.alpha = 0.9; } self.scale.set(scale, scale); }; self.update = function () { scale -= self.type === 'splash' ? 0.04 : 0.02; self.scale.set(scale, scale); if (scale <= 0) { // Instead of destroying, return to pool if (self.parent) { self.parent.removeChild(self); } ParticlePool.return(self); return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; }; return self; });
User prompt
Add this: var ParticlePool = { pool: [], maxSize: 200, get: function() { if (this.pool.length > 0) { var particle = this.pool.pop(); particle.visible = true; return particle; } return new WaterParticle(); }, return: function(particle) { if (this.pool.length < this.maxSize) { // Reset particle properties particle.visible = false; particle.scale.set(1, 1); particle.x = 0; particle.y = 0; particle.rotation = 0; this.pool.push(particle); } else { particle.destroy(); } } };
User prompt
Update wave system with: self.update = function() { var targetPitch = 0; if (facekit.volume > 0.15) { var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH); normalizedPitch = Math.max(0, Math.min(1, normalizedPitch)); targetPitch = normalizedPitch * 0.8 + lastPitch * 0.2; } lastPitch += (targetPitch - lastPitch) * 0.2; var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT); points = []; for (var i = 0; i < NUM_POINTS; i++) { var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH; var distanceFromCenter = (x - SCREEN_WIDTH * 0.35) / (SCREEN_WIDTH * 0.45); var heightFactor = gaussianCurve(distanceFromCenter); var y = baseY - smoothedHeight * heightFactor; points.push({x: x, y: y}); } // Update water rectangles for (var i = 0; i < NUM_WATER_SECTIONS; i++) { var rect = waterRects[i]; var xPosition = i / NUM_WATER_SECTIONS * SCREEN_WIDTH; var exactPointPosition = xPosition / SCREEN_WIDTH * (NUM_POINTS - 1); var pointIndex = Math.floor(exactPointPosition); var nextPointIndex = Math.min(pointIndex + 1, NUM_POINTS - 1); var progress = exactPointPosition - pointIndex; var y1 = points[pointIndex].y; var y2 = points[nextPointIndex].y; var y = y1 + (y2 - y1) * progress; rect.x = xPosition; rect.y = y; rect.height = 2732 - y; rect.alpha = 0.3 + Math.sin(LK.ticks * 0.02 + i * 0.2) * 0.02; } self.points = points; }; ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: currentPoint is undefined' in or related to this line: 'var targetY = currentPoint.y + (nextPoint.y - currentPoint.y) * progress + WAVE_OFFSET;' Line Number: 90
User prompt
update with: self.update = function() { // Only update wave physics on certain frames if (LK.ticks % WAVE_UPDATE_INTERVAL === 0) { // Do intensive wave calculations // Update points array // Update water rectangles }
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: // Then modify the update call: game.update = function() { var now = Date.now(); if (now - lastUpdateTime < 16) { return; } lastUpdateTime = now; waveSystem.update(); surfer.update(); particles.update(); // Only update score/multiplier text when values change var currentScore = Math.floor(score); if (currentScore !== lastScoreDisplay) { lastScoreDisplay = currentScore; scoreText.setText(currentScore.toLocaleString()); } var currentMultiplier = Math.floor(multiplier * 10) / 10; // Round to 1 decimal if (currentMultiplier !== lastMultiplierDisplay) { lastMultiplierDisplay = currentMultiplier; multiplierText.setText("x" + currentMultiplier.toFixed(1)); } };
User prompt
Update with: // Before (current code) scoreText.setText(Math.floor(score).toLocaleString()); multiplierText.setText("x" + multiplier.toFixed(1)); // Let's modify to only update when they actually change // Add to game initialization section: var lastScoreDisplay = -1; var lastMultiplierDisplay = -1;
User prompt
update with: // In WaveSystem constructor, where we create lines var lines = []; function createLines() { // Clean up any existing lines first lines.forEach(line => { line.destroy(); self.removeChild(line); }); lines = []; // Create new lines for (var i = 0; i < NUM_POINTS - 1; i++) { var line = self.attachAsset('wave_line', { anchorX: 0, anchorY: 0.5, height: 4 }); lines.push(line); } } // Call initial creation createLines();
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
var ParticleSystem = Container.expand(function () {
	var self = Container.call(this);
	self.addWaterParticle = function (x, y, type) {
		var particle = ParticlePool.get();
		if (type === 'trail') {
			// Move spawn point up and behind surfer
			particle.x = x - 100; // Spawn behind (to the right of) surfer
			particle.y = y + 10; // Raised up from previous +90
		} else {
			// Keep original splash positioning
			particle.x = x + Math.random() * 130 - 40;
			particle.y = y - 20;
		}
		particle.init(type);
		self.addChild(particle);
	};
	self.update = function () {
		for (var i = self.children.length - 1; i >= 0; i--) {
			var particle = self.children[i];
			if (particle.update) {
				particle.update();
			}
			// Remove particles that have moved far off screen
			if (particle.x < -500 || particle.x > 2548 || particle.y < -500 || particle.y > 3232) {
				ParticlePool["return"](particle);
				self.removeChild(particle);
			}
		}
	};
	return self;
});
var Surfer = Container.expand(function () {
	var self = Container.call(this);
	var BASE_GRAVITY = 1.5; // Reduced for smoother acceleration
	var MAX_SPEED = 40; // Increased for longer falls
	var DAMPENING = 0.98; // Less dampening for smoother motion
	var WAVE_OFFSET = -30;
	var FIXED_X = 2048 * 0.35;
	var MAX_AIR_VELOCITY = -25; // Only applies when surfer is above wave
	var velocityY = 0;
	var velocityRot = 0;
	var activeTween = null; // Initialize activeTween variable
	var lastWaveY = 2732 * 0.85; // Match WaveSystem's baseY
	var initialized = false;
	var surferGraphics = self.attachAsset('surfer', {
		anchorX: 0.5,
		anchorY: 0.8
	});
	self.x = FIXED_X;
	self.y = lastWaveY + WAVE_OFFSET; // Start at base wave height
	self.setWaveSystem = function (ws) {
		waveSystem = ws;
		if (!waveSystem.points) {
			waveSystem.points = [];
		}
		initialized = true;
	};
	self.update = function () {
		// Add tween cleanup
		if (activeTween) {
			tween.stop(activeTween);
		}
		if (!waveSystem) {
			return;
		}
		var normalizedX = self.x / 2048;
		var pointIndex = Math.floor(normalizedX * (waveSystem.points.length - 1));
		var nextPointIndex = Math.min(pointIndex + 1, waveSystem.points.length - 1);
		var progress = normalizedX * (waveSystem.points.length - 1) - pointIndex;
		var currentPoint = waveSystem.points[pointIndex];
		var nextPoint = waveSystem.points[nextPointIndex];
		var targetY = currentPoint.y + (nextPoint.y - currentPoint.y) * progress + WAVE_OFFSET;
		var waveRising = targetY < lastWaveY;
		var aboveWave = self.y < targetY;
		if (waveRising && !aboveWave) {
			// Natural wave following - no limits when on the wave
			velocityY = (targetY - self.y) * 0.2;
			self.y += velocityY;
		} else {
			// In air or falling
			velocityY += BASE_GRAVITY;
			velocityY *= DAMPENING;
			// Only cap velocity when above the wave
			if (aboveWave && velocityY < MAX_AIR_VELOCITY) {
				velocityY = MAX_AIR_VELOCITY;
			}
			self.y += velocityY;
			if (self.y > targetY && velocityY > 0) {
				var fallVelocity = velocityY; // Capture velocity before reset
				self.y = targetY;
				velocityY = 0;
				if (aboveWave && fallVelocity > 15) {
					// Only splash on significant falls
					//createSplash();
				}
			}
		}
		lastWaveY = targetY;
		// Create trail particles whenever touching water
		if (self.y >= targetY) {
			//createTrail();
		}
		var targetAngle = Math.atan2(nextPoint.y - currentPoint.y, nextPoint.x - currentPoint.x);
		// ... rest of the rotation code ...
		particles.children.forEach(function (particle) {
			if (particle.update) {
				particle.update();
			}
		});
	};
	self.getScore = function () {
		return Math.floor(score);
	};
	// Then in the Surfer class, replace the particle system with:
	var particles = self.addChild(new ParticleSystem());
	function createSplash() {
		for (var i = 0; i < 50; i++) {
			// Move splash up by 40 to match trail Y position
			game.particles.addWaterParticle(FIXED_X, self.y + 40, 'splash');
		}
	}
	function createTrail() {
		// Create fewer particles but more frequently for trail
		for (var i = 0; i < 4; i++) {
			game.particles.addWaterParticle(FIXED_X, self.y, 'trail');
		}
	}
	return self;
});
var WaterParticle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('wave_point', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var speed = Math.random() * 3;
	var angle = -Math.random() * Math.PI;
	var scale = 1;
	// Add a type parameter to determine behavior
	self.init = function (type) {
		if (type === 'trail') {
			speed = Math.random() * 8 + 6; // Increased from 6 + 4
			angle = Math.PI + (Math.random() * 0.4 - 0.2); // Slightly wider spread
			scale = 0.7;
			particleGraphics.alpha = 0.8; // Start slightly less than full alpha
		} else {
			//{N}  // splash
			speed = Math.random() * 12 + 8; // Increased from 8 + 6
			angle = -Math.PI / 2 + (Math.random() * 1.4 - 0.7); // Wider arc spread
			scale = 1.2;
			particleGraphics.alpha = 0.9; // Start slightly less than full alpha
		}
	};
	self.update = function () {
		scale -= self.type === 'splash' ? 0.04 : 0.02; // Double fade speed for splash
		self.scaleX = scale;
		self.scaleY = scale;
		if (scale <= 0) {
			self.destroy();
		}
		self.x += Math.cos(angle) * speed;
		self.y += Math.sin(angle) * speed;
	};
	self.destroy = function () {
		if (self.parent) {
			self.parent.removeChild(self);
		}
		Container.prototype.destroy.call(this);
	};
	return self;
});
var WaveSystem = Container.expand(function () {
	var self = Container.call(this);
	var NUM_POINTS = 40;
	var SCREEN_WIDTH = 2048;
	var points = [];
	var baseY = 2732 * 0.85;
	var MIN_PITCH = 50;
	var MAX_PITCH = 300;
	var WAVE_HEIGHT = 2300;
	var lastPitch = 0;
	// Enhanced smoothing system
	var heightBuffer = Array(15).fill(0);
	var bufferIndex = 0;
	var lastSmoothedHeight = 0;
	// Water fill rectangles
	var waterRects = [];
	var NUM_WATER_SECTIONS = 80; // Reduced from 80 
	for (var i = 0; i < NUM_WATER_SECTIONS; i++) {
		var rect = self.attachAsset('wave_line', {
			anchorX: 0.5,
			// Center anchor
			anchorY: 0,
			// Top anchor
			height: 2732,
			width: SCREEN_WIDTH / NUM_WATER_SECTIONS + 1,
			// Tiny overlap to prevent pixel gaps
			tint: 0x0066cc,
			alpha: 0.3
		});
		waterRects.push(rect);
	}
	// Create wave line segments
	var lines = [];
	function createLines() {
		// Clean up any existing lines first
		lines.forEach(function (line) {
			line.destroy();
			self.removeChild(line);
		});
		lines = [];
		// Create new lines
		for (var i = 0; i < NUM_POINTS - 1; i++) {
			var line = self.attachAsset('wave_line', {
				anchorX: 0,
				anchorY: 0.5,
				height: 4
			});
			lines.push(line);
		}
	}
	// Call initial creation
	createLines();
	function gaussianCurve(x) {
		return Math.exp(-(x * x) / 0.8);
	}
	function getSmoothedHeight(newHeight) {
		heightBuffer[bufferIndex] = newHeight;
		bufferIndex = (bufferIndex + 1) % heightBuffer.length;
		// Simplified smoothing calculation
		var total = 0;
		for (var i = 0; i < heightBuffer.length; i++) {
			total += heightBuffer[i];
		}
		var smoothedHeight = total / heightBuffer.length;
		lastSmoothedHeight = lastSmoothedHeight * 0.7 + smoothedHeight * 0.3;
		return lastSmoothedHeight;
	}
	self.update = function () {
		var targetPitch = 0;
		if (facekit.volume > 0.15) {
			var normalizedPitch = (facekit.pitch - MIN_PITCH) / (MAX_PITCH - MIN_PITCH);
			normalizedPitch = Math.max(0, Math.min(1, normalizedPitch));
			targetPitch = normalizedPitch * 0.8 + lastPitch * 0.2;
		}
		lastPitch += (targetPitch - lastPitch) * 0.2;
		var smoothedHeight = getSmoothedHeight(lastPitch * WAVE_HEIGHT);
		points = [];
		for (var i = 0; i < NUM_POINTS; i++) {
			var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH;
			var distanceFromCenter = (x - SCREEN_WIDTH * 0.35) / (SCREEN_WIDTH * 0.45);
			var heightFactor = gaussianCurve(distanceFromCenter);
			var y = baseY - smoothedHeight * heightFactor;
			points.push({
				x: x,
				y: y
			});
		}
		// Update water rectangles
		for (var i = 0; i < NUM_WATER_SECTIONS; i++) {
			var rect = waterRects[i];
			var xPosition = i / NUM_WATER_SECTIONS * SCREEN_WIDTH;
			var exactPointPosition = xPosition / SCREEN_WIDTH * (NUM_POINTS - 1);
			var pointIndex = Math.floor(exactPointPosition);
			var nextPointIndex = Math.min(pointIndex + 1, NUM_POINTS - 1);
			var progress = exactPointPosition - pointIndex;
			var y1 = points[pointIndex].y;
			var y2 = points[nextPointIndex].y;
			var y = y1 + (y2 - y1) * progress;
			rect.x = xPosition;
			rect.y = y;
			rect.height = 2732 - y;
			rect.alpha = 0.3 + Math.sin(LK.ticks * 0.02 + i * 0.2) * 0.02;
		}
		self.points = points;
		if (facekit.volume > 0.15) {
			score += smoothedHeight / WAVE_HEIGHT * multiplier;
			multiplier += 0.001;
		} else {
			multiplier = Math.max(1, multiplier - 0.01);
		}
		points = [];
		for (var i = 0; i < NUM_POINTS; i++) {
			var x = i / (NUM_POINTS - 1) * SCREEN_WIDTH;
			var distanceFromCenter = (x - SCREEN_WIDTH * 0.35) / (SCREEN_WIDTH * 0.45);
			var heightFactor = gaussianCurve(distanceFromCenter);
			var y = baseY - smoothedHeight * heightFactor;
			points.push({
				x: x,
				y: y
			});
		}
		// Update water rectangles
		for (var i = 0; i < NUM_WATER_SECTIONS; i++) {
			var rect = waterRects[i];
			var xPosition = i / NUM_WATER_SECTIONS * SCREEN_WIDTH;
			// Match x positions exactly with wave points
			var exactPointPosition = xPosition / SCREEN_WIDTH * (NUM_POINTS - 1);
			var pointIndex = Math.floor(exactPointPosition);
			var nextPointIndex = Math.min(pointIndex + 1, NUM_POINTS - 1);
			// Precise interpolation
			var progress = exactPointPosition - pointIndex;
			var y1 = points[pointIndex].y;
			var y2 = points[nextPointIndex].y;
			var y = y1 + (y2 - y1) * progress;
			// Align exactly with wave position
			rect.x = xPosition;
			rect.y = y;
			rect.height = 2732 - y;
			// Very subtle alpha variation
			rect.alpha = 0.3 + Math.sin(LK.ticks * 0.02 + i * 0.2) * 0.02;
		}
		self.points = points;
		// Update wave line segments
		for (var i = 0; i < lines.length; i++) {
			var start = points[i];
			var end = points[i + 1];
			var dx = end.x - start.x;
			var dy = end.y - start.y;
			var length = Math.sqrt(dx * dx + dy * dy);
			var angle = Math.atan2(dy, dx);
			lines[i].x += (start.x - lines[i].x) * 0.3;
			lines[i].y += (start.y - lines[i].y) * 0.3;
			lines[i].width += (length - lines[i].width) * 0.3;
			var angleDiff = angle - lines[i].rotation;
			if (angleDiff > Math.PI) {
				angleDiff -= Math.PI * 2;
			}
			if (angleDiff < -Math.PI) {
				angleDiff += Math.PI * 2;
			}
			lines[i].rotation += angleDiff * 0.3;
		}
	};
	self.destroy = function () {
		waterRects.forEach(function (rect) {
			return rect.destroy();
		});
		lines.forEach(function (line) {
			return line.destroy();
		});
		waterRects = [];
		lines = [];
		Container.prototype.destroy.call(this);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 //Init game with black background 
});
/**** 
* Game Code
****/ 
var ParticlePool = {
	pool: [],
	maxSize: 200,
	get: function get() {
		if (this.pool.length > 0) {
			var particle = this.pool.pop();
			particle.visible = true;
			return particle;
		}
		return new WaterParticle();
	},
	"return": function _return(particle) {
		if (this.pool.length < this.maxSize) {
			// Reset particle properties
			particle.visible = false;
			particle.scale.set(1, 1);
			particle.x = 0;
			particle.y = 0;
			particle.rotation = 0;
			this.pool.push(particle);
		} else {
			particle.destroy();
		}
	}
};
var lastScoreDisplay = -1;
var lastMultiplierDisplay = -1;
function detectPerformance() {
	// Simple initial detection based on first few frames
	var startTime = performance.now();
	var frameCount = 0;
	function checkFrameRate() {
		frameCount++;
		if (frameCount === 60) {
			var elapsed = performance.now() - startTime;
			var fps = 1000 / (elapsed / 60);
			// Adjust update interval based on performance
			if (fps < 45) {
				devicePerformance = 0.5; // Slower device
				WAVE_UPDATE_INTERVAL = 3; // Update every 3rd frame
			} else if (fps < 30) {
				devicePerformance = 0.25; // Very slow device
				WAVE_UPDATE_INTERVAL = 4; // Update every 4th frame
			}
		} else if (frameCount < 60) {
			requestAnimationFrame(checkFrameRate);
		}
	}
	checkFrameRate();
}
var originalSetInterval = LK.setInterval;
LK.setInterval = function () {
	for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
		args[_key] = arguments[_key];
	}
	var timer = originalSetInterval.apply(this, args);
	gameTimers.push(timer);
	return timer;
};
var originalSetTimeout = LK.setTimeout;
LK.setTimeout = function () {
	for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
		args[_key2] = arguments[_key2];
	}
	var timer = originalSetTimeout.apply(this, args);
	gameTimers.push(timer);
	return timer;
};
var gameTimers = [];
var score = 0; // Initialize score variable
var multiplier = 1;
var lastWaveHeight = 0;
var lastWaveUpdate = 0;
var WAVE_UPDATE_INTERVAL = 2; // Skip every other frame
var devicePerformance = 1; // Default performance multiplier
var waveSystem = game.addChild(new WaveSystem());
var particles = new ParticleSystem();
game.particles = game.addChild(new ParticleSystem());
var surfer = game.addChild(new Surfer());
surfer.setWaveSystem(waveSystem);
var scoreText = new Text2("", {
	size: 100,
	fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.top.addChild(scoreText);
var multiplierText = new Text2("", {
	size: 60,
	fill: 0xFFFFFF,
	alpha: 0.8
});
multiplierText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(multiplierText);
// Game update function
var lastUpdateTime = 0;
game.update = function () {
	var now = Date.now();
	if (now - lastUpdateTime < 16) {
		// Don't update faster than 60fps
		return;
	}
	lastUpdateTime = now;
	// Every 300 frames, log counts
	if (LK.ticks % 600 === 0) {
		console.log('Active timers:', gameTimers.length);
	}
	if (LK.ticks % 300 === 0) {
		console.log('Particle count:', game.particles.children.length);
		console.log('Wave points:', waveSystem.points.length);
		console.log('Total game children:', game.children.length);
		console.log('Active tweens:', tween.getActiveTweens ? tween.getActiveTweens().length : 0);
	}
	waveSystem.update();
	surfer.update();
	particles.update();
	var currentScore = Math.floor(score);
	if (currentScore !== lastScoreDisplay) {
		lastScoreDisplay = currentScore;
		scoreText.setText(currentScore.toLocaleString());
	}
	var currentMultiplier = Math.floor(multiplier * 10) / 10; // Round to 1 decimal
	if (currentMultiplier !== lastMultiplierDisplay) {
		lastMultiplierDisplay = currentMultiplier;
		multiplierText.setText("x" + currentMultiplier.toFixed(1));
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -9,9 +9,9 @@
 ****/ 
 var ParticleSystem = Container.expand(function () {
 	var self = Container.call(this);
 	self.addWaterParticle = function (x, y, type) {
-		var particle = new WaterParticle();
+		var particle = ParticlePool.get();
 		if (type === 'trail') {
 			// Move spawn point up and behind surfer
 			particle.x = x - 100; // Spawn behind (to the right of) surfer
 			particle.y = y + 10; // Raised up from previous +90
@@ -30,9 +30,9 @@
 				particle.update();
 			}
 			// Remove particles that have moved far off screen
 			if (particle.x < -500 || particle.x > 2548 || particle.y < -500 || particle.y > 3232) {
-				particle.destroy();
+				ParticlePool["return"](particle);
 				self.removeChild(particle);
 			}
 		}
 	};
@@ -364,8 +364,33 @@
 
 /**** 
 * Game Code
 ****/ 
+var ParticlePool = {
+	pool: [],
+	maxSize: 200,
+	get: function get() {
+		if (this.pool.length > 0) {
+			var particle = this.pool.pop();
+			particle.visible = true;
+			return particle;
+		}
+		return new WaterParticle();
+	},
+	"return": function _return(particle) {
+		if (this.pool.length < this.maxSize) {
+			// Reset particle properties
+			particle.visible = false;
+			particle.scale.set(1, 1);
+			particle.x = 0;
+			particle.y = 0;
+			particle.rotation = 0;
+			this.pool.push(particle);
+		} else {
+			particle.destroy();
+		}
+	}
+};
 var lastScoreDisplay = -1;
 var lastMultiplierDisplay = -1;
 function detectPerformance() {
 	// Simple initial detection based on first few frames
:quality(85)/https://cdn.frvr.ai/67a93eb368c182ca2db2af7e.png%3F3) 
 A surfer standing and riding on a surfboard. Side profile. Cartoon. Full body. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67aa1245badf5001415a636c.png%3F3) 
 A peaked blue rock. Cartoon style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67aa1bb8badf5001415a63b2.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/67aa2e23badf5001415a645e.png%3F3) 
 Poseidon’s face. Cartoon style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67aa3a5b89fd120dcff03110.png%3F3) 
 An opened pair of lips as if singing . Light Skin color. Cell shading vector art style. Facing forward. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67aa765f89fd120dcff031bb.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/67aaacc72308eb0585f20705.png%3F3) 
 A tropical fish. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67ae55fa8a1a41a014d09fa5.png%3F3)