/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // AgeUpButton class var AgeUpButton = Container.expand(function () { var self = Container.call(this); var btn = self.attachAsset('ageup_btn', { anchorX: 0.5, anchorY: 0.5 }); var label = new Text2('Age Up', { size: 70, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); label.x = 0; label.y = 0; self.addChild(label); // For click feedback self.flash = function () { tween(btn, { tint: 0x80ff80 }, { duration: 100, onFinish: function onFinish() { tween(btn, { tint: 0x43aa8b }, { duration: 200 }); } }); }; return self; }); // Avatar class for displaying the character at different ages var Avatar = Container.expand(function () { var self = Container.call(this); // Default to baby self.stage = 'baby'; self.avatarNode = null; self.setStage = function (stage) { self.stage = stage; if (self.avatarNode) { self.avatarNode.destroy(); } var assetId = 'avatar_' + stage; self.avatarNode = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; // Initialize as baby self.setStage('baby'); return self; }); // EventPopup class for showing milestone or choice events var EventPopup = Container.expand(function () { var self = Container.call(this); var bg = self.attachAsset('event_bg', { anchorX: 0.5, anchorY: 0.5 }); self.text = new Text2('', { size: 60, fill: 0x222222, wordWrap: true, wordWrapWidth: 1100 }); self.text.anchor.set(0.5, 0.5); self.text.x = 0; self.text.y = -100; self.addChild(self.text); // Option buttons (max 2 for MVP) self.optionBtns = []; // Show popup with text and options self.show = function (text, options) { self.text.setText(text); // Remove old buttons for (var i = 0; i < self.optionBtns.length; i++) { self.optionBtns[i].destroy(); } self.optionBtns = []; // Create new buttons var btnY = 120; for (var i = 0; i < options.length; i++) { (function (idx) { var opt = options[idx]; var btn = new Container(); var btnBg = btn.attachAsset('ageup_btn', { anchorX: 0.5, anchorY: 0.5, width: 500, height: 100 }); btn.x = 0; btn.y = btnY + idx * 130; var btnLabel = new Text2(opt.text, { size: 48, fill: 0xFFFFFF }); btnLabel.anchor.set(0.5, 0.5); btn.addChild(btnLabel); btn.down = function (x, y, obj) { // Animate feedback tween(btnBg, { tint: 0x80ff80 }, { duration: 100, onFinish: function onFinish() { tween(btnBg, { tint: 0x43aa8b }, { duration: 200 }); } }); // Call option handler if (opt.onSelect) { opt.onSelect(); } }; self.addChild(btn); self.optionBtns.push(btn); })(i); } }; // Hide popup self.hide = function () { for (var i = 0; i < self.optionBtns.length; i++) { self.optionBtns[i].destroy(); } self.optionBtns = []; self.text.setText(''); self.visible = false; }; // Start hidden self.visible = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf7f7f7 }); /**** * Game Code ****/ // Life stages and their age ranges // Character avatars for each life stage (baby, child, teen, adult, elder) // Button for "Age Up" // Event popup background var lifeStages = [{ stage: 'baby', min: 0, max: 2 }, { stage: 'child', min: 3, max: 12 }, { stage: 'teen', min: 13, max: 19 }, { stage: 'adult', min: 20, max: 64 }, { stage: 'elder', min: 65, max: 120 }]; // Milestone events per age (MVP: a few per stage) var milestoneEvents = { 0: { text: "Welcome to the world! You are a newborn baby.", options: [{ text: "Continue" }] }, 1: { text: "You take your first steps!", options: [{ text: "Yay!" }] }, 5: { text: "You start school. Do you want to make a new friend?", options: [{ text: "Yes", onSelect: function onSelect() { showEvent("You made a new friend!"); } }, { text: "No", onSelect: function onSelect() { showEvent("You prefer to play alone for now."); } }] }, 13: { text: "You become a teenager. Time for high school!", options: [{ text: "Bring it on!" }] }, 18: { text: "You graduate high school. What will you do?", options: [{ text: "Go to college", onSelect: function onSelect() { showEvent("You start college life!"); } }, { text: "Start working", onSelect: function onSelect() { showEvent("You get your first job!"); } }] }, 30: { text: "You reach adulthood. Do you want to travel?", options: [{ text: "Yes", onSelect: function onSelect() { showEvent("You see the world and gain new experiences!"); } }, { text: "No", onSelect: function onSelect() { showEvent("You focus on your career."); } }] }, 65: { text: "You retire! Time to relax and enjoy your golden years.", options: [{ text: "Celebrate" }] }, 90: { text: "You reflect on a life well lived.", options: [{ text: "The End" }] } }; // Helper to get stage by age function getStageByAge(age) { for (var i = 0; i < lifeStages.length; i++) { if (age >= lifeStages[i].min && age <= lifeStages[i].max) { return lifeStages[i].stage; } } return 'elder'; } // Generate infinite age-based decisions function generateAgeBasedDecisions() { var stage = getStageByAge(age); var decisionTemplates = []; var responseTemplates = []; var activities = []; var emotions = []; var objects = []; var people = []; var places = []; var skills = []; var challenges = []; if (stage === "baby") { activities = ["cuddle", "cry", "sleep", "babble", "giggle", "stare", "reach", "wiggle", "smile", "coo", "suck thumb", "kick legs", "roll over", "grab", "listen"]; objects = ["mobile", "toy", "blanket", "bottle", "rattle", "stuffed animal", "colorful shapes", "music box", "soft fabric", "shiny object"]; people = ["mommy", "daddy", "sibling", "grandparent", "caregiver", "visitor"]; emotions = ["happy", "sleepy", "curious", "content", "fussy", "excited", "calm", "surprised"]; decisionTemplates = ["[activity] with [people]", "[activity] at the [objects]", "Feel [emotions] and [activity]", "Try to [activity]", "[activity] because you're [emotions]"]; responseTemplates = ["You feel [emotions] and [emotions].", "[people] smiles at you lovingly.", "The [objects] captures your attention.", "You discover something wonderful!", "This makes you feel safe and loved.", "You're learning about the world around you."]; } else if (stage === "child") { activities = ["play", "draw", "build", "read", "run", "jump", "sing", "dance", "explore", "help", "learn", "share", "imagine", "create", "discover"]; objects = ["blocks", "crayons", "book", "toy car", "doll", "puzzle", "ball", "bike", "sandbox", "swing", "slide", "art supplies", "games"]; people = ["friends", "parents", "teacher", "siblings", "classmates", "neighbor", "pets"]; places = ["playground", "school", "backyard", "park", "bedroom", "kitchen", "library", "store"]; emotions = ["excited", "proud", "curious", "happy", "silly", "adventurous", "creative", "friendly"]; skills = ["counting", "writing", "riding", "swimming", "climbing", "sharing", "reading"]; decisionTemplates = ["[activity] with [objects] at the [places]", "Help [people] with something", "Practice [skills]", "[activity] and feel [emotions]", "Go to [places] and [activity]", "Share [objects] with [people]", "Learn about [skills] by [activity]"]; responseTemplates = ["You have so much fun [activity]!", "[people] is proud of your [skills].", "You feel [emotions] and accomplished.", "This helps you grow and learn.", "You make new friends while [activity].", "Your imagination runs wild!", "You discover you're good at [skills]."]; } else if (stage === "teen") { activities = ["study", "hang out", "practice", "volunteer", "work", "drive", "party", "compete", "perform", "rebel", "dream", "plan", "date", "experiment"]; objects = ["phone", "car", "guitar", "computer", "books", "sports equipment", "clothes", "music", "video games"]; people = ["friends", "crush", "teammates", "family", "teachers", "boss", "mentor"]; places = ["school", "mall", "concert", "party", "gym", "job", "car", "room", "hangout spot"]; emotions = ["confident", "nervous", "excited", "rebellious", "passionate", "confused", "determined", "social"]; skills = ["driving", "leadership", "sports", "music", "academics", "social skills", "independence"]; challenges = ["peer pressure", "responsibilities", "identity", "relationships", "future planning"]; decisionTemplates = ["[activity] with [people] at [places]", "Deal with [challenges] by [activity]", "Use your [objects] to [activity]", "Feel [emotions] and [activity]", "Practice [skills] through [activity]", "Balance [activity] with responsibilities"]; responseTemplates = ["You feel [emotions] and more mature.", "This helps you understand [challenges] better.", "[people] respects your [skills].", "You're becoming more independent.", "This experience shapes who you're becoming.", "You learn valuable life lessons.", "Your [skills] improves significantly."]; } else if (stage === "adult") { activities = ["work", "travel", "cook", "exercise", "invest", "network", "create", "mentor", "innovate", "lead", "balance", "achieve"]; objects = ["career", "home", "car", "savings", "relationship", "family", "business", "skills", "goals"]; people = ["spouse", "children", "colleagues", "boss", "friends", "parents", "mentees", "clients"]; places = ["office", "home", "gym", "restaurant", "vacation spot", "conference", "neighborhood"]; emotions = ["accomplished", "stressed", "fulfilled", "ambitious", "responsible", "wise", "experienced"]; skills = ["management", "parenting", "financial planning", "communication", "expertise", "leadership"]; challenges = ["work-life balance", "career growth", "family responsibilities", "financial planning", "health"]; decisionTemplates = ["Focus on [skills] at [places]", "Balance [objects] with [people]", "[activity] to improve [challenges]", "Invest time in [objects]", "[activity] with [people] for [objects]", "Handle [challenges] by [activity]"]; responseTemplates = ["You feel [emotions] with your progress.", "This strengthens your [objects].", "[people] appreciates your [skills].", "You're building a meaningful life.", "This decision pays off in the long run.", "You're becoming the person you want to be.", "Your [skills] reaches new heights."]; } else { // elder activities = ["reflect", "share", "mentor", "volunteer", "relax", "remember", "teach", "enjoy", "appreciate", "guide", "celebrate"]; objects = ["wisdom", "memories", "family", "health", "legacy", "stories", "experience", "peace"]; people = ["grandchildren", "family", "friends", "community", "younger generation"]; places = ["home", "park", "family gatherings", "community center", "garden", "favorite spots"]; emotions = ["peaceful", "wise", "grateful", "content", "nostalgic", "proud", "serene"]; skills = ["wisdom sharing", "mentoring", "patience", "appreciation", "reflection"]; challenges = ["health", "loneliness", "changing times", "legacy building"]; decisionTemplates = ["Share [objects] with [people]", "[activity] about [objects]", "Enjoy [places] with [people]", "[activity] and feel [emotions]", "Pass on [skills] to [people]", "Find [emotions] in [activity]"]; responseTemplates = ["You feel [emotions] and fulfilled.", "[people] treasures your [objects].", "This brings you deep satisfaction.", "You're leaving a meaningful [objects].", "Your [skills] touches many lives.", "You find joy in simple moments.", "Life feels [emotions] and complete."]; } // Generate 2-4 unique decisions var numOptions = 2 + Math.floor(Math.random() * 3); var options = []; var usedTexts = {}; for (var i = 0; i < numOptions; i++) { var attempts = 0; var decisionText, responseText; do { // Pick random templates var template = decisionTemplates[Math.floor(Math.random() * decisionTemplates.length)]; var responseTemplate = responseTemplates[Math.floor(Math.random() * responseTemplates.length)]; // Fill in template with random words decisionText = template; responseText = responseTemplate; if (activities.length > 0) { decisionText = decisionText.replace(/\[activity\]/g, activities[Math.floor(Math.random() * activities.length)]); responseText = responseText.replace(/\[activity\]/g, activities[Math.floor(Math.random() * activities.length)]); } if (objects.length > 0) { decisionText = decisionText.replace(/\[objects\]/g, objects[Math.floor(Math.random() * objects.length)]); responseText = responseText.replace(/\[objects\]/g, objects[Math.floor(Math.random() * objects.length)]); } if (people.length > 0) { decisionText = decisionText.replace(/\[people\]/g, people[Math.floor(Math.random() * people.length)]); responseText = responseText.replace(/\[people\]/g, people[Math.floor(Math.random() * people.length)]); } if (places.length > 0) { decisionText = decisionText.replace(/\[places\]/g, places[Math.floor(Math.random() * places.length)]); responseText = responseText.replace(/\[places\]/g, places[Math.floor(Math.random() * places.length)]); } if (emotions.length > 0) { decisionText = decisionText.replace(/\[emotions\]/g, emotions[Math.floor(Math.random() * emotions.length)]); responseText = responseText.replace(/\[emotions\]/g, emotions[Math.floor(Math.random() * emotions.length)]); } if (skills.length > 0) { decisionText = decisionText.replace(/\[skills\]/g, skills[Math.floor(Math.random() * skills.length)]); responseText = responseText.replace(/\[skills\]/g, skills[Math.floor(Math.random() * skills.length)]); } if (challenges.length > 0) { decisionText = decisionText.replace(/\[challenges\]/g, challenges[Math.floor(Math.random() * challenges.length)]); responseText = responseText.replace(/\[challenges\]/g, challenges[Math.floor(Math.random() * challenges.length)]); } // Capitalize first letter decisionText = decisionText.charAt(0).toUpperCase() + decisionText.slice(1); responseText = responseText.charAt(0).toUpperCase() + responseText.slice(1); attempts++; } while (usedTexts[decisionText] && attempts < 10); if (!usedTexts[decisionText]) { usedTexts[decisionText] = true; options.push({ text: decisionText, onSelect: function (response) { return function () { showEvent(response); decisionTime = false; }; }(responseText) }); } } return options; } // Game state var age = 0; var day = 0; var maxAge = 100; var avatar = null; var ageUpBtn = null; var ageText = null; var eventPopup = null; var milestoneShown = {}; // To avoid showing same milestone twice var parents = []; // To store parent avatars var dayText = null; var decisionTime = false; // If true, show decision popup on day age up // Center positions var centerX = 2048 / 2; var centerY = 2732 / 2; // Add parents (simple: two parent avatars, left and right of baby) function addParents() { // Only add once if (parents.length > 0) return; var parent1 = new Avatar(); parent1.setStage('adult'); parent1.x = centerX - 350; parent1.y = centerY - 350; game.addChild(parent1); var parent2 = new Avatar(); parent2.setStage('adult'); parent2.x = centerX + 350; parent2.y = centerY - 350; game.addChild(parent2); parents.push(parent1, parent2); } addParents(); // Add avatar avatar = new Avatar(); avatar.x = centerX; avatar.y = centerY - 350; game.addChild(avatar); // Age text ageText = new Text2('Age: 0y 0m', { size: 120, fill: 0x333333 }); ageText.anchor.set(0.5, 0); ageText.x = centerX; ageText.y = 200; game.addChild(ageText); // Day text dayText = new Text2('Day: 0', { size: 80, fill: 0x666666 }); dayText.anchor.set(0.5, 0); dayText.x = centerX; dayText.y = 320; game.addChild(dayText); // Age Up buttons for year, month, week, day var ageUpBtns = []; var ageUpTypes = [{ label: "Age Up 10 Years", type: "ten_years" }, { label: "Age Up 1 Year", type: "year" }, { label: "Age Up 1 Month", type: "month" }, { label: "Age Up 1 Week", type: "week" }, { label: "Age Up 1 Day", type: "day" }]; var btnSpacing = 220; for (var i = 0; i < ageUpTypes.length; i++) { (function (idx) { var btn = new AgeUpButton(); btn.x = centerX; btn.y = centerY + 400 + idx * btnSpacing; btn.children[1].setText(ageUpTypes[idx].label); // Set label btn.ageType = ageUpTypes[idx].type; btn.down = function (x, y, obj) { btn.flash(); doAgeUp(btn.ageType); }; game.addChild(btn); ageUpBtns.push(btn); })(i); } // Event popup eventPopup = new EventPopup(); eventPopup.x = centerX; eventPopup.y = centerY; game.addChild(eventPopup); // Show event helper function showEvent(text, options) { eventPopup.visible = true; if (!options) { options = [{ text: "OK", onSelect: function onSelect() { eventPopup.hide(); } }]; } eventPopup.show(text, options); } // Show milestone if available function checkMilestone() { if (milestoneEvents[age] && !milestoneShown[age]) { milestoneShown[age] = true; var event = milestoneEvents[age]; // Wrap options to always hide popup after selection var opts = []; for (var i = 0; i < event.options.length; i++) { (function (idx) { var opt = event.options[idx]; opts.push({ text: opt.text, onSelect: function onSelect() { if (opt.onSelect) opt.onSelect(); eventPopup.hide(); } }); })(i); } showEvent(event.text, opts); } } // Age up logic function doAgeUp(type) { if (eventPopup.visible) return; // Don't age up while popup is open if (age >= maxAge) return; // If it's decision time, show a decision popup instead of aging up if (decisionTime) { var options = generateAgeBasedDecisions(); showEvent("It's decision time! What will you do today?", options); return; } var daysToAdd = 1; if (type === "ten_years") daysToAdd = 3650;else if (type === "year") daysToAdd = 365;else if (type === "month") daysToAdd = 30;else if (type === "week") daysToAdd = 7;else daysToAdd = 1; for (var i = 0; i < daysToAdd; i++) { if (age >= maxAge) break; day += 1; // Every 7 days, age up by one year if (day % 7 === 0) { age += 1; // Animate avatar "growing" tween(avatar, { scaleX: 1.1, scaleY: 1.1 }, { duration: 120, onFinish: function onFinish() { tween(avatar, { scaleX: 1, scaleY: 1 }, { duration: 120 }); } }); // Update avatar stage if needed var newStage = getStageByAge(age); if (avatar.stage !== newStage) { avatar.setStage(newStage); } // Show milestone if any checkMilestone(); // End of life if (age === maxAge) { LK.effects.flashScreen(0x000000, 1200); LK.showGameOver(); break; } } // Every 3 days, trigger a decision time if (day % 3 === 0) { decisionTime = true; break; } } // Calculate years and months for display var years = age; var months = Math.floor(day % 365 / 30); ageText.setText('Age: ' + years + 'y ' + months + 'm'); dayText.setText('Day: ' + day); } // Also allow clicking anywhere on avatar to age up one day avatar.down = function (x, y, obj) { doAgeUp("day"); }; // Prevent interaction when popup is open game.down = function (x, y, obj) { if (eventPopup.visible) { // Dismiss popup if click outside options eventPopup.hide(); } }; // Show first milestone at start checkMilestone(); // No need for update loop for MVP // GUI: Show age at top right corner LK.gui.topRight.addChild(ageText); LK.gui.top.addChild(dayText);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// AgeUpButton class
var AgeUpButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('ageup_btn', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('Age Up', {
size: 70,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
label.x = 0;
label.y = 0;
self.addChild(label);
// For click feedback
self.flash = function () {
tween(btn, {
tint: 0x80ff80
}, {
duration: 100,
onFinish: function onFinish() {
tween(btn, {
tint: 0x43aa8b
}, {
duration: 200
});
}
});
};
return self;
});
// Avatar class for displaying the character at different ages
var Avatar = Container.expand(function () {
var self = Container.call(this);
// Default to baby
self.stage = 'baby';
self.avatarNode = null;
self.setStage = function (stage) {
self.stage = stage;
if (self.avatarNode) {
self.avatarNode.destroy();
}
var assetId = 'avatar_' + stage;
self.avatarNode = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
// Initialize as baby
self.setStage('baby');
return self;
});
// EventPopup class for showing milestone or choice events
var EventPopup = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('event_bg', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2('', {
size: 60,
fill: 0x222222,
wordWrap: true,
wordWrapWidth: 1100
});
self.text.anchor.set(0.5, 0.5);
self.text.x = 0;
self.text.y = -100;
self.addChild(self.text);
// Option buttons (max 2 for MVP)
self.optionBtns = [];
// Show popup with text and options
self.show = function (text, options) {
self.text.setText(text);
// Remove old buttons
for (var i = 0; i < self.optionBtns.length; i++) {
self.optionBtns[i].destroy();
}
self.optionBtns = [];
// Create new buttons
var btnY = 120;
for (var i = 0; i < options.length; i++) {
(function (idx) {
var opt = options[idx];
var btn = new Container();
var btnBg = btn.attachAsset('ageup_btn', {
anchorX: 0.5,
anchorY: 0.5,
width: 500,
height: 100
});
btn.x = 0;
btn.y = btnY + idx * 130;
var btnLabel = new Text2(opt.text, {
size: 48,
fill: 0xFFFFFF
});
btnLabel.anchor.set(0.5, 0.5);
btn.addChild(btnLabel);
btn.down = function (x, y, obj) {
// Animate feedback
tween(btnBg, {
tint: 0x80ff80
}, {
duration: 100,
onFinish: function onFinish() {
tween(btnBg, {
tint: 0x43aa8b
}, {
duration: 200
});
}
});
// Call option handler
if (opt.onSelect) {
opt.onSelect();
}
};
self.addChild(btn);
self.optionBtns.push(btn);
})(i);
}
};
// Hide popup
self.hide = function () {
for (var i = 0; i < self.optionBtns.length; i++) {
self.optionBtns[i].destroy();
}
self.optionBtns = [];
self.text.setText('');
self.visible = false;
};
// Start hidden
self.visible = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf7f7f7
});
/****
* Game Code
****/
// Life stages and their age ranges
// Character avatars for each life stage (baby, child, teen, adult, elder)
// Button for "Age Up"
// Event popup background
var lifeStages = [{
stage: 'baby',
min: 0,
max: 2
}, {
stage: 'child',
min: 3,
max: 12
}, {
stage: 'teen',
min: 13,
max: 19
}, {
stage: 'adult',
min: 20,
max: 64
}, {
stage: 'elder',
min: 65,
max: 120
}];
// Milestone events per age (MVP: a few per stage)
var milestoneEvents = {
0: {
text: "Welcome to the world! You are a newborn baby.",
options: [{
text: "Continue"
}]
},
1: {
text: "You take your first steps!",
options: [{
text: "Yay!"
}]
},
5: {
text: "You start school. Do you want to make a new friend?",
options: [{
text: "Yes",
onSelect: function onSelect() {
showEvent("You made a new friend!");
}
}, {
text: "No",
onSelect: function onSelect() {
showEvent("You prefer to play alone for now.");
}
}]
},
13: {
text: "You become a teenager. Time for high school!",
options: [{
text: "Bring it on!"
}]
},
18: {
text: "You graduate high school. What will you do?",
options: [{
text: "Go to college",
onSelect: function onSelect() {
showEvent("You start college life!");
}
}, {
text: "Start working",
onSelect: function onSelect() {
showEvent("You get your first job!");
}
}]
},
30: {
text: "You reach adulthood. Do you want to travel?",
options: [{
text: "Yes",
onSelect: function onSelect() {
showEvent("You see the world and gain new experiences!");
}
}, {
text: "No",
onSelect: function onSelect() {
showEvent("You focus on your career.");
}
}]
},
65: {
text: "You retire! Time to relax and enjoy your golden years.",
options: [{
text: "Celebrate"
}]
},
90: {
text: "You reflect on a life well lived.",
options: [{
text: "The End"
}]
}
};
// Helper to get stage by age
function getStageByAge(age) {
for (var i = 0; i < lifeStages.length; i++) {
if (age >= lifeStages[i].min && age <= lifeStages[i].max) {
return lifeStages[i].stage;
}
}
return 'elder';
}
// Generate infinite age-based decisions
function generateAgeBasedDecisions() {
var stage = getStageByAge(age);
var decisionTemplates = [];
var responseTemplates = [];
var activities = [];
var emotions = [];
var objects = [];
var people = [];
var places = [];
var skills = [];
var challenges = [];
if (stage === "baby") {
activities = ["cuddle", "cry", "sleep", "babble", "giggle", "stare", "reach", "wiggle", "smile", "coo", "suck thumb", "kick legs", "roll over", "grab", "listen"];
objects = ["mobile", "toy", "blanket", "bottle", "rattle", "stuffed animal", "colorful shapes", "music box", "soft fabric", "shiny object"];
people = ["mommy", "daddy", "sibling", "grandparent", "caregiver", "visitor"];
emotions = ["happy", "sleepy", "curious", "content", "fussy", "excited", "calm", "surprised"];
decisionTemplates = ["[activity] with [people]", "[activity] at the [objects]", "Feel [emotions] and [activity]", "Try to [activity]", "[activity] because you're [emotions]"];
responseTemplates = ["You feel [emotions] and [emotions].", "[people] smiles at you lovingly.", "The [objects] captures your attention.", "You discover something wonderful!", "This makes you feel safe and loved.", "You're learning about the world around you."];
} else if (stage === "child") {
activities = ["play", "draw", "build", "read", "run", "jump", "sing", "dance", "explore", "help", "learn", "share", "imagine", "create", "discover"];
objects = ["blocks", "crayons", "book", "toy car", "doll", "puzzle", "ball", "bike", "sandbox", "swing", "slide", "art supplies", "games"];
people = ["friends", "parents", "teacher", "siblings", "classmates", "neighbor", "pets"];
places = ["playground", "school", "backyard", "park", "bedroom", "kitchen", "library", "store"];
emotions = ["excited", "proud", "curious", "happy", "silly", "adventurous", "creative", "friendly"];
skills = ["counting", "writing", "riding", "swimming", "climbing", "sharing", "reading"];
decisionTemplates = ["[activity] with [objects] at the [places]", "Help [people] with something", "Practice [skills]", "[activity] and feel [emotions]", "Go to [places] and [activity]", "Share [objects] with [people]", "Learn about [skills] by [activity]"];
responseTemplates = ["You have so much fun [activity]!", "[people] is proud of your [skills].", "You feel [emotions] and accomplished.", "This helps you grow and learn.", "You make new friends while [activity].", "Your imagination runs wild!", "You discover you're good at [skills]."];
} else if (stage === "teen") {
activities = ["study", "hang out", "practice", "volunteer", "work", "drive", "party", "compete", "perform", "rebel", "dream", "plan", "date", "experiment"];
objects = ["phone", "car", "guitar", "computer", "books", "sports equipment", "clothes", "music", "video games"];
people = ["friends", "crush", "teammates", "family", "teachers", "boss", "mentor"];
places = ["school", "mall", "concert", "party", "gym", "job", "car", "room", "hangout spot"];
emotions = ["confident", "nervous", "excited", "rebellious", "passionate", "confused", "determined", "social"];
skills = ["driving", "leadership", "sports", "music", "academics", "social skills", "independence"];
challenges = ["peer pressure", "responsibilities", "identity", "relationships", "future planning"];
decisionTemplates = ["[activity] with [people] at [places]", "Deal with [challenges] by [activity]", "Use your [objects] to [activity]", "Feel [emotions] and [activity]", "Practice [skills] through [activity]", "Balance [activity] with responsibilities"];
responseTemplates = ["You feel [emotions] and more mature.", "This helps you understand [challenges] better.", "[people] respects your [skills].", "You're becoming more independent.", "This experience shapes who you're becoming.", "You learn valuable life lessons.", "Your [skills] improves significantly."];
} else if (stage === "adult") {
activities = ["work", "travel", "cook", "exercise", "invest", "network", "create", "mentor", "innovate", "lead", "balance", "achieve"];
objects = ["career", "home", "car", "savings", "relationship", "family", "business", "skills", "goals"];
people = ["spouse", "children", "colleagues", "boss", "friends", "parents", "mentees", "clients"];
places = ["office", "home", "gym", "restaurant", "vacation spot", "conference", "neighborhood"];
emotions = ["accomplished", "stressed", "fulfilled", "ambitious", "responsible", "wise", "experienced"];
skills = ["management", "parenting", "financial planning", "communication", "expertise", "leadership"];
challenges = ["work-life balance", "career growth", "family responsibilities", "financial planning", "health"];
decisionTemplates = ["Focus on [skills] at [places]", "Balance [objects] with [people]", "[activity] to improve [challenges]", "Invest time in [objects]", "[activity] with [people] for [objects]", "Handle [challenges] by [activity]"];
responseTemplates = ["You feel [emotions] with your progress.", "This strengthens your [objects].", "[people] appreciates your [skills].", "You're building a meaningful life.", "This decision pays off in the long run.", "You're becoming the person you want to be.", "Your [skills] reaches new heights."];
} else {
// elder
activities = ["reflect", "share", "mentor", "volunteer", "relax", "remember", "teach", "enjoy", "appreciate", "guide", "celebrate"];
objects = ["wisdom", "memories", "family", "health", "legacy", "stories", "experience", "peace"];
people = ["grandchildren", "family", "friends", "community", "younger generation"];
places = ["home", "park", "family gatherings", "community center", "garden", "favorite spots"];
emotions = ["peaceful", "wise", "grateful", "content", "nostalgic", "proud", "serene"];
skills = ["wisdom sharing", "mentoring", "patience", "appreciation", "reflection"];
challenges = ["health", "loneliness", "changing times", "legacy building"];
decisionTemplates = ["Share [objects] with [people]", "[activity] about [objects]", "Enjoy [places] with [people]", "[activity] and feel [emotions]", "Pass on [skills] to [people]", "Find [emotions] in [activity]"];
responseTemplates = ["You feel [emotions] and fulfilled.", "[people] treasures your [objects].", "This brings you deep satisfaction.", "You're leaving a meaningful [objects].", "Your [skills] touches many lives.", "You find joy in simple moments.", "Life feels [emotions] and complete."];
}
// Generate 2-4 unique decisions
var numOptions = 2 + Math.floor(Math.random() * 3);
var options = [];
var usedTexts = {};
for (var i = 0; i < numOptions; i++) {
var attempts = 0;
var decisionText, responseText;
do {
// Pick random templates
var template = decisionTemplates[Math.floor(Math.random() * decisionTemplates.length)];
var responseTemplate = responseTemplates[Math.floor(Math.random() * responseTemplates.length)];
// Fill in template with random words
decisionText = template;
responseText = responseTemplate;
if (activities.length > 0) {
decisionText = decisionText.replace(/\[activity\]/g, activities[Math.floor(Math.random() * activities.length)]);
responseText = responseText.replace(/\[activity\]/g, activities[Math.floor(Math.random() * activities.length)]);
}
if (objects.length > 0) {
decisionText = decisionText.replace(/\[objects\]/g, objects[Math.floor(Math.random() * objects.length)]);
responseText = responseText.replace(/\[objects\]/g, objects[Math.floor(Math.random() * objects.length)]);
}
if (people.length > 0) {
decisionText = decisionText.replace(/\[people\]/g, people[Math.floor(Math.random() * people.length)]);
responseText = responseText.replace(/\[people\]/g, people[Math.floor(Math.random() * people.length)]);
}
if (places.length > 0) {
decisionText = decisionText.replace(/\[places\]/g, places[Math.floor(Math.random() * places.length)]);
responseText = responseText.replace(/\[places\]/g, places[Math.floor(Math.random() * places.length)]);
}
if (emotions.length > 0) {
decisionText = decisionText.replace(/\[emotions\]/g, emotions[Math.floor(Math.random() * emotions.length)]);
responseText = responseText.replace(/\[emotions\]/g, emotions[Math.floor(Math.random() * emotions.length)]);
}
if (skills.length > 0) {
decisionText = decisionText.replace(/\[skills\]/g, skills[Math.floor(Math.random() * skills.length)]);
responseText = responseText.replace(/\[skills\]/g, skills[Math.floor(Math.random() * skills.length)]);
}
if (challenges.length > 0) {
decisionText = decisionText.replace(/\[challenges\]/g, challenges[Math.floor(Math.random() * challenges.length)]);
responseText = responseText.replace(/\[challenges\]/g, challenges[Math.floor(Math.random() * challenges.length)]);
}
// Capitalize first letter
decisionText = decisionText.charAt(0).toUpperCase() + decisionText.slice(1);
responseText = responseText.charAt(0).toUpperCase() + responseText.slice(1);
attempts++;
} while (usedTexts[decisionText] && attempts < 10);
if (!usedTexts[decisionText]) {
usedTexts[decisionText] = true;
options.push({
text: decisionText,
onSelect: function (response) {
return function () {
showEvent(response);
decisionTime = false;
};
}(responseText)
});
}
}
return options;
}
// Game state
var age = 0;
var day = 0;
var maxAge = 100;
var avatar = null;
var ageUpBtn = null;
var ageText = null;
var eventPopup = null;
var milestoneShown = {}; // To avoid showing same milestone twice
var parents = []; // To store parent avatars
var dayText = null;
var decisionTime = false; // If true, show decision popup on day age up
// Center positions
var centerX = 2048 / 2;
var centerY = 2732 / 2;
// Add parents (simple: two parent avatars, left and right of baby)
function addParents() {
// Only add once
if (parents.length > 0) return;
var parent1 = new Avatar();
parent1.setStage('adult');
parent1.x = centerX - 350;
parent1.y = centerY - 350;
game.addChild(parent1);
var parent2 = new Avatar();
parent2.setStage('adult');
parent2.x = centerX + 350;
parent2.y = centerY - 350;
game.addChild(parent2);
parents.push(parent1, parent2);
}
addParents();
// Add avatar
avatar = new Avatar();
avatar.x = centerX;
avatar.y = centerY - 350;
game.addChild(avatar);
// Age text
ageText = new Text2('Age: 0y 0m', {
size: 120,
fill: 0x333333
});
ageText.anchor.set(0.5, 0);
ageText.x = centerX;
ageText.y = 200;
game.addChild(ageText);
// Day text
dayText = new Text2('Day: 0', {
size: 80,
fill: 0x666666
});
dayText.anchor.set(0.5, 0);
dayText.x = centerX;
dayText.y = 320;
game.addChild(dayText);
// Age Up buttons for year, month, week, day
var ageUpBtns = [];
var ageUpTypes = [{
label: "Age Up 10 Years",
type: "ten_years"
}, {
label: "Age Up 1 Year",
type: "year"
}, {
label: "Age Up 1 Month",
type: "month"
}, {
label: "Age Up 1 Week",
type: "week"
}, {
label: "Age Up 1 Day",
type: "day"
}];
var btnSpacing = 220;
for (var i = 0; i < ageUpTypes.length; i++) {
(function (idx) {
var btn = new AgeUpButton();
btn.x = centerX;
btn.y = centerY + 400 + idx * btnSpacing;
btn.children[1].setText(ageUpTypes[idx].label); // Set label
btn.ageType = ageUpTypes[idx].type;
btn.down = function (x, y, obj) {
btn.flash();
doAgeUp(btn.ageType);
};
game.addChild(btn);
ageUpBtns.push(btn);
})(i);
}
// Event popup
eventPopup = new EventPopup();
eventPopup.x = centerX;
eventPopup.y = centerY;
game.addChild(eventPopup);
// Show event helper
function showEvent(text, options) {
eventPopup.visible = true;
if (!options) {
options = [{
text: "OK",
onSelect: function onSelect() {
eventPopup.hide();
}
}];
}
eventPopup.show(text, options);
}
// Show milestone if available
function checkMilestone() {
if (milestoneEvents[age] && !milestoneShown[age]) {
milestoneShown[age] = true;
var event = milestoneEvents[age];
// Wrap options to always hide popup after selection
var opts = [];
for (var i = 0; i < event.options.length; i++) {
(function (idx) {
var opt = event.options[idx];
opts.push({
text: opt.text,
onSelect: function onSelect() {
if (opt.onSelect) opt.onSelect();
eventPopup.hide();
}
});
})(i);
}
showEvent(event.text, opts);
}
}
// Age up logic
function doAgeUp(type) {
if (eventPopup.visible) return; // Don't age up while popup is open
if (age >= maxAge) return;
// If it's decision time, show a decision popup instead of aging up
if (decisionTime) {
var options = generateAgeBasedDecisions();
showEvent("It's decision time! What will you do today?", options);
return;
}
var daysToAdd = 1;
if (type === "ten_years") daysToAdd = 3650;else if (type === "year") daysToAdd = 365;else if (type === "month") daysToAdd = 30;else if (type === "week") daysToAdd = 7;else daysToAdd = 1;
for (var i = 0; i < daysToAdd; i++) {
if (age >= maxAge) break;
day += 1;
// Every 7 days, age up by one year
if (day % 7 === 0) {
age += 1;
// Animate avatar "growing"
tween(avatar, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 120,
onFinish: function onFinish() {
tween(avatar, {
scaleX: 1,
scaleY: 1
}, {
duration: 120
});
}
});
// Update avatar stage if needed
var newStage = getStageByAge(age);
if (avatar.stage !== newStage) {
avatar.setStage(newStage);
}
// Show milestone if any
checkMilestone();
// End of life
if (age === maxAge) {
LK.effects.flashScreen(0x000000, 1200);
LK.showGameOver();
break;
}
}
// Every 3 days, trigger a decision time
if (day % 3 === 0) {
decisionTime = true;
break;
}
}
// Calculate years and months for display
var years = age;
var months = Math.floor(day % 365 / 30);
ageText.setText('Age: ' + years + 'y ' + months + 'm');
dayText.setText('Day: ' + day);
}
// Also allow clicking anywhere on avatar to age up one day
avatar.down = function (x, y, obj) {
doAgeUp("day");
};
// Prevent interaction when popup is open
game.down = function (x, y, obj) {
if (eventPopup.visible) {
// Dismiss popup if click outside options
eventPopup.hide();
}
};
// Show first milestone at start
checkMilestone();
// No need for update loop for MVP
// GUI: Show age at top right corner
LK.gui.topRight.addChild(ageText);
LK.gui.top.addChild(dayText);