User prompt
Make sure the tracking graph is viewers on the statistics screen.
User prompt
Make sure the tracking graph is visible on the statistics screen.
User prompt
Split the statistics screen into 3 and make subscriber, view and money graphs appear separately. Currently only the subscriber graph is visible, fix this.
User prompt
have 3 different line graphs on the statistics screen. money, views and subscribe . List them one below the other like a list.
User prompt
have 3 different line graphs on the statistics screen. money, subscribers and views
User prompt
There is only a subscriber graph on the statistics screen right now. Add the money graph and the viewer graph as well.
User prompt
Restore the statistics screen to its old state. There is only a subscriber counter on the statistics screen now.
User prompt
Don't give an extra reward when the publishing loading bar is full. Remove the video from the video list when the publishing loading bar is full.
User prompt
Make sure the publishing loading bar is filled in 7 days.
User prompt
Make sure videos continue to be watched until the publishing loading bar is full.
User prompt
Place the edit/publish button at the bottom of the video's background in the video list
User prompt
Place the edit button in the video list at the bottom of the video's background and remove the loading bar behind the edit button.
User prompt
Please fix the bug: 'Uncaught ReferenceError: stateTxt is not defined' in or related to this line: 'barBg.y = stateTxt.y + stateTxt.height + 18;' Line Number: 410
User prompt
Remove text that says just published, gainin views etc. in the video list.
User prompt
The edit button is above the loading bar, please center the edit button.
User prompt
The recording loading bar is not filling.
User prompt
Before the record video stream starts, show that video in the video list and let's see how long it will take to record the video with the loading bar.
User prompt
After the record video stage, add a loading bar so we can track when the video will be shot.
User prompt
Bring back loading bars in video list.
User prompt
You need to bring back the edit and publish buttons on videos right now, the flow is not continuing.
User prompt
There should be 5 videos in a single line of the video list. After there are 5 videos, they should move to the next line.
User prompt
Position the video list 50 pixels further to the left.
User prompt
Position the video list 10 pixels further to the left.
User prompt
Add the name of the videos shot, the number of views, the money earned, the number of subscribers and their status into the created background.
User prompt
List the videos shot in the game on a square background with the text below each other and do this separately for each video and the videos will be listed side by side.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Energy bar class var EnergyBar = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('energyBarBg', { anchorX: 0, anchorY: 0.5 }); self.fill = self.attachAsset('energyBarFill', { anchorX: 0, anchorY: 0.5 }); self.fill.x = 0; self.bg.x = 0; self.bg.y = 0; self.fill.y = 0; self.maxWidth = self.fill.width; self.set = function (ratio) { if (ratio < 0) { ratio = 0; } if (ratio > 1) { ratio = 1; } self.fill.width = self.maxWidth * ratio; }; return self; }); // Button class for all clickable actions var GameButton = Container.expand(function () { var self = Container.call(this); self.bg = null; self.label = null; self.action = null; self.enabled = true; self.setButton = function (assetId, labelText, color, width, height) { self.bg = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.bg.width = width; self.bg.height = height; // Modern look: more pronounced rounded corners and soft drop shadow self.bg.cornerRadius = Math.min(width, height) * 0.28; self.bg.shadow = { color: 0x111111, blur: 36, offsetX: 0, offsetY: 16, alpha: 0.32 }; self.label = new Text2(labelText, { size: 80, fill: color, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 12, dropShadowDistance: 2 }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); }; self.setEnabled = function (val) { self.enabled = val; if (self.bg) { self.bg.alpha = val ? 1 : 0.4; } }; self.down = function (x, y, obj) { if (!self.enabled) { return; } if (typeof self.action === 'function') { self.action(); } }; return self; }); // VideoListItem: displays a video in the list with title, state, and stats var VideoListItem = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('loadingbarempty', { anchorX: 0, anchorY: 0.5 }); self.bg.width = 1200; self.bg.height = 120; self.bg.alpha = 0.92; self.titleTxt = new Text2("", { size: 56, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); self.titleTxt.anchor.set(0, 0.5); self.titleTxt.x = 40; self.titleTxt.y = 0; self.addChild(self.titleTxt); self.stateTxt = new Text2("", { size: 44, fill: "#ff0", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); self.stateTxt.anchor.set(0, 0.5); self.stateTxt.x = 500; self.stateTxt.y = 0; self.addChild(self.stateTxt); self.statsTxt = new Text2("", { size: 44, fill: "#0ff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); self.statsTxt.anchor.set(0, 0.5); self.statsTxt.x = 800; self.statsTxt.y = 0; self.addChild(self.statsTxt); self.setVideo = function (videoObj) { self.titleTxt.setText(videoObj.title || "Untitled"); // State: Recording, Gaining Views, Finished if (videoObj.hour === 0 && !videoObj.finished) { self.stateTxt.setText("Just Published"); } else if (!videoObj.finished) { self.stateTxt.setText("Gaining Views"); } else { self.stateTxt.setText("Finished"); } // Stats: views, money, subs var stats = formatNumber(videoObj.totalViews) + " views"; // Truncate money to 2 decimal digits for display in video list var moneyDisplay = Math.floor(videoObj.totalMoney * 100) / 100; stats += " | $" + formatNumber(moneyDisplay); stats += " | " + formatNumber(videoObj.totalSubs) + " subs"; if (videoObj.trending) { stats += " | 🔥"; } self.statsTxt.setText(stats); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Video Categories (must be defined before use in updateTrendingCategory) --- // --- Trending Category State --- var videoCategories = ["Vlog", "Challenge", "Reaction", "Tutorial", "Unboxing", "Gaming", "Music", "Comedy", "Q&A", "Other"]; var selectedCategoryIdx = 0; // Studio background (simple box for now) // --- Game State Variables --- var trendingCategoryIdx = 0; var trendingCategoryDay = 1; // The day this trending category started function updateTrendingCategory() { // Pick a new trending category index, different from the current one if possible var oldIdx = trendingCategoryIdx; if (videoCategories && videoCategories.length > 1) { var newIdx; do { newIdx = Math.floor(Math.random() * videoCategories.length); } while (newIdx === oldIdx); trendingCategoryIdx = newIdx; } else { trendingCategoryIdx = 0; } trendingCategoryDay = gameDay; // Set next change day if not already set if (typeof trendingCategoryNextChangeDay === "undefined") { trendingCategoryNextChangeDay = trendingCategoryDay + 7 + Math.floor(Math.random() * 24); // 7-30 days } } // If the record video panel is open, update the trending label text if it exists if (typeof isRecordPanelOpen !== "undefined" && isRecordPanelOpen && typeof categoryBtns !== "undefined") { for (var i = 0; i < categoryBtns.length; i++) { if (categoryBtns[i].trendingTxt) { categoryBtns[i].trendingTxt.setText("Trending"); // Move trending label to the new trending category if (i === trendingCategoryIdx) { categoryBtns[i].trendingTxt.visible = true; } else { categoryBtns[i].trendingTxt.visible = false; } } // Update button highlight for trending if (i === trendingCategoryIdx) { categoryBtns[i].bg.alpha = 0.95; if (categoryBtns[i].trendingTxt) { categoryBtns[i].trendingTxt.visible = true; } } else { if (categoryBtns[i].trendingTxt) { categoryBtns[i].trendingTxt.visible = false; } if (i !== selectedCategoryIdx) { categoryBtns[i].bg.alpha = 0.7; } } } } // Video button // Edit button // Promote button // Upgrade button // Energy bar background // Energy bar fill // Subscriber icon // Money icon // Sound for making a video var subscribers = 0; var viewCount = 0; var money = 0; var videoQuality = 1; // upgrades increase this var editSkill = 1; // upgrades increase this var promoteSkill = 1; // upgrades increase this var videoCount = 0; var upgradeCost = 20; var upgradeLevel = 1; // --- Time Mechanics --- var gameHour = 8; // Start at 8:00 var gameDay = 1; var isTimePaused = false; var timeTimer = null; var timeProcess = null; // {type: 'record'|'edit'|'promote', hoursLeft: int, onFinish: fn} // --- UI Elements --- var studioBg = LK.getAsset('studioBg', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(studioBg); var computerBg = LK.getAsset('computerbackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(computerBg); var computerScreen = LK.getAsset('computerscreen', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 485 }); game.addChild(computerScreen); // --- Time Display --- // Place time text to the right of the money text var timeTxt = new Text2('Day 1, 08:00', { size: 44, fill: 0xFFFFFF }); timeTxt.anchor.set(0, 0.5); // Will be positioned after moneyTxt is created and positioned // --- Video List UI --- // Video list container (horizontal, each video on a square background, text below, side by side) var videoListContainer = new Container(); videoListContainer.x = 110; // leave margin from left (avoid top left 100x100), moved 10px further left videoListContainer.y = 450; // below counters row game.addChild(videoListContainer); // Helper to update the video list display function updateVideoLists() { // Remove all previous children while (videoListContainer.children.length > 0) { videoListContainer.children[0].destroy(); } if (!window.uploadedVideos || window.uploadedVideos.length === 0) { return; } var squareSize = 340; var spacing = 48; for (var i = 0; i < window.uploadedVideos.length; i++) { var video = window.uploadedVideos[i]; // Square background var bg = LK.getAsset('loadingbarempty', { anchorX: 0.5, anchorY: 0.5 }); bg.width = squareSize; bg.height = squareSize; bg.x = i * (squareSize + spacing) + squareSize / 2; bg.y = squareSize / 2; bg.alpha = 0.93; videoListContainer.addChild(bg); // Video name (title) - top of square var nameTxt = new Text2(video.title || "Untitled", { size: 44, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); nameTxt.anchor.set(0.5, 0); nameTxt.x = bg.x; nameTxt.y = bg.y - squareSize / 2 + 18; videoListContainer.addChild(nameTxt); // Views - below name var viewsTxt = new Text2(formatNumber(video.totalViews) + " views", { size: 36, fill: "#0ff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); viewsTxt.anchor.set(0.5, 0); viewsTxt.x = bg.x; viewsTxt.y = nameTxt.y + nameTxt.height + 6; videoListContainer.addChild(viewsTxt); // Money earned - below views var moneyDisplay = Math.floor(video.totalMoney * 100) / 100; var moneyTxt = new Text2("$" + formatNumber(moneyDisplay) + " earned", { size: 36, fill: 0xFA4B00, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); moneyTxt.anchor.set(0.5, 0); moneyTxt.x = bg.x; moneyTxt.y = viewsTxt.y + viewsTxt.height + 2; videoListContainer.addChild(moneyTxt); // Subscribers - below money var subsTxt = new Text2(formatNumber(video.totalSubs) + " subs", { size: 36, fill: 0xFFE066, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); subsTxt.anchor.set(0.5, 0); subsTxt.x = bg.x; subsTxt.y = moneyTxt.y + moneyTxt.height + 2; videoListContainer.addChild(subsTxt); // Status - below subs var stateStr = ""; if (video.hour === 0 && !video.finished) { stateStr = "Just Published"; } else if (!video.finished) { stateStr = "Gaining Views"; } else { stateStr = "Finished"; } var stateTxt = new Text2(stateStr, { size: 32, fill: "#ff0", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); stateTxt.anchor.set(0.5, 0); stateTxt.x = bg.x; stateTxt.y = subsTxt.y + subsTxt.height + 2; videoListContainer.addChild(stateTxt); // Optionally, trending badge (top of square, above name) if (video.trending) { var trendingTxt = new Text2("Trending", { size: 32, fill: "#ff0", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); trendingTxt.anchor.set(0.5, 1); trendingTxt.x = bg.x; trendingTxt.y = bg.y - squareSize / 2 + 8; videoListContainer.addChild(trendingTxt); } } } // --- Pause/Resume/Double Speed Buttons --- // Track time speed: 0 = paused, 1 = normal, 2 = double var timeSpeed = 1; // Pause button var pauseBtn = new GameButton(); pauseBtn.setButton('pauseicon', '', "#fff", 54, 54); pauseBtn.action = function () { if (timeSpeed !== 0) { timeSpeed = 0; isTimePaused = true; } updateTimeControlButtons(); }; // Resume button var resumeBtn = new GameButton(); resumeBtn.setButton('resumeicon', '', "#fff", 54, 54); resumeBtn.action = function () { if (timeSpeed !== 1) { timeSpeed = 1; isTimePaused = false; } updateTimeControlButtons(); }; // Double speed button var doubleSpeedBtn = new GameButton(); // Double the size: 54*2 = 108 doubleSpeedBtn.setButton('doublespeedicon', '', "#fff", 108, 108); doubleSpeedBtn.action = function () { if (timeSpeed !== 2) { timeSpeed = 2; isTimePaused = false; } updateTimeControlButtons(); }; // Helper to update button enabled/disabled state and highlight function updateTimeControlButtons() { // Highlight the selected speed, dim others pauseBtn.setEnabled(timeSpeed !== 0 ? true : false); resumeBtn.setEnabled(timeSpeed !== 1 ? true : false); doubleSpeedBtn.setEnabled(timeSpeed !== 2 ? true : false); // Optionally, visually highlight the active button pauseBtn.bg.alpha = timeSpeed === 0 ? 1 : 0.6; resumeBtn.bg.alpha = timeSpeed === 1 ? 1 : 0.6; doubleSpeedBtn.bg.alpha = timeSpeed === 2 ? 1 : 0.6; } // Initial highlight updateTimeControlButtons(); // --- Position time text and pause/resume/double speed buttons to the right of the money text --- // This must be done after moneyTxt is created and positioned, so move this block after moneyTxt and icons are created and layoutCountersRow() is called. // --- Counter Row Display (subscribers, viewers, money) --- // Helper to position counters/icons in a row, matching the viewer counter/icon position function layoutCountersRow() { var counterY = 160; var centerX = 2048 / 2; var iconSpacing = 420; // Subscribers (left, further left) subIcon.x = centerX - iconSpacing * 1.7; subIcon.y = counterY; subTxt.x = subIcon.x + 70; subTxt.y = subIcon.y; // Viewers (shifted further left from center) viewIcon.x = centerX - iconSpacing * 0.9; viewIcon.y = counterY; viewTxt.x = viewIcon.x + 70; viewTxt.y = viewIcon.y; // Money (move further left) moneyIcon.x = centerX + iconSpacing * 0.1; moneyIcon.y = counterY; moneyTxt.x = moneyIcon.x + 70; moneyTxt.y = moneyIcon.y; } // Create icons and text objects var subIcon = LK.getAsset('subIcon', { anchorX: 0.5, anchorY: 0.5 }); game.addChild(subIcon); var subTxt = new Text2('0', { size: 64, fill: 0xFFFFFF }); subTxt.anchor.set(0, 0.5); game.addChild(subTxt); var viewIcon = LK.getAsset('viewersicon', { anchorX: 0.5, anchorY: 0.5 }); game.addChild(viewIcon); var viewTxt = new Text2('0', { size: 64, fill: 0x00e0ff }); viewTxt.anchor.set(0, 0.5); game.addChild(viewTxt); var moneyIcon = LK.getAsset('moneyIcon', { anchorX: 0.5, anchorY: 0.5 }); game.addChild(moneyIcon); var moneyTxt = new Text2('0', { size: 64, fill: 0xFFE066 }); moneyTxt.anchor.set(0, 0.5); game.addChild(moneyTxt); // Initial layout layoutCountersRow(); // --- Position time text and pause/resume/double speed buttons to the right of the money text --- var timePauseSpacing = 180; // Further increased spacing to move timeTxt even more right var pauseBtnSpacing = 80; // Further increased spacing to move pauseBtn even more right // Place timeTxt to the right of moneyTxt timeTxt.x = moneyTxt.x + moneyTxt.width + timePauseSpacing; timeTxt.y = moneyTxt.y; // Place pause, resume, and double speed buttons side by side to the right of timeTxt var btnsStartX = timeTxt.x + timeTxt.width + pauseBtnSpacing + pauseBtn.bg.width / 2; var btnsY = timeTxt.y; pauseBtn.x = btnsStartX; pauseBtn.y = btnsY; resumeBtn.x = btnsStartX + pauseBtn.bg.width + 24; resumeBtn.y = btnsY; doubleSpeedBtn.x = btnsStartX + (pauseBtn.bg.width + 24) * 2; doubleSpeedBtn.y = btnsY; // Add to game after positioning game.addChild(timeTxt); game.addChild(pauseBtn); game.addChild(resumeBtn); game.addChild(doubleSpeedBtn); // --- Action Buttons --- // Button layout: stack vertically, bigger, with spacing var btnW = 540; var btnH = 220; var btnSpacingY = 60; var btnStartY = 900; // Make Video Button var makeVideoBtn = new GameButton(); makeVideoBtn.setButton('videoBtn', 'Record Video', "#fff", btnW, btnH); makeVideoBtn.x = 2048 / 2; // Move the record video button further down to fill the space of removed buttons // Move the record video button 250 pixels higher makeVideoBtn.y = btnStartY + 3 * (btnH + btnSpacingY) - 250; // --- Loading Bar for Process --- // (Removed: processBarBg and processBarFill, and their show/hide functions.) // No independent loading bar on the main screen. // --- Action Button Logic (time-based) --- // Track if record video panel is open var isRecordPanelOpen = false; makeVideoBtn.action = function () { if (timeProcess) { return; } // Only one process at a time if (isRecordPanelOpen) { return; } // Prevent multiple panels isRecordPanelOpen = true; // Show a panel before starting the process var panelBg = LK.getAsset('energyBarBg', { anchorX: 0.5, anchorY: 0.5 }); // Expand the panel to allow for more rows of category buttons panelBg.width = 1500; panelBg.height = 1300; panelBg.x = 2048 / 2; panelBg.y = 2732 / 2; panelBg.alpha = 0.98; // --- Panel Title --- var panelText = new Text2("Select Category & Title", { size: 90, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 8, dropShadowDistance: 2 }); panelText.anchor.set(0.5, 0.5); panelText.x = panelBg.x; panelText.y = panelBg.y - panelBg.height / 2 + 120; // near top of panel // --- Video Title Input --- var titleInputBg = LK.getAsset('loadingbarempty', { anchorX: 0.5, anchorY: 0.5 }); titleInputBg.width = 1000; titleInputBg.height = 130; titleInputBg.x = panelBg.x - 180; // shift left to make space for random button titleInputBg.y = panelText.y + 200; // more space below title titleInputBg.alpha = 0.92; var videoTitle = ""; var titleInputTxt = new Text2("Enter video title...", { size: 72, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 8, dropShadowDistance: 2 }); titleInputTxt.anchor.set(0.5, 0.5); titleInputTxt.x = titleInputBg.x; titleInputTxt.y = titleInputBg.y; // Simulate input: tap to edit, prompt for text titleInputBg.down = function (x, y, obj) { var prompt = LK.prompt ? LK.prompt : window.prompt; // fallback for dev var val = prompt ? prompt("Enter video title:", videoTitle) : ""; if (typeof val === "string" && val.length > 0) { videoTitle = val; titleInputTxt.setText(videoTitle); } }; // --- Random Title Button --- var randomBtn = new GameButton(); randomBtn.setButton('promoteBtn', 'Random', "#fff", 340, 120); randomBtn.x = titleInputBg.x + titleInputBg.width / 2 + 200; // right of input with space randomBtn.y = titleInputBg.y; randomBtn.action = function () { // Titles per category var categoryTitles = { "Vlog": ["My Daily Vlog", "Life Update", "A Day in My Life", "Morning Routine", "Evening Recap"], "Challenge": ["Epic Challenge!", "24 Hour Challenge", "Impossible Task!", "Last To Leave", "Extreme Challenge"], "Reaction": ["Reacting to Comments", "Reacting to Viral Videos", "First Time Watching", "Fan Reactions", "Surprising Reactions"], "Tutorial": ["How To Edit Videos", "Beginner's Guide", "Pro Tips & Tricks", "Step by Step Tutorial", "Easy DIY"], "Unboxing": ["Unboxing Surprise", "Mystery Box Unboxing", "Tech Unboxing", "Unboxing Haul", "First Impressions"], "Gaming": ["Let's Play!", "Epic Gaming Moments", "Game Review", "Speedrun Attempt", "Funny Gaming Fails"], "Music": ["My New Song", "Music Cover", "Behind the Music", "Songwriting Session", "Live Performance"], "Comedy": ["Funny Moments", "Comedy Skit", "Prank Video", "Try Not To Laugh", "Bloopers & Outtakes"], "Q&A": ["Q&A Special", "Answering Your Questions", "Ask Me Anything", "Subscriber Q&A", "Get To Know Me"], "Other": ["Behind the Scenes", "Special Announcement", "Random Thoughts", "Channel Update", "What Happened Today"] }; var cat = videoCategories[selectedCategoryIdx]; var titles = categoryTitles[cat] || ["My Daily Vlog", "Epic Challenge!", "Reacting to Comments", "24 Hours in My Studio", "Behind the Scenes", "Q&A Special", "Trying Viral Trends", "Unboxing Surprise", "Life Update", "Funny Moments"]; var idx = Math.floor(Math.random() * titles.length); videoTitle = titles[idx]; titleInputTxt.setText(videoTitle); }; // --- Video Category Buttons --- var categoryBtnW = 340; var categoryBtnH = 120; var categoryBtnSpacingX = 40; var categoryBtnSpacingY = 40; var categoryBtns = []; // Layout: fit as many as possible per row, then wrap var maxRowWidth = panelBg.width - 120; // leave some margin var maxPerRow = Math.floor((maxRowWidth + categoryBtnSpacingX) / (categoryBtnW + categoryBtnSpacingX)); if (maxPerRow < 1) { maxPerRow = 1; } var startX = panelBg.x - (Math.min(maxPerRow, videoCategories.length) * (categoryBtnW + categoryBtnSpacingX) - categoryBtnSpacingX) / 2 + categoryBtnW / 2; var startY = titleInputBg.y + 220; // more space below input+random for (var i = 0; i < videoCategories.length; i++) { (function (idx) { var btn = new GameButton(); btn.setButton('editBtn', videoCategories[idx], "#fff", categoryBtnW, categoryBtnH); var row = Math.floor(idx / maxPerRow); var col = idx % maxPerRow; btn.x = startX + col * (categoryBtnW + categoryBtnSpacingX); btn.y = startY + row * (categoryBtnH + categoryBtnSpacingY); btn.action = function () { // Deselect all for (var j = 0; j < categoryBtns.length; j++) { // If trending, keep its highlight if (j === trendingCategoryIdx) { categoryBtns[j].bg.alpha = 0.95; } else { categoryBtns[j].bg.alpha = 0.7; } } btn.bg.alpha = 1; selectedCategoryIdx = idx; }; // Highlight the first by default if (i === 0) { btn.bg.alpha = 1; } else { btn.bg.alpha = 0.7; } // Mark trending category visually if (i === trendingCategoryIdx) { btn.bg.alpha = 0.95; // Add a "Trending" label above the button var trendingTxt = new Text2("🔥 Trending", { size: 48, fill: "#ff0", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 8, dropShadowDistance: 2 }); trendingTxt.anchor.set(0.5, 1); trendingTxt.x = btn.x; trendingTxt.y = btn.y - categoryBtnH / 2 - 10; btn.trendingTxt = trendingTxt; } categoryBtns.push(btn); })(i); } // --- Confirm/Record Button --- var confirmBtn = new GameButton(); confirmBtn.setButton('videoBtn', 'Start Recording', "#fff", 600, 180); confirmBtn.x = panelBg.x; // Find the bottom Y of the last category button for spacing var lastCategoryBtn = categoryBtns[categoryBtns.length - 1]; var categoryBtnsBottomY = lastCategoryBtn ? lastCategoryBtn.y + categoryBtnH / 2 : startY + categoryBtnH / 2; confirmBtn.y = categoryBtnsBottomY + 200; // more space below category confirmBtn.action = function () { // Remove panel panelBg.destroy(); panelText.destroy(); confirmBtn.destroy(); titleInputBg.destroy(); titleInputTxt.destroy(); randomBtn.destroy(); closeBtn.destroy(); // Also destroy the close (X) button // Destroy all category buttons for (var i = 0; i < categoryBtns.length; i++) { // Destroy trending label if exists if (categoryBtns[i].trendingTxt) { categoryBtns[i].trendingTxt.destroy(); } categoryBtns[i].destroy(); } isRecordPanelOpen = false; // Start the process timeProcess = { type: 'record', hoursLeft: 3, total: 3, category: videoCategories[selectedCategoryIdx], title: videoTitle, onFinish: function onFinish() { LK.getSound('makeVideo').play(); // Create a new video object to accrue views over time if (!window.uploadedVideos) { window.uploadedVideos = []; } var videoObj = { title: videoTitle, category: videoCategories[selectedCategoryIdx], hour: 0, totalHours: 7 * 24, totalViews: 0, totalMoney: 0, totalSubs: 0, trending: videoCategories[selectedCategoryIdx] === videoCategories[trendingCategoryIdx], baseSubscribers: subscribers, finished: false, state: "recorded", // new: states are "recorded", "editing", "readyToPublish", "published" editHoursLeft: 5, // in-game hours to edit publishReady: false }; // Precompute total views to distribute realistically over 7 days // Make hourly views between 1% and 5% of the number of subscribers at publish time var minViewPercent = 0.01; var maxViewPercent = 0.05; var percent = minViewPercent + Math.random() * (maxViewPercent - minViewPercent); var baseViews = Math.floor(videoObj.baseSubscribers * percent); if (videoObj.baseSubscribers < 100) { baseViews = 100 + Math.floor(Math.random() * 400); } if (videoObj.trending) { baseViews = Math.floor(baseViews * 1.5); } videoObj.targetViews = baseViews; videoObj.targetMoney = Math.floor(baseViews / 1000 * (3 + Math.random() * 2)); videoObj.targetSubs = Math.floor(baseViews / (200 + Math.floor(Math.random() * 101))); videoObj.hourlyViews = []; // Distribute views per hour: more at start, less at end (decay curve) var decay = 0.012; // controls how fast views drop off var total = 0; for (var h = 0; h < videoObj.totalHours; h++) { var rel = h / videoObj.totalHours; var hourViews = Math.max(1, Math.round(baseViews * Math.exp(-decay * h))); videoObj.hourlyViews.push(hourViews); total += hourViews; } // Normalize to match targetViews var scale = baseViews / total; for (var h = 0; h < videoObj.hourlyViews.length; h++) { videoObj.hourlyViews[h] = Math.floor(videoObj.hourlyViews[h] * scale); } window.uploadedVideos.push(videoObj); videoCount += 1; updateStats(); updateVideoLists(); // Animate button tween(makeVideoBtn, { scaleX: 1.1, scaleY: 1.1 }, { duration: 80, onFinish: function onFinish() { tween(makeVideoBtn, { scaleX: 1, scaleY: 1 }, { duration: 80 }); } }); // Removed winning condition at 1000 subscribers; game continues forever } }; // Removed call to undefined showProcessBar(0) }; // --- Close (X) Button --- var closeBtn = new Text2("×", { size: 120, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 8, dropShadowDistance: 2 }); closeBtn.anchor.set(0.5, 0.5); // Place at top right of panel, with margin closeBtn.x = panelBg.x + panelBg.width / 2 - 80; closeBtn.y = panelBg.y - panelBg.height / 2 + 80; closeBtn.interactive = true; closeBtn.buttonMode = true; closeBtn.down = function () { panelBg.destroy(); panelText.destroy(); confirmBtn.destroy(); closeBtn.destroy(); titleInputBg.destroy(); titleInputTxt.destroy(); randomBtn.destroy(); // Destroy all category buttons for (var i = 0; i < categoryBtns.length; i++) { // Destroy trending label if exists if (categoryBtns[i].trendingTxt) { categoryBtns[i].trendingTxt.destroy(); } categoryBtns[i].destroy(); } isRecordPanelOpen = false; }; // Add all panel elements to game game.addChild(panelBg); game.addChild(panelText); game.addChild(titleInputBg); game.addChild(titleInputTxt); game.addChild(randomBtn); game.addChild(closeBtn); // Add all category buttons for (var i = 0; i < categoryBtns.length; i++) { game.addChild(categoryBtns[i]); // If trending label exists, add it to game if (categoryBtns[i].trendingTxt) { game.addChild(categoryBtns[i].trendingTxt); } } game.addChild(confirmBtn); }; // Add buttons to game game.addChild(makeVideoBtn); // (Removed: manual y-positioning of subIcon/subTxt and moneyIcon/moneyTxt; handled by layoutCountersRow) // Removed undefined energyBar and energyTxt // --- GUI: Timer/Score (use subscribers as score) --- // Removed giant numbers next to the subscriber counter // --- Helper Functions --- function formatNumber(num) { if (num < 1000) { return "" + num; } if (num < 1000000) { var k = num / 1000; if (k % 1 === 0) { return k + "k"; } return k.toFixed(1).replace(/\.0$/, "") + "k"; } var m = num / 1000000; if (m % 1 === 0) { return m + "m"; } return m.toFixed(1).replace(/\.0$/, "") + "m"; } function updateStats() { // --- Helper for green increase text --- function showGreenIncrease(textObj, increase, prefix) { if (!increase || increase <= 0) { return; } var plusText = new Text2("+" + formatNumber(increase), { size: 48, fill: 0x00FF44, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 8, dropShadowDistance: 2 }); plusText.anchor.set(0, 0.5); // Place to the right of the number plusText.x = textObj.x + textObj.width + 16; plusText.y = textObj.y; game.addChild(plusText); tween(plusText, { y: plusText.y - 40, alpha: 0 }, { duration: 1200, easing: tween.cubicOut, onFinish: function onFinish() { plusText.destroy(); } }); } // Subscribers if (typeof updateStats.lastSubValue !== "number") { updateStats.lastSubValue = subscribers; } var subIncrease = subscribers - updateStats.lastSubValue; subTxt.setText(formatNumber(subscribers)); if (subIncrease > 0) { showGreenIncrease(subTxt, subIncrease, ""); } updateStats.lastSubValue = subscribers; // Views if (typeof updateStats.lastViewValue !== "number") { updateStats.lastViewValue = viewCount; } var viewIncrease = viewCount - updateStats.lastViewValue; viewTxt.setText(formatNumber(viewCount)); if (viewIncrease > 0) { showGreenIncrease(viewTxt, viewIncrease, ""); } updateStats.lastViewValue = viewCount; // Money if (typeof updateStats.lastMoneyValue !== "number") { updateStats.lastMoneyValue = money; } var moneyIncrease = money - updateStats.lastMoneyValue; // Truncate money to 2 decimal digits for display var moneyDisplay = Math.floor(money * 100) / 100; moneyTxt.setText(formatNumber(moneyDisplay)); if (moneyIncrease > 0) { // Truncate moneyIncrease to 2 decimal digits for display var moneyIncreaseDisplay = Math.floor(moneyIncrease * 100) / 100; showGreenIncrease(moneyTxt, moneyIncreaseDisplay, ""); } updateStats.lastMoneyValue = money; // Enable/disable buttons based on process and resources makeVideoBtn.setEnabled(!timeProcess); // --- Achievements --- if (!updateStats.milestones) { updateStats.milestones = {}; } // Subscriber milestones var milestones = [10, 25, 50, 100, 250, 500, 750, 1000, 2500, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000]; for (var i = 0; i < milestones.length; i++) { var m = milestones[i]; if (subscribers >= m && !updateStats.milestones["subs" + m]) { updateStats.milestones["subs" + m] = true; var ach = new Text2("Milestone: " + m + " Subs!", { size: 110, fill: "#ff0", stroke: "#000", strokeThickness: 12, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 12, dropShadowDistance: 4 }); ach.anchor.set(0.5, 0.5); ach.x = 2048 / 2; ach.y = 400 + i * 80; game.addChild(ach); tween(ach, { alpha: 0, y: ach.y - 100 }, { duration: 1800, onFinish: function onFinish() { ach.destroy(); } }); } } // View milestones var viewMilestones = [1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, 5000000, 10000000]; for (var i = 0; i < viewMilestones.length; i++) { var m = viewMilestones[i]; if (viewCount >= m && !updateStats.milestones["views" + m]) { updateStats.milestones["views" + m] = true; var ach = new Text2("Milestone: " + formatNumber(m) + " Views!", { size: 110, fill: 0x00E0FF, stroke: "#000", strokeThickness: 12, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 12, dropShadowDistance: 4 }); ach.anchor.set(0.5, 0.5); ach.x = 2048 / 2; ach.y = 400 + (i + milestones.length) * 80; game.addChild(ach); tween(ach, { alpha: 0, y: ach.y - 100 }, { duration: 1800, onFinish: function onFinish() { ach.destroy(); } }); } } // Money milestones var moneyMilestones = [100, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000]; for (var i = 0; i < moneyMilestones.length; i++) { var m = moneyMilestones[i]; if (money >= m && !updateStats.milestones["money" + m]) { updateStats.milestones["money" + m] = true; var ach = new Text2("Milestone: $" + formatNumber(m) + " Earned!", { size: 110, fill: 0xFA4B00, stroke: "#000", strokeThickness: 12, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma", dropShadow: true, dropShadowColor: "#222", dropShadowBlur: 12, dropShadowDistance: 4 }); ach.anchor.set(0.5, 0.5); ach.x = 2048 / 2; ach.y = 400 + (i + milestones.length + viewMilestones.length) * 80; game.addChild(ach); tween(ach, { alpha: 0, y: ach.y - 100 }, { duration: 1800, onFinish: function onFinish() { ach.destroy(); } }); } } } // --- Video List UI Update --- // --- Time Update --- function updateTimeDisplay() { var h = gameHour; var hStr = (h < 10 ? "0" : "") + h + ":00"; timeTxt.setText("Day " + gameDay + ", " + hStr); } // --- Process Update --- function updateProcessBar() { // No independent loading bar on the main screen. } // --- Time Timer --- if (timeTimer) { LK.clearInterval(timeTimer); } // Helper function to process one hour of time advancement function processOneHour() { // Advance time gameHour += 1; if (gameHour >= 24) { gameHour = 0; gameDay += 1; // Check if it's time to change trending category // Trending category changes a random number of times every 7 to 30 days if (typeof trendingCategoryNextChangeDay === "undefined") { trendingCategoryNextChangeDay = trendingCategoryDay + 7 + Math.floor(Math.random() * 24); // 7-30 days } if (gameDay >= trendingCategoryNextChangeDay) { updateTrendingCategory(); trendingCategoryNextChangeDay = gameDay + 7 + Math.floor(Math.random() * 24); // 7-30 days } } updateTimeDisplay(); // Process logic if (timeProcess) { timeProcess.hoursLeft -= 1; updateProcessBar(); if (timeProcess.hoursLeft <= 0) { var finish = timeProcess.onFinish; // If editing, update video state if (timeProcess.type === "edit" && timeProcess.video) { timeProcess.video.state = "readyToPublish"; timeProcess.video.publishReady = true; } timeProcess = null; updateProcessBar(); updateStats(); updateVideoLists(); if (typeof finish === "function") { finish(); } } } // Per-hour video view/money/subscriber accrual if (window.uploadedVideos) { for (var v = 0; v < window.uploadedVideos.length; v++) { var vid = window.uploadedVideos[v]; // Only accrue views, money, and subs if published and not finished if (vid.state === "published" && vid.hour < vid.totalHours) { var viewsThisHour = vid.hourlyViews[vid.hour] || 0; // --- NEW: Instantly update subscribers and money per view --- // 1) For every 1 view, 0.1% chance to gain a subscriber (instantly) // 2) For every 100 views, earn 0.1 money (instantly) var subsThisHour = 0; var moneyThisHour = 0; for (var i = 0; i < viewsThisHour; i++) { if (Math.random() < 0.001) { // 0.1% chance per view subsThisHour += 1; } } moneyThisHour = viewsThisHour / 100 * 0.1; // 0.1 per 100 views, not rounded vid.totalViews += viewsThisHour; vid.totalMoney += moneyThisHour; vid.totalSubs += subsThisHour; viewCount += viewsThisHour; money += moneyThisHour; subscribers += subsThisHour; vid.hour++; // Clamp to target on last hour if (vid.hour === vid.totalHours) { var leftViews = vid.targetViews - vid.totalViews; var leftMoney = vid.targetMoney - vid.totalMoney; var leftSubs = vid.targetSubs - vid.totalSubs; if (leftViews > 0) { viewCount += leftViews; vid.totalViews += leftViews; } if (leftMoney > 0) { money += leftMoney; vid.totalMoney += leftMoney; } if (leftSubs > 0) { subscribers += leftSubs; vid.totalSubs += leftSubs; } vid.finished = true; } } } } updateStats(); updateVideoLists(); } // Timer logic for normal and double speed var doubleSpeedTimer = null; function setTimeTimer() { if (timeTimer) { LK.clearInterval(timeTimer); timeTimer = null; } if (doubleSpeedTimer) { LK.clearInterval(doubleSpeedTimer); doubleSpeedTimer = null; } // Normal speed: 1 hour every 1000ms if (timeSpeed === 1) { timeTimer = LK.setInterval(function () { if (timeSpeed !== 1 || isTimePaused) return; processOneHour(); }, 1000); } // Double speed: 1 hour every 500ms else if (timeSpeed === 2) { doubleSpeedTimer = LK.setInterval(function () { if (timeSpeed !== 2 || isTimePaused) return; processOneHour(); }, 500); } // Paused: do nothing } setTimeTimer(); // Patch time control buttons to call setTimeTimer when speed changes var oldUpdateTimeControlButtons = updateTimeControlButtons; updateTimeControlButtons = function updateTimeControlButtons() { oldUpdateTimeControlButtons(); setTimeTimer(); }; // --- Game Update Loop --- game.update = function () { // Nothing needed for now, all logic is event/click based }; // --- Touch/Drag Handling (no drag needed, but block top left 100x100) --- game.down = function (x, y, obj) { // Prevent accidental clicks in top left if (x < 100 && y < 100) { return; } }; game.move = function (x, y, obj) {}; game.up = function (x, y, obj) {}; // --- Initialize UI --- updateStats(); // --- Bottom Navigation Bar --- var navBarHeight = 220; var navBarY = 2732 - navBarHeight / 2; // Background bar var navBarBg = LK.getAsset('loadingbarempty', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: navBarY }); navBarBg.width = 2048; navBarBg.height = navBarHeight; navBarBg.alpha = 0.96; game.addChild(navBarBg); // Section button width and spacing var navBtnW = 540; var navBtnH = 160; var navBtnSpacing = (2048 - 3 * navBtnW) / 4; var navBtnY = navBarY; // Video Recording Section Button var navVideoBtn = new GameButton(); navVideoBtn.setButton('videoBtn', 'Video', "#fff", navBtnW, navBtnH); navVideoBtn.x = navBtnSpacing + navBtnW / 2; navVideoBtn.y = navBtnY; navVideoBtn.action = function () { // Scroll to or focus video section (no-op for now) }; game.addChild(navVideoBtn); // Skill Tree Section Button var navSkillBtn = new GameButton(); navSkillBtn.setButton('upgradeBtn', 'Skill Tree', "#fff", navBtnW, navBtnH); navSkillBtn.x = navVideoBtn.x + navBtnW / 2 + navBtnSpacing + navBtnW / 2; navSkillBtn.y = navBtnY; navSkillBtn.action = function () { // Open skill tree (to be implemented) }; game.addChild(navSkillBtn); // --- Statistics Section UI --- // Data arrays for stats (one entry per day) var statsViewsPerDay = []; var statsSubsPerDay = []; var statsMoneyPerDay = []; var statsLastDay = 0; // Statistics overlay container (hidden by default) var statsOverlay = new Container(); statsOverlay.visible = false; statsOverlay.x = 0; statsOverlay.y = 0; game.addChild(statsOverlay); // Overlay background var statsBg = LK.getAsset('studioBg', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); statsBg.alpha = 0.98; statsOverlay.addChild(statsBg); // Title var statsTitle = new Text2("Statistics", { size: 120, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); statsTitle.anchor.set(0.5, 0); statsTitle.x = 2048 / 2; statsTitle.y = 120; statsOverlay.addChild(statsTitle); // Graph area positions var graphStartY = 320; var graphSpacingY = 520; var graphW = 1600; var graphH = 320; var graphStartX = (2048 - graphW) / 2; // Helper to draw a clear, separate line graph for a stat (money, views, or subscribers) function drawStatLineGraph(container, data, color, iconAssetId, label, yOffset) { // Remove previous graph if (container.graphNodes) { for (var i = 0; i < container.graphNodes.length; i++) { container.graphNodes[i].destroy(); } } container.graphNodes = []; // Draw icon var icon = LK.getAsset(iconAssetId, { anchorX: 0.5, anchorY: 0.5, x: graphStartX - 80, y: yOffset + graphH / 2 }); container.addChild(icon); container.graphNodes.push(icon); // Draw label var labelTxt = new Text2(label, { size: 60, fill: "#fff", font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); labelTxt.anchor.set(0, 0.5); labelTxt.x = graphStartX; labelTxt.y = yOffset - 40; container.addChild(labelTxt); container.graphNodes.push(labelTxt); // Find max value for scaling var maxVal = 1; for (var i = 0; i < data.length; i++) { if (data[i] > maxVal) { maxVal = data[i]; } } // Draw line graph: connect points with rectangles (simulate lines) var n = Math.max(1, data.length - 1); var prevX = null, prevY = null; for (var i = 0; i < data.length; i++) { var x0 = graphStartX + i / Math.max(1, data.length - 1) * graphW; var y0 = yOffset + graphH - data[i] / maxVal * (graphH - 20); // Draw a small circle at each data point var point = LK.getAsset('loadingbarfull', { anchorX: 0.5, anchorY: 0.5, x: x0, y: y0 }); point.width = 18; point.height = 18; point.tint = color; container.addChild(point); container.graphNodes.push(point); // Draw value label every 5 days or last if ((i % 5 === 0 || i === data.length - 1) && data[i] > 0) { var valTxt = new Text2("" + data[i], { size: 36, fill: "#fff" }); valTxt.anchor.set(0.5, 1); valTxt.x = x0; valTxt.y = y0 - 8; container.addChild(valTxt); container.graphNodes.push(valTxt); } // Draw a "line" between previous and current point using a thin rectangle if (prevX !== null && prevY !== null) { var dx = x0 - prevX; var dy = y0 - prevY; var dist = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); var line = LK.getAsset('loadingbarfull', { anchorX: 0, anchorY: 0.5, x: prevX, y: prevY }); line.width = dist; line.height = 8; line.tint = color; line.rotation = angle; container.addChild(line); container.graphNodes.push(line); } prevX = x0; prevY = y0; } } // Draw all three graphs, each as a clear, separate line graph, one below the other function updateStatsGraphs() { // Remove all previous graph nodes before drawing new ones if (statsOverlay.graphNodes) { for (var i = 0; i < statsOverlay.graphNodes.length; i++) { statsOverlay.graphNodes[i].destroy(); } } statsOverlay.graphNodes = []; // Divide the statistics screen into 3 different areas // Money graph (top section) drawStatLineGraph(statsOverlay, statsMoneyPerDay, 0xfa4b00, 'moneyIcon', "Money Earned per Day", graphStartY); // Viewership graph (middle section) drawStatLineGraph(statsOverlay, statsViewsPerDay, 0x00e0ff, 'viewersicon', "Views per Day", graphStartY + graphH + 60); // Subscriber graph (bottom section) drawStatLineGraph(statsOverlay, statsSubsPerDay, 0xffe066, 'subIcon', "Subscribers per Day", graphStartY + 2 * (graphH + 60)); } // Close button for stats overlay var statsCloseBtn = new GameButton(); statsCloseBtn.setButton('editBtn', 'Close', "#fff", 400, 120); statsCloseBtn.x = 2048 / 2; statsCloseBtn.y = 2732 - navBarHeight - 100; statsCloseBtn.action = function () { statsOverlay.visible = false; }; statsOverlay.addChild(statsCloseBtn); // Statistics Section Button var navStatsBtn = new GameButton(); navStatsBtn.setButton('editBtn', 'Statistics', "#fff", navBtnW, navBtnH); navStatsBtn.x = navSkillBtn.x + navBtnW / 2 + navBtnSpacing + navBtnW / 2; navStatsBtn.y = navBtnY; navStatsBtn.action = function () { updateStatsGraphs(); statsOverlay.visible = true; }; game.addChild(navStatsBtn); // --- Track stats per day --- // Call this at the end of each day function recordDailyStats() { // Only record once per day if (statsLastDay === gameDay) { return; } statsLastDay = gameDay; statsViewsPerDay.push(viewCount); statsSubsPerDay.push(subscribers); statsMoneyPerDay.push(money); } // Patch into time timer: after day advances, record stats var oldTimeTimer = timeTimer; if (timeTimer) { LK.clearInterval(timeTimer); } timeTimer = LK.setInterval(function () { if (timeSpeed === 0 || isTimePaused) { return; } // How many ticks to process this frame var ticks = timeSpeed === 2 ? 2 : 1; for (var tick = 0; tick < ticks; tick++) { gameHour += 1; if (gameHour >= 24) { gameHour = 0; gameDay += 1; recordDailyStats(); // Trending category logic... if (typeof trendingCategoryNextChangeDay === "undefined") { trendingCategoryNextChangeDay = trendingCategoryDay + 7 + Math.floor(Math.random() * 24); } if (gameDay >= trendingCategoryNextChangeDay) { updateTrendingCategory(); trendingCategoryNextChangeDay = gameDay + 7 + Math.floor(Math.random() * 24); } } updateTimeDisplay(); if (timeProcess) { timeProcess.hoursLeft -= 1; updateProcessBar(); if (timeProcess.hoursLeft <= 0) { var finish = timeProcess.onFinish; if (timeProcess.type === "edit" && timeProcess.video) { timeProcess.video.state = "readyToPublish"; timeProcess.video.publishReady = true; } timeProcess = null; updateProcessBar(); updateStats(); updateVideoLists(); if (typeof finish === "function") { finish(); } } } if (window.uploadedVideos) { for (var v = 0; v < window.uploadedVideos.length; v++) { var vid = window.uploadedVideos[v]; if (vid.state === "published" && vid.hour < vid.totalHours) { var viewsThisHour = vid.hourlyViews[vid.hour] || 0; // --- NEW: Instantly update subscribers and money per view --- // 1) For every 1 view, 0.1% chance to gain a subscriber (instantly) // 2) For every 100 views, earn 0.1 money (instantly) var subsThisHour = 0; var moneyThisHour = 0; for (var i = 0; i < viewsThisHour; i++) { if (Math.random() < 0.001) { // 0.1% chance per view subsThisHour += 1; } } moneyThisHour = viewsThisHour / 100 * 0.1; // 0.1 per 100 views, not rounded vid.totalViews += viewsThisHour; vid.totalMoney += moneyThisHour; vid.totalSubs += subsThisHour; viewCount += viewsThisHour; money += moneyThisHour; subscribers += subsThisHour; vid.hour++; if (vid.hour === vid.totalHours) { var leftViews = vid.targetViews - vid.totalViews; var leftMoney = vid.targetMoney - vid.totalMoney; var leftSubs = vid.targetSubs - vid.totalSubs; if (leftViews > 0) { viewCount += leftViews; vid.totalViews += leftViews; } if (leftMoney > 0) { money += leftMoney; vid.totalMoney += leftMoney; } if (leftSubs > 0) { subscribers += leftSubs; vid.totalSubs += leftSubs; } vid.finished = true; } } } } } updateStats(); updateVideoLists(); }, 1000); // Record stats for day 1 at game start recordDailyStats();
===================================================================
--- original.js
+++ change.js
@@ -265,9 +265,9 @@
// Will be positioned after moneyTxt is created and positioned
// --- Video List UI ---
// Video list container (horizontal, each video on a square background, text below, side by side)
var videoListContainer = new Container();
-videoListContainer.x = 120; // leave margin from left (avoid top left 100x100)
+videoListContainer.x = 110; // leave margin from left (avoid top left 100x100), moved 10px further left
videoListContainer.y = 450; // below counters row
game.addChild(videoListContainer);
// Helper to update the video list display
function updateVideoLists() {
subscriber icon 2d. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
money icon 2d. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
solid grey colour background for panel. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
viewers icon for a mobile game. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make bigger this monitor
please to this white color
white play button solid white color. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
double speed icon for mobile games. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat. no text. only white color.
2d phone for mobile games. modern phone. looks good but phone is one color, phone's screen one color. Let it be completely 2-dimensional and not look like 3-dimensional. There should be a mute button and small volume up and down and hang up buttons on the sides of the phone.. In-Game asset. 2d. High contrast. No shadows - Fill the entire screen with a light gray color. - The outer cover color of the phone should be dark gray.
youtube button logo. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
white background rounded corners. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat white color. all white color no border.
playstore logo. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
editing application logo. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
çöp kutusu logosu fakat kırmızı arka planlı (çöp kutusu logosu beyaz renkte olacak). In-Game asset. 2d. High contrast. No shadows
kırmızıya boya
beyaza boya
maviye boya
istatistik logosu. In-Game asset. 2d. High contrast. No shadows
reklam logosu herhangi bir yazı olmasın. In-Game asset. 2d. High contrast. No shadows
record video logo with not text. In-Game asset. 2d. High contrast. No shadows
finans logosu. In-Game asset. 2d. High contrast. No shadows
youtube studio logo with no text only logo. In-Game asset. 2d. High contrast. No shadows
create youtube channel avatar cartoon 2d. In-Game asset. 2d. High contrast. No shadows
youtube channel logo. In-Game asset. 2d. High contrast. No shadows
"rastgele" ikonu, beyaz renginde olacak.. In-Game asset. 2d. High contrast. No shadows
youtube thumbnail for vlog. 2d. High contrast. No shadows
kilit ikonu beyaz. In-Game asset. 2d. High contrast. No shadows