User prompt
Long titled buttons are overlapping
User prompt
Make the spaces between each button even smaller and make sure sandbox unlocks every designs, system. Also consider adding a arrow that collapses it ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add boat designs and consider resizing various words on the buttons because it goes past the button
User prompt
make sure article goes in front of the buttons and the higher the lifespan number the faster the days go down so players dont need to wait to see it go to zero. Also buttons are going past boundaries squeeze it a bot
User prompt
Add even more materials like alloys, graphene, heavy motor, and more like safety systems and a whole new class players could add crew type now. Make sure none of the materials or designs or safety or crew needs boats launched, only lifespan, also add a sandbox button to unlock everything ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
When players do various combos or reach a high amount of lifespan on a ship to unlock materials, propulsions, safety systems, and designs. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add propulsion and safety systems as selectable options to boost ship lifespan even more
User prompt
Let players also have the option to add propulsion and safety systems
User prompt
Pretend survival time is in months, years, and days.
User prompt
Timelapse how long it lasted, example randomizing lifespan based on accidents.
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var localPos = self.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 83
User prompt
Still does not work.
User prompt
fix article
User prompt
Doesnt work make a modular article system also make sure article color is brown.
User prompt
Things work, but result doesn’t, make it so that after the player makes the boat a news article appears and a red x can be used to exit the article
User prompt
The Ui keeps flashing from blue to black, set ui to black and white
User prompt
Please fix the bug: 'Timeout.tick error: null is not an object (evaluating 'materialData.name')' in or related to this line: 'newsPanel.showNews(materialData.name, designData.name, survivalTime, disaster);' Line Number: 363
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var savedLaunches = storage.get('launches') || [];' Line Number: 343
User prompt
Completely revamp building system. Were players chose one material, one design, and then see it a news article about were it died, how long it lasted and a procedurally generated reason of accident and problems
Code edit (1 edits merged)
Please save this source code
User prompt
Faithless
Initial prompt
Make a game called Faithless, about making boats and seeing horrible accidents go on with them.
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Article = Container.expand(function (title, content) {
	var self = Container.call(this);
	self.visible = false;
	var background = self.attachAsset('newsPanel', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	background.tint = 0x8b4513; // Brown color
	var titleText = new Text2(title, {
		size: 60,
		fill: 0xffffff
	});
	titleText.anchor.set(0.5, 0);
	titleText.y = -550;
	self.addChild(titleText);
	var contentText = new Text2(content, {
		size: 40,
		fill: 0xffffff,
		wordWrap: true,
		wordWrapWidth: 1600
	});
	contentText.anchor.set(0.5, 0);
	contentText.y = -400;
	self.addChild(contentText);
	var closeButton = self.attachAsset('materialButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 800,
		y: -550,
		scaleX: 0.5,
		scaleY: 0.5
	});
	closeButton.tint = 0xff0000;
	var closeText = new Text2('X', {
		size: 60,
		fill: 0xffffff
	});
	closeText.anchor.set(0.5, 0.5);
	closeText.x = 800;
	closeText.y = -550;
	self.addChild(closeText);
	self.updateContent = function (newTitle, newContent) {
		if (titleText && contentText) {
			titleText.setText(newTitle);
			contentText.setText(newContent);
			console.log('Article content updated:', newTitle, newContent);
		} else {
			console.log('Text objects not available for update');
		}
	};
	self.show = function () {
		console.log('Showing article, current visibility:', self.visible);
		self.visible = true;
		self.alpha = 1;
		console.log('Article visibility set to:', self.visible);
		LK.getSound('newspaper').play();
	};
	self.hide = function () {
		self.visible = false;
	};
	self.down = function (x, y, obj) {
		if (self.visible) {
			// Check if click is near the X button (top right area)
			// Use the passed x, y coordinates directly as they are already in local space
			if (x > 700 && x < 900 && y > -600 && y < -500) {
				self.hide();
			}
		}
	};
	return self;
});
var DesignButton = Container.expand(function (designType, designName, x, y) {
	var self = Container.call(this);
	self.designType = designType;
	self.designName = designName;
	self.selected = false;
	var background = self.attachAsset('designButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var nameText = new Text2(designName, {
		size: 32,
		fill: 0xffffff
	});
	nameText.anchor.set(0.5, 0.5);
	self.addChild(nameText);
	self.x = x;
	self.y = y;
	self.updateVisual = function () {
		if (self.selected) {
			background.tint = 0x00ff00;
		} else {
			background.tint = 0xffffff;
		}
	};
	self.down = function (x, y, obj) {
		selectDesign(self.designType);
	};
	return self;
});
var MaterialButton = Container.expand(function (materialType, materialName, x, y) {
	var self = Container.call(this);
	self.materialType = materialType;
	self.materialName = materialName;
	self.selected = false;
	var background = self.attachAsset('materialButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var nameText = new Text2(materialName, {
		size: 32,
		fill: 0xffffff
	});
	nameText.anchor.set(0.5, 0.5);
	self.addChild(nameText);
	self.x = x;
	self.y = y;
	self.updateVisual = function () {
		if (self.selected) {
			background.tint = 0x00ff00;
		} else {
			background.tint = 0xffffff;
		}
	};
	self.down = function (x, y, obj) {
		selectMaterial(self.materialType);
	};
	return self;
});
var NewsPanel = Container.expand(function () {
	var self = Container.call(this);
	self.currentArticle = null;
	self.formatSurvivalTime = function (timeInTicks) {
		var totalDays = Math.floor(timeInTicks / 60);
		var years = Math.floor(totalDays / 365);
		var remainingDays = totalDays % 365;
		var months = Math.floor(remainingDays / 30);
		var days = remainingDays % 30;
		var timeStr = '';
		if (years > 0) timeStr += years + ' years, ';
		if (months > 0) timeStr += months + ' months, ';
		timeStr += days + ' days';
		return timeStr;
	};
	self.showNews = function (material, design, propulsion, safety, survivalTime, disaster) {
		var title = 'MARITIME DISASTER REPORT';
		var content = 'VESSEL SPECIFICATIONS:\n';
		content += 'Material: ' + material + '\n';
		content += 'Design: ' + design + '\n';
		content += 'Propulsion: ' + propulsion + '\n';
		content += 'Safety Systems: ' + safety + '\n\n';
		content += 'SURVIVAL TIME: ' + self.formatSurvivalTime(survivalTime) + '\n\n';
		content += 'CAUSE OF DISASTER:\n' + disaster;
		console.log('Showing news with:', title, content);
		if (self.currentArticle) {
			self.currentArticle.updateContent(title, content);
			self.currentArticle.show();
			console.log('Article shown successfully');
		} else {
			console.log('No article available to show news');
		}
	};
	return self;
});
var PropulsionButton = Container.expand(function (propulsionType, propulsionName, x, y) {
	var self = Container.call(this);
	self.propulsionType = propulsionType;
	self.propulsionName = propulsionName;
	self.selected = false;
	var background = self.attachAsset('materialButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var nameText = new Text2(propulsionName, {
		size: 32,
		fill: 0xffffff
	});
	nameText.anchor.set(0.5, 0.5);
	self.addChild(nameText);
	self.x = x;
	self.y = y;
	self.updateVisual = function () {
		if (self.selected) {
			background.tint = 0x0066ff; // Blue for propulsion
		} else {
			background.tint = 0xffffff;
		}
	};
	self.down = function (x, y, obj) {
		selectPropulsion(self.propulsionType);
	};
	return self;
});
var SafetyButton = Container.expand(function (safetyType, safetyName, x, y) {
	var self = Container.call(this);
	self.safetyType = safetyType;
	self.safetyName = safetyName;
	self.selected = false;
	var background = self.attachAsset('materialButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var nameText = new Text2(safetyName, {
		size: 32,
		fill: 0xffffff
	});
	nameText.anchor.set(0.5, 0.5);
	self.addChild(nameText);
	self.x = x;
	self.y = y;
	self.updateVisual = function () {
		if (self.selected) {
			background.tint = 0xff6600; // Orange for safety
		} else {
			background.tint = 0xffffff;
		}
	};
	self.down = function (x, y, obj) {
		selectSafety(self.safetyType);
	};
	return self;
});
var TimerDisplay = Container.expand(function () {
	var self = Container.call(this);
	self.visible = false;
	self.currentTime = 0;
	self.maxTime = 0;
	self.isActive = false;
	var background = self.attachAsset('timerPanel', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var titleText = new Text2('VESSEL STATUS', {
		size: 32,
		fill: 0xffffff
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -60;
	self.addChild(titleText);
	var timeText = new Text2('0.0s', {
		size: 48,
		fill: 0x00ff00
	});
	timeText.anchor.set(0.5, 0.5);
	timeText.y = -10;
	self.addChild(timeText);
	var statusText = new Text2('OPERATIONAL', {
		size: 28,
		fill: 0x00ff00
	});
	statusText.anchor.set(0.5, 0.5);
	statusText.y = 40;
	self.addChild(statusText);
	self.formatTime = function (timeInTicks) {
		// Convert ticks to days (assuming 1 tick = 1 day for dramatic effect)
		var totalDays = Math.floor(timeInTicks / 60);
		var years = Math.floor(totalDays / 365);
		var remainingDays = totalDays % 365;
		var months = Math.floor(remainingDays / 30);
		var days = remainingDays % 30;
		var timeStr = '';
		if (years > 0) timeStr += years + 'y ';
		if (months > 0) timeStr += months + 'm ';
		timeStr += days + 'd';
		return timeStr;
	};
	self.startTimer = function (maxSurvivalTime) {
		self.currentTime = maxSurvivalTime;
		self.maxTime = maxSurvivalTime;
		self.isActive = true;
		self.visible = true;
		timeText.setText(self.formatTime(self.currentTime));
		timeText.tint = 0x00ff00;
		statusText.setText('OPERATIONAL');
		statusText.tint = 0x00ff00;
		// Position timer in top right area
		self.x = 1700;
		self.y = 200;
	};
	self.update = function () {
		if (self.isActive && self.currentTime > 0) {
			self.currentTime--;
			timeText.setText(self.formatTime(self.currentTime));
			// Change color based on remaining time
			var timeRatio = self.currentTime / self.maxTime;
			if (timeRatio > 0.5) {
				timeText.tint = 0x00ff00; // Green
				statusText.tint = 0x00ff00;
			} else if (timeRatio > 0.25) {
				timeText.tint = 0xffff00; // Yellow
				statusText.tint = 0xffff00;
				statusText.setText('CRITICAL');
			} else {
				timeText.tint = 0xff0000; // Red
				statusText.tint = 0xff0000;
				statusText.setText('FAILING');
			}
			// Play tick sound every second (60 ticks)
			if (self.currentTime % 60 === 0 && self.currentTime > 0) {
				LK.getSound('tick').play();
			}
			// When time runs out
			if (self.currentTime <= 0) {
				self.isActive = false;
				timeText.setText('0d');
				timeText.tint = 0xff0000;
				statusText.setText('DESTROYED');
				statusText.tint = 0xff0000;
				LK.getSound('explosion').play();
				LK.effects.flashScreen(0xff0000, 1000);
				// Hide timer after 3 seconds
				LK.setTimeout(function () {
					self.visible = false;
				}, 3000);
			}
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Game state variables
var selectedMaterial = null;
var selectedDesign = null;
var selectedPropulsion = null;
var selectedSafety = null;
var totalBoatsLaunched = 0;
var materialButtons = [];
var designButtons = [];
var propulsionButtons = [];
var safetyButtons = [];
var newsPanel = null;
var timerDisplay = null;
// Material data
var materials = [{
	type: 'wood',
	name: 'Wood',
	durability: 50,
	cost: 25
}, {
	type: 'steel',
	name: 'Steel',
	durability: 80,
	cost: 45
}, {
	type: 'plastic',
	name: 'Plastic',
	durability: 30,
	cost: 15
}, {
	type: 'aluminum',
	name: 'Aluminum',
	durability: 70,
	cost: 35
}];
// Design data
var designs = [{
	type: 'fishing',
	name: 'Fishing Boat',
	stability: 60,
	speed: 40
}, {
	type: 'yacht',
	name: 'Luxury Yacht',
	stability: 40,
	speed: 80
}, {
	type: 'cargo',
	name: 'Cargo Ship',
	stability: 80,
	speed: 20
}, {
	type: 'speedboat',
	name: 'Speed Boat',
	stability: 30,
	speed: 90
}];
// Propulsion data
var propulsionSystems = [{
	type: 'sail',
	name: 'Sail Power',
	efficiency: 40,
	reliability: 90,
	cost: 10
}, {
	type: 'diesel',
	name: 'Diesel Engine',
	efficiency: 80,
	reliability: 70,
	cost: 50
}, {
	type: 'electric',
	name: 'Electric Motor',
	efficiency: 90,
	reliability: 85,
	cost: 75
}, {
	type: 'nuclear',
	name: 'Nuclear Reactor',
	efficiency: 100,
	reliability: 50,
	cost: 200
}];
// Safety system data
var safetySystems = [{
	type: 'basic',
	name: 'Basic Safety',
	protection: 30,
	weight: 10,
	cost: 20
}, {
	type: 'advanced',
	name: 'Advanced Safety',
	protection: 70,
	weight: 30,
	cost: 80
}, {
	type: 'military',
	name: 'Military Grade',
	protection: 90,
	weight: 50,
	cost: 150
}, {
	type: 'experimental',
	name: 'Experimental',
	protection: 95,
	weight: 20,
	cost: 300
}];
// Disaster scenarios
var disasters = ['Structural failure due to poor material choice', 'Capsized in rough waters due to design instability', 'Engine explosion caused by manufacturing defects', 'Hull breach from collision with debris', 'Overloading beyond design capacity', 'Fire spread rapidly through cheap materials', 'Steering system malfunction in storm', 'Crew error compounded by design flaws'];
// Create UI
var scoreText = new Text2('Boats Launched: 0', {
	size: 60,
	fill: 0xffffff
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var instructionText = new Text2('Select material and design, then launch your vessel to its doom!', {
	size: 40,
	fill: 0xffffff
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
// Create material selection area
var materialTitle = new Text2('SELECT MATERIAL:', {
	size: 50,
	fill: 0xffffff
});
materialTitle.anchor.set(0.5, 0.5);
materialTitle.x = 1024;
materialTitle.y = 400;
game.addChild(materialTitle);
// Create material buttons
for (var i = 0; i < materials.length; i++) {
	var materialButton = new MaterialButton(materials[i].type, materials[i].name, 400 + i * 320, 550);
	game.addChild(materialButton);
	materialButtons.push(materialButton);
}
// Create design selection area
var designTitle = new Text2('SELECT DESIGN:', {
	size: 50,
	fill: 0xffffff
});
designTitle.anchor.set(0.5, 0.5);
designTitle.x = 1024;
designTitle.y = 800;
game.addChild(designTitle);
// Create design buttons
for (var i = 0; i < designs.length; i++) {
	var designButton = new DesignButton(designs[i].type, designs[i].name, 400 + i * 320, 950);
	game.addChild(designButton);
	designButtons.push(designButton);
}
// Create propulsion selection area
var propulsionTitle = new Text2('SELECT PROPULSION:', {
	size: 50,
	fill: 0xffffff
});
propulsionTitle.anchor.set(0.5, 0.5);
propulsionTitle.x = 1024;
propulsionTitle.y = 1200;
game.addChild(propulsionTitle);
// Create propulsion buttons
for (var i = 0; i < propulsionSystems.length; i++) {
	var propulsionButton = new PropulsionButton(propulsionSystems[i].type, propulsionSystems[i].name, 400 + i * 320, 1350);
	game.addChild(propulsionButton);
	propulsionButtons.push(propulsionButton);
}
// Create safety selection area
var safetyTitle = new Text2('SELECT SAFETY SYSTEMS:', {
	size: 50,
	fill: 0xffffff
});
safetyTitle.anchor.set(0.5, 0.5);
safetyTitle.x = 1024;
safetyTitle.y = 1600;
game.addChild(safetyTitle);
// Create safety buttons
for (var i = 0; i < safetySystems.length; i++) {
	var safetyButton = new SafetyButton(safetySystems[i].type, safetySystems[i].name, 400 + i * 320, 1750);
	game.addChild(safetyButton);
	safetyButtons.push(safetyButton);
}
// Create launch button
var launchButton = game.addChild(LK.getAsset('launchButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1024,
	y: 2000
}));
var launchText = new Text2('LAUNCH VESSEL', {
	size: 50,
	fill: 0xffffff
});
launchText.anchor.set(0.5, 0.5);
launchText.x = 1024;
launchText.y = 2000;
game.addChild(launchText);
// Create news panel with article system
newsPanel = new NewsPanel();
var article = new Article('', '');
article.x = 1024;
article.y = 1366;
game.addChild(article);
newsPanel.currentArticle = article;
// Create timer display
timerDisplay = new TimerDisplay();
game.addChild(timerDisplay);
function selectMaterial(materialType) {
	selectedMaterial = materialType;
	// Update button visuals
	for (var i = 0; i < materialButtons.length; i++) {
		materialButtons[i].selected = materialButtons[i].materialType === materialType;
		materialButtons[i].updateVisual();
	}
}
function selectDesign(designType) {
	selectedDesign = designType;
	// Update button visuals
	for (var i = 0; i < designButtons.length; i++) {
		designButtons[i].selected = designButtons[i].designType === designType;
		designButtons[i].updateVisual();
	}
}
function selectPropulsion(propulsionType) {
	selectedPropulsion = propulsionType;
	// Update button visuals
	for (var i = 0; i < propulsionButtons.length; i++) {
		propulsionButtons[i].selected = propulsionButtons[i].propulsionType === propulsionType;
		propulsionButtons[i].updateVisual();
	}
}
function selectSafety(safetyType) {
	selectedSafety = safetyType;
	// Update button visuals
	for (var i = 0; i < safetyButtons.length; i++) {
		safetyButtons[i].selected = safetyButtons[i].safetyType === safetyType;
		safetyButtons[i].updateVisual();
	}
}
function getMaterialData(materialType) {
	for (var i = 0; i < materials.length; i++) {
		if (materials[i].type === materialType) {
			return materials[i];
		}
	}
	return null;
}
function getDesignData(designType) {
	for (var i = 0; i < designs.length; i++) {
		if (designs[i].type === designType) {
			return designs[i];
		}
	}
	return null;
}
function getPropulsionData(propulsionType) {
	for (var i = 0; i < propulsionSystems.length; i++) {
		if (propulsionSystems[i].type === propulsionType) {
			return propulsionSystems[i];
		}
	}
	return null;
}
function getSafetyData(safetyType) {
	for (var i = 0; i < safetySystems.length; i++) {
		if (safetySystems[i].type === safetyType) {
			return safetySystems[i];
		}
	}
	return null;
}
function calculateSurvivalTime(material, design, propulsion, safety) {
	var materialData = getMaterialData(material);
	var designData = getDesignData(design);
	var propulsionData = getPropulsionData(propulsion);
	var safetyData = getSafetyData(safety);
	if (!materialData || !designData) return 60; // Default 1 second
	// Base survival time with some randomness
	var baseTime = 180 + Math.random() * 600; // 3-13 seconds
	// Material affects durability
	baseTime *= materialData.durability / 50;
	// Design affects stability
	baseTime *= designData.stability / 50;
	// Propulsion affects reliability and efficiency
	if (propulsionData) {
		baseTime *= propulsionData.reliability / 70;
		baseTime *= propulsionData.efficiency / 80;
	}
	// Safety systems significantly improve survival
	if (safetyData) {
		baseTime *= (100 + safetyData.protection) / 100;
		// Better safety reduces weight penalty
		baseTime *= (100 - safetyData.weight * 0.5) / 100;
	}
	// Add some chaos
	baseTime *= 0.5 + Math.random();
	return Math.floor(baseTime);
}
function generateDisasterReport(material, design, propulsion, safety, survivalTime) {
	var materialData = getMaterialData(material);
	var designData = getDesignData(design);
	var propulsionData = getPropulsionData(propulsion);
	var safetyData = getSafetyData(safety);
	var randomDisaster = disasters[Math.floor(Math.random() * disasters.length)];
	// Format survival time
	var totalDays = Math.floor(survivalTime / 60);
	var years = Math.floor(totalDays / 365);
	var remainingDays = totalDays % 365;
	var months = Math.floor(remainingDays / 30);
	var days = remainingDays % 30;
	var timeStr = '';
	if (years > 0) timeStr += years + ' years, ';
	if (months > 0) timeStr += months + ' months, ';
	timeStr += days + ' days';
	// Create more specific disaster based on choices
	var specificCause = '';
	if (materialData.durability < 40) {
		specificCause = 'The cheap ' + materialData.name.toLowerCase() + ' construction proved inadequate for maritime conditions. ';
	} else if (designData.stability < 50) {
		specificCause = 'The ' + designData.name.toLowerCase() + ' design showed inherent stability issues. ';
	} else if (propulsionData && propulsionData.reliability < 60) {
		specificCause = 'The ' + propulsionData.name.toLowerCase() + ' system suffered catastrophic failure. ';
	} else if (safetyData && safetyData.protection < 50) {
		specificCause = 'Inadequate safety systems (' + safetyData.name.toLowerCase() + ') failed to prevent disaster. ';
	}
	return specificCause + randomDisaster + '. The vessel lasted ' + timeStr + ' before meeting its inevitable fate.';
}
function launchVessel() {
	if (!selectedMaterial || !selectedDesign || !selectedPropulsion || !selectedSafety) {
		return; // Can't launch without all selections
	}
	totalBoatsLaunched++;
	scoreText.setText('Boats Launched: ' + totalBoatsLaunched);
	// Calculate how long this boat will survive
	var survivalTime = calculateSurvivalTime(selectedMaterial, selectedDesign, selectedPropulsion, selectedSafety);
	// Generate disaster report
	var disaster = generateDisasterReport(selectedMaterial, selectedDesign, selectedPropulsion, selectedSafety, survivalTime);
	// Show launch effect
	LK.getSound('launch').play();
	LK.effects.flashScreen(0x0000ff, 500);
	// Start the timelapse timer
	timerDisplay.startTimer(survivalTime);
	// Store this launch for potential leaderboard
	var launchData = {
		material: selectedMaterial,
		design: selectedDesign,
		propulsion: selectedPropulsion,
		safety: selectedSafety,
		survivalTime: survivalTime,
		disaster: disaster,
		timestamp: Date.now()
	};
	var savedLaunches = [];
	try {
		savedLaunches = storage.get('launches') || [];
	} catch (e) {
		console.log('Storage not available, using empty array');
		savedLaunches = [];
	}
	savedLaunches.push(launchData);
	if (savedLaunches.length > 50) {
		savedLaunches = savedLaunches.slice(-50); // Keep only last 50
	}
	try {
		storage.set('launches', savedLaunches);
	} catch (e) {
		console.log('Could not save to storage');
	}
	for (var i = 0; i < materialButtons.length; i++) {
		materialButtons[i].selected = false;
		materialButtons[i].updateVisual();
	}
	for (var i = 0; i < designButtons.length; i++) {
		designButtons[i].selected = false;
		designButtons[i].updateVisual();
	}
	for (var i = 0; i < propulsionButtons.length; i++) {
		propulsionButtons[i].selected = false;
		propulsionButtons[i].updateVisual();
	}
	for (var i = 0; i < safetyButtons.length; i++) {
		safetyButtons[i].selected = false;
		safetyButtons[i].updateVisual();
	}
	// Check for achievement
	if (totalBoatsLaunched >= 10) {
		LK.showYouWin();
	}
}
// Event handlers
launchButton.down = function (x, y, obj) {
	launchVessel();
};
game.update = function () {
	// Background stays consistently black - no flashing
	// Update timer display
	if (timerDisplay) {
		timerDisplay.update();
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -150,13 +150,15 @@
 		if (months > 0) timeStr += months + ' months, ';
 		timeStr += days + ' days';
 		return timeStr;
 	};
-	self.showNews = function (material, design, survivalTime, disaster) {
+	self.showNews = function (material, design, propulsion, safety, survivalTime, disaster) {
 		var title = 'MARITIME DISASTER REPORT';
 		var content = 'VESSEL SPECIFICATIONS:\n';
 		content += 'Material: ' + material + '\n';
-		content += 'Design: ' + design + '\n\n';
+		content += 'Design: ' + design + '\n';
+		content += 'Propulsion: ' + propulsion + '\n';
+		content += 'Safety Systems: ' + safety + '\n\n';
 		content += 'SURVIVAL TIME: ' + self.formatSurvivalTime(survivalTime) + '\n\n';
 		content += 'CAUSE OF DISASTER:\n' + disaster;
 		console.log('Showing news with:', title, content);
 		if (self.currentArticle) {
@@ -168,8 +170,66 @@
 		}
 	};
 	return self;
 });
+var PropulsionButton = Container.expand(function (propulsionType, propulsionName, x, y) {
+	var self = Container.call(this);
+	self.propulsionType = propulsionType;
+	self.propulsionName = propulsionName;
+	self.selected = false;
+	var background = self.attachAsset('materialButton', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	var nameText = new Text2(propulsionName, {
+		size: 32,
+		fill: 0xffffff
+	});
+	nameText.anchor.set(0.5, 0.5);
+	self.addChild(nameText);
+	self.x = x;
+	self.y = y;
+	self.updateVisual = function () {
+		if (self.selected) {
+			background.tint = 0x0066ff; // Blue for propulsion
+		} else {
+			background.tint = 0xffffff;
+		}
+	};
+	self.down = function (x, y, obj) {
+		selectPropulsion(self.propulsionType);
+	};
+	return self;
+});
+var SafetyButton = Container.expand(function (safetyType, safetyName, x, y) {
+	var self = Container.call(this);
+	self.safetyType = safetyType;
+	self.safetyName = safetyName;
+	self.selected = false;
+	var background = self.attachAsset('materialButton', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	var nameText = new Text2(safetyName, {
+		size: 32,
+		fill: 0xffffff
+	});
+	nameText.anchor.set(0.5, 0.5);
+	self.addChild(nameText);
+	self.x = x;
+	self.y = y;
+	self.updateVisual = function () {
+		if (self.selected) {
+			background.tint = 0xff6600; // Orange for safety
+		} else {
+			background.tint = 0xffffff;
+		}
+	};
+	self.down = function (x, y, obj) {
+		selectSafety(self.safetyType);
+	};
+	return self;
+});
 var TimerDisplay = Container.expand(function () {
 	var self = Container.call(this);
 	self.visible = false;
 	self.currentTime = 0;
@@ -279,11 +339,15 @@
 ****/ 
 // Game state variables
 var selectedMaterial = null;
 var selectedDesign = null;
+var selectedPropulsion = null;
+var selectedSafety = null;
 var totalBoatsLaunched = 0;
 var materialButtons = [];
 var designButtons = [];
+var propulsionButtons = [];
+var safetyButtons = [];
 var newsPanel = null;
 var timerDisplay = null;
 // Material data
 var materials = [{
@@ -328,8 +392,60 @@
 	name: 'Speed Boat',
 	stability: 30,
 	speed: 90
 }];
+// Propulsion data
+var propulsionSystems = [{
+	type: 'sail',
+	name: 'Sail Power',
+	efficiency: 40,
+	reliability: 90,
+	cost: 10
+}, {
+	type: 'diesel',
+	name: 'Diesel Engine',
+	efficiency: 80,
+	reliability: 70,
+	cost: 50
+}, {
+	type: 'electric',
+	name: 'Electric Motor',
+	efficiency: 90,
+	reliability: 85,
+	cost: 75
+}, {
+	type: 'nuclear',
+	name: 'Nuclear Reactor',
+	efficiency: 100,
+	reliability: 50,
+	cost: 200
+}];
+// Safety system data
+var safetySystems = [{
+	type: 'basic',
+	name: 'Basic Safety',
+	protection: 30,
+	weight: 10,
+	cost: 20
+}, {
+	type: 'advanced',
+	name: 'Advanced Safety',
+	protection: 70,
+	weight: 30,
+	cost: 80
+}, {
+	type: 'military',
+	name: 'Military Grade',
+	protection: 90,
+	weight: 50,
+	cost: 150
+}, {
+	type: 'experimental',
+	name: 'Experimental',
+	protection: 95,
+	weight: 20,
+	cost: 300
+}];
 // Disaster scenarios
 var disasters = ['Structural failure due to poor material choice', 'Capsized in rough waters due to design instability', 'Engine explosion caused by manufacturing defects', 'Hull breach from collision with debris', 'Overloading beyond design capacity', 'Fire spread rapidly through cheap materials', 'Steering system malfunction in storm', 'Crew error compounded by design flaws'];
 // Create UI
 var scoreText = new Text2('Boats Launched: 0', {
@@ -374,22 +490,52 @@
 	var designButton = new DesignButton(designs[i].type, designs[i].name, 400 + i * 320, 950);
 	game.addChild(designButton);
 	designButtons.push(designButton);
 }
+// Create propulsion selection area
+var propulsionTitle = new Text2('SELECT PROPULSION:', {
+	size: 50,
+	fill: 0xffffff
+});
+propulsionTitle.anchor.set(0.5, 0.5);
+propulsionTitle.x = 1024;
+propulsionTitle.y = 1200;
+game.addChild(propulsionTitle);
+// Create propulsion buttons
+for (var i = 0; i < propulsionSystems.length; i++) {
+	var propulsionButton = new PropulsionButton(propulsionSystems[i].type, propulsionSystems[i].name, 400 + i * 320, 1350);
+	game.addChild(propulsionButton);
+	propulsionButtons.push(propulsionButton);
+}
+// Create safety selection area
+var safetyTitle = new Text2('SELECT SAFETY SYSTEMS:', {
+	size: 50,
+	fill: 0xffffff
+});
+safetyTitle.anchor.set(0.5, 0.5);
+safetyTitle.x = 1024;
+safetyTitle.y = 1600;
+game.addChild(safetyTitle);
+// Create safety buttons
+for (var i = 0; i < safetySystems.length; i++) {
+	var safetyButton = new SafetyButton(safetySystems[i].type, safetySystems[i].name, 400 + i * 320, 1750);
+	game.addChild(safetyButton);
+	safetyButtons.push(safetyButton);
+}
 // Create launch button
 var launchButton = game.addChild(LK.getAsset('launchButton', {
 	anchorX: 0.5,
 	anchorY: 0.5,
 	x: 1024,
-	y: 1350
+	y: 2000
 }));
 var launchText = new Text2('LAUNCH VESSEL', {
 	size: 50,
 	fill: 0xffffff
 });
 launchText.anchor.set(0.5, 0.5);
 launchText.x = 1024;
-launchText.y = 1350;
+launchText.y = 2000;
 game.addChild(launchText);
 // Create news panel with article system
 newsPanel = new NewsPanel();
 var article = new Article('', '');
@@ -415,8 +561,24 @@
 		designButtons[i].selected = designButtons[i].designType === designType;
 		designButtons[i].updateVisual();
 	}
 }
+function selectPropulsion(propulsionType) {
+	selectedPropulsion = propulsionType;
+	// Update button visuals
+	for (var i = 0; i < propulsionButtons.length; i++) {
+		propulsionButtons[i].selected = propulsionButtons[i].propulsionType === propulsionType;
+		propulsionButtons[i].updateVisual();
+	}
+}
+function selectSafety(safetyType) {
+	selectedSafety = safetyType;
+	// Update button visuals
+	for (var i = 0; i < safetyButtons.length; i++) {
+		safetyButtons[i].selected = safetyButtons[i].safetyType === safetyType;
+		safetyButtons[i].updateVisual();
+	}
+}
 function getMaterialData(materialType) {
 	for (var i = 0; i < materials.length; i++) {
 		if (materials[i].type === materialType) {
 			return materials[i];
@@ -431,25 +593,56 @@
 		}
 	}
 	return null;
 }
-function calculateSurvivalTime(material, design) {
+function getPropulsionData(propulsionType) {
+	for (var i = 0; i < propulsionSystems.length; i++) {
+		if (propulsionSystems[i].type === propulsionType) {
+			return propulsionSystems[i];
+		}
+	}
+	return null;
+}
+function getSafetyData(safetyType) {
+	for (var i = 0; i < safetySystems.length; i++) {
+		if (safetySystems[i].type === safetyType) {
+			return safetySystems[i];
+		}
+	}
+	return null;
+}
+function calculateSurvivalTime(material, design, propulsion, safety) {
 	var materialData = getMaterialData(material);
 	var designData = getDesignData(design);
+	var propulsionData = getPropulsionData(propulsion);
+	var safetyData = getSafetyData(safety);
 	if (!materialData || !designData) return 60; // Default 1 second
 	// Base survival time with some randomness
 	var baseTime = 180 + Math.random() * 600; // 3-13 seconds
 	// Material affects durability
 	baseTime *= materialData.durability / 50;
 	// Design affects stability
 	baseTime *= designData.stability / 50;
+	// Propulsion affects reliability and efficiency
+	if (propulsionData) {
+		baseTime *= propulsionData.reliability / 70;
+		baseTime *= propulsionData.efficiency / 80;
+	}
+	// Safety systems significantly improve survival
+	if (safetyData) {
+		baseTime *= (100 + safetyData.protection) / 100;
+		// Better safety reduces weight penalty
+		baseTime *= (100 - safetyData.weight * 0.5) / 100;
+	}
 	// Add some chaos
 	baseTime *= 0.5 + Math.random();
 	return Math.floor(baseTime);
 }
-function generateDisasterReport(material, design, survivalTime) {
+function generateDisasterReport(material, design, propulsion, safety, survivalTime) {
 	var materialData = getMaterialData(material);
 	var designData = getDesignData(design);
+	var propulsionData = getPropulsionData(propulsion);
+	var safetyData = getSafetyData(safety);
 	var randomDisaster = disasters[Math.floor(Math.random() * disasters.length)];
 	// Format survival time
 	var totalDays = Math.floor(survivalTime / 60);
 	var years = Math.floor(totalDays / 365);
@@ -465,21 +658,25 @@
 	if (materialData.durability < 40) {
 		specificCause = 'The cheap ' + materialData.name.toLowerCase() + ' construction proved inadequate for maritime conditions. ';
 	} else if (designData.stability < 50) {
 		specificCause = 'The ' + designData.name.toLowerCase() + ' design showed inherent stability issues. ';
+	} else if (propulsionData && propulsionData.reliability < 60) {
+		specificCause = 'The ' + propulsionData.name.toLowerCase() + ' system suffered catastrophic failure. ';
+	} else if (safetyData && safetyData.protection < 50) {
+		specificCause = 'Inadequate safety systems (' + safetyData.name.toLowerCase() + ') failed to prevent disaster. ';
 	}
 	return specificCause + randomDisaster + '. The vessel lasted ' + timeStr + ' before meeting its inevitable fate.';
 }
 function launchVessel() {
-	if (!selectedMaterial || !selectedDesign) {
-		return; // Can't launch without both selections
+	if (!selectedMaterial || !selectedDesign || !selectedPropulsion || !selectedSafety) {
+		return; // Can't launch without all selections
 	}
 	totalBoatsLaunched++;
 	scoreText.setText('Boats Launched: ' + totalBoatsLaunched);
 	// Calculate how long this boat will survive
-	var survivalTime = calculateSurvivalTime(selectedMaterial, selectedDesign);
+	var survivalTime = calculateSurvivalTime(selectedMaterial, selectedDesign, selectedPropulsion, selectedSafety);
 	// Generate disaster report
-	var disaster = generateDisasterReport(selectedMaterial, selectedDesign, survivalTime);
+	var disaster = generateDisasterReport(selectedMaterial, selectedDesign, selectedPropulsion, selectedSafety, survivalTime);
 	// Show launch effect
 	LK.getSound('launch').play();
 	LK.effects.flashScreen(0x0000ff, 500);
 	// Start the timelapse timer
@@ -487,8 +684,10 @@
 	// Store this launch for potential leaderboard
 	var launchData = {
 		material: selectedMaterial,
 		design: selectedDesign,
+		propulsion: selectedPropulsion,
+		safety: selectedSafety,
 		survivalTime: survivalTime,
 		disaster: disaster,
 		timestamp: Date.now()
 	};
@@ -507,26 +706,24 @@
 		storage.set('launches', savedLaunches);
 	} catch (e) {
 		console.log('Could not save to storage');
 	}
-	// Get material and design data before resetting selections
-	var materialData = getMaterialData(selectedMaterial);
-	var designData = getDesignData(selectedDesign);
-	// Show news report after a delay
-	LK.setTimeout(function () {
-		newsPanel.showNews(materialData.name, designData.name, survivalTime, disaster);
-	}, 2000);
-	// Reset selections
-	selectedMaterial = null;
-	selectedDesign = null;
 	for (var i = 0; i < materialButtons.length; i++) {
 		materialButtons[i].selected = false;
 		materialButtons[i].updateVisual();
 	}
 	for (var i = 0; i < designButtons.length; i++) {
 		designButtons[i].selected = false;
 		designButtons[i].updateVisual();
 	}
+	for (var i = 0; i < propulsionButtons.length; i++) {
+		propulsionButtons[i].selected = false;
+		propulsionButtons[i].updateVisual();
+	}
+	for (var i = 0; i < safetyButtons.length; i++) {
+		safetyButtons[i].selected = false;
+		safetyButtons[i].updateVisual();
+	}
 	// Check for achievement
 	if (totalBoatsLaunched >= 10) {
 		LK.showYouWin();
 	}