diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx
index d97d55ee1..5b5112516 100644
--- a/src/Bladeburner/Bladeburner.tsx
+++ b/src/Bladeburner/Bladeburner.tsx
@@ -2026,7 +2026,7 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.startAction", errorLogText);
+      workerScript.log("bladeburner.startAction", () => errorLogText);
       return false;
     }
 
@@ -2038,13 +2038,13 @@ export class Bladeburner implements IBladeburner {
       if (!(action instanceof BlackOperation)) throw new Error(`Action should be BlackOperation but isn't`);
       //const blackOp = (action as BlackOperation);
       if (action.reqdRank > this.rank) {
-        workerScript.log("bladeburner.startAction", `Insufficient rank to start Black Op '${actionId.name}'.`);
+        workerScript.log("bladeburner.startAction", () => `Insufficient rank to start Black Op '${actionId.name}'.`);
         return false;
       }
 
       // Can't start a BlackOp if its already been done
       if (this.blackops[actionId.name] != null) {
-        workerScript.log("bladeburner.startAction", `Black Op ${actionId.name} has already been completed.`);
+        workerScript.log("bladeburner.startAction", () => `Black Op ${actionId.name} has already been completed.`);
         return false;
       }
 
@@ -2061,14 +2061,14 @@ export class Bladeburner implements IBladeburner {
 
       const i = blackops.indexOf(actionId.name);
       if (i === -1) {
-        workerScript.log("bladeburner.startAction", `Invalid Black Op: '${name}'`);
+        workerScript.log("bladeburner.startAction", () => `Invalid Black Op: '${name}'`);
         return false;
       }
 
       if (i > 0 && this.blackops[blackops[i - 1]] == null) {
         workerScript.log(
           "bladeburner.startAction",
-          `Preceding Black Op must be completed before starting '${actionId.name}'.`,
+          () => `Preceding Black Op must be completed before starting '${actionId.name}'.`,
         );
         return false;
       }
@@ -2076,11 +2076,14 @@ export class Bladeburner implements IBladeburner {
 
     try {
       this.startAction(player, actionId);
-      workerScript.log("bladeburner.startAction", `Starting bladeburner action with type '${type}' and name ${name}"`);
+      workerScript.log(
+        "bladeburner.startAction",
+        () => `Starting bladeburner action with type '${type}' and name ${name}"`,
+      );
       return true;
     } catch (e: any) {
       this.resetAction();
-      workerScript.log("bladeburner.startAction", errorLogText);
+      workerScript.log("bladeburner.startAction", () => errorLogText);
       return false;
     }
   }
@@ -2089,13 +2092,13 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.getActionTime", errorLogText);
+      workerScript.log("bladeburner.getActionTime", () => errorLogText);
       return -1;
     }
 
     const actionObj = this.getActionObject(actionId);
     if (actionObj == null) {
-      workerScript.log("bladeburner.getActionTime", errorLogText);
+      workerScript.log("bladeburner.getActionTime", () => errorLogText);
       return -1;
     }
 
@@ -2116,7 +2119,7 @@ export class Bladeburner implements IBladeburner {
       case ActionTypes["Incite Violence"]:
         return 60000;
       default:
-        workerScript.log("bladeburner.getActionTime", errorLogText);
+        workerScript.log("bladeburner.getActionTime", () => errorLogText);
         return -1;
     }
   }
@@ -2130,13 +2133,13 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText);
+      workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
       return [-1, -1];
     }
 
     const actionObj = this.getActionObject(actionId);
     if (actionObj == null) {
-      workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText);
+      workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
       return [-1, -1];
     }
 
@@ -2158,7 +2161,7 @@ export class Bladeburner implements IBladeburner {
         return [recChance, recChance];
       }
       default:
-        workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText);
+        workerScript.log("bladeburner.getActionEstimatedSuccessChance", () => errorLogText);
         return [-1, -1];
     }
   }
@@ -2167,13 +2170,13 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.getActionCountRemaining", errorLogText);
+      workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
       return -1;
     }
 
     const actionObj = this.getActionObject(actionId);
     if (actionObj == null) {
-      workerScript.log("bladeburner.getActionCountRemaining", errorLogText);
+      workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
       return -1;
     }
 
@@ -2197,14 +2200,14 @@ export class Bladeburner implements IBladeburner {
       case ActionTypes["Incite Violence"]:
         return Infinity;
       default:
-        workerScript.log("bladeburner.getActionCountRemaining", errorLogText);
+        workerScript.log("bladeburner.getActionCountRemaining", () => errorLogText);
         return -1;
     }
   }
 
   getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number {
     if (skillName === "" || !Skills.hasOwnProperty(skillName)) {
-      workerScript.log("bladeburner.getSkillLevel", `Invalid skill: '${skillName}'`);
+      workerScript.log("bladeburner.getSkillLevel", () => `Invalid skill: '${skillName}'`);
       return -1;
     }
 
@@ -2217,7 +2220,7 @@ export class Bladeburner implements IBladeburner {
 
   getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number {
     if (skillName === "" || !Skills.hasOwnProperty(skillName)) {
-      workerScript.log("bladeburner.getSkillUpgradeCost", `Invalid skill: '${skillName}'`);
+      workerScript.log("bladeburner.getSkillUpgradeCost", () => `Invalid skill: '${skillName}'`);
       return -1;
     }
 
@@ -2232,7 +2235,7 @@ export class Bladeburner implements IBladeburner {
   upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean {
     const errorLogText = `Invalid skill: '${skillName}'`;
     if (!Skills.hasOwnProperty(skillName)) {
-      workerScript.log("bladeburner.upgradeSkill", errorLogText);
+      workerScript.log("bladeburner.upgradeSkill", () => errorLogText);
       return false;
     }
 
@@ -2244,21 +2247,22 @@ export class Bladeburner implements IBladeburner {
     const cost = skill.calculateCost(currentLevel);
 
     if (skill.maxLvl && currentLevel >= skill.maxLvl) {
-      workerScript.log("bladeburner.upgradeSkill", `Skill '${skillName}' is already maxed.`);
+      workerScript.log("bladeburner.upgradeSkill", () => `Skill '${skillName}' is already maxed.`);
       return false;
     }
 
     if (this.skillPoints < cost) {
       workerScript.log(
         "bladeburner.upgradeSkill",
-        `You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`,
+        () =>
+          `You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`,
       );
       return false;
     }
 
     this.skillPoints -= cost;
     this.upgradeSkill(skill);
-    workerScript.log("bladeburner.upgradeSkill", `'${skillName}' upgraded to level ${this.skills[skillName]}`);
+    workerScript.log("bladeburner.upgradeSkill", () => `'${skillName}' upgraded to level ${this.skills[skillName]}`);
     return true;
   }
 
@@ -2270,13 +2274,13 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.getTeamSize", errorLogText);
+      workerScript.log("bladeburner.getTeamSize", () => errorLogText);
       return -1;
     }
 
     const actionObj = this.getActionObject(actionId);
     if (actionObj == null) {
-      workerScript.log("bladeburner.getTeamSize", errorLogText);
+      workerScript.log("bladeburner.getTeamSize", () => errorLogText);
       return -1;
     }
 
@@ -2295,7 +2299,7 @@ export class Bladeburner implements IBladeburner {
     const errorLogText = `Invalid action: type='${type}' name='${name}'`;
     const actionId = this.getActionIdFromTypeAndName(type, name);
     if (actionId == null) {
-      workerScript.log("bladeburner.setTeamSize", errorLogText);
+      workerScript.log("bladeburner.setTeamSize", () => errorLogText);
       return -1;
     }
 
@@ -2304,26 +2308,26 @@ export class Bladeburner implements IBladeburner {
       actionId.type !== ActionTypes["BlackOp"] &&
       actionId.type !== ActionTypes["BlackOperation"]
     ) {
-      workerScript.log("bladeburner.setTeamSize", "Only valid for 'Operations' and 'BlackOps'");
+      workerScript.log("bladeburner.setTeamSize", () => "Only valid for 'Operations' and 'BlackOps'");
       return -1;
     }
 
     const actionObj = this.getActionObject(actionId);
     if (actionObj == null) {
-      workerScript.log("bladeburner.setTeamSize", errorLogText);
+      workerScript.log("bladeburner.setTeamSize", () => errorLogText);
       return -1;
     }
 
     let sanitizedSize = Math.round(size);
     if (isNaN(sanitizedSize) || sanitizedSize < 0) {
-      workerScript.log("bladeburner.setTeamSize", `Invalid size: ${size}`);
+      workerScript.log("bladeburner.setTeamSize", () => `Invalid size: ${size}`);
       return -1;
     }
     if (this.teamSize < sanitizedSize) {
       sanitizedSize = this.teamSize;
     }
     actionObj.teamCount = sanitizedSize;
-    workerScript.log("bladeburner.setTeamSize", `Team size for '${name}' set to ${sanitizedSize}.`);
+    workerScript.log("bladeburner.setTeamSize", () => `Team size for '${name}' set to ${sanitizedSize}.`);
     return sanitizedSize;
   }
 
@@ -2333,12 +2337,12 @@ export class Bladeburner implements IBladeburner {
       return true;
     } else if (this.rank >= BladeburnerConstants.RankNeededForFaction) {
       joinFaction(bladeburnerFac);
-      workerScript.log("bladeburner.joinBladeburnerFaction", "Joined Bladeburners faction.");
+      workerScript.log("bladeburner.joinBladeburnerFaction", () => "Joined Bladeburners faction.");
       return true;
     } else {
       workerScript.log(
         "bladeburner.joinBladeburnerFaction",
-        `You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`,
+        () => `You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`,
       );
       return false;
     }
diff --git a/src/Gang/Gang.ts b/src/Gang/Gang.ts
index 17128b91b..b9f9f46b8 100644
--- a/src/Gang/Gang.ts
+++ b/src/Gang/Gang.ts
@@ -349,7 +349,7 @@ export class Gang {
       const res = member.ascend();
       this.respect = Math.max(1, this.respect - res.respect);
       if (workerScript) {
-        workerScript.log("ascend", `Ascended Gang member ${member.name}`);
+        workerScript.log("ascend", () => `Ascended Gang member ${member.name}`);
       }
       return res;
     } catch (e: any) {
diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts
index 084024e1a..304cd00bd 100644
--- a/src/Netscript/WorkerScript.ts
+++ b/src/Netscript/WorkerScript.ts
@@ -195,14 +195,14 @@ export class WorkerScript {
     return this.disableLogs[fn] == null;
   }
 
-  log(func: string, txt: string): void {
+  log(func: string, txt: () => string): void {
     if (this.shouldLog(func)) {
       if (func && txt) {
-        this.scriptRef.log(`${func}: ${txt}`);
+        this.scriptRef.log(`${func}: ${txt()}`);
       } else if (func) {
         this.scriptRef.log(func);
       } else {
-        this.scriptRef.log(txt);
+        this.scriptRef.log(txt());
       }
     }
   }
diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts
index 89c8c0fda..6585b43f5 100644
--- a/src/NetscriptFunctions.ts
+++ b/src/NetscriptFunctions.ts
@@ -213,7 +213,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
    */
   const failOnHacknetServer = function (server: any, callingFn: any = ""): boolean {
     if (server instanceof HacknetServer) {
-      workerScript.log(callingFn, `Does not work on Hacknet Servers`);
+      workerScript.log(callingFn, () => `Does not work on Hacknet Servers`);
       return true;
     } else {
       return false;
@@ -282,7 +282,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       userstack.push(`${filename}:L${call.line}@${call.func}`);
     }
 
-    workerScript.log(caller, msg);
+    workerScript.log(caller, () => msg);
     let rejectMsg = `${caller}: ${msg}`;
     if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`;
     return makeRuntimeRejectMsg(workerScript, rejectMsg);
@@ -317,10 +317,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
     workerScript.log(
       "hack",
-      `Executing ${hostname} in ${convertTimeMsToTimeElapsedString(
-        hackingTime * 1000,
-        true,
-      )} (t=${numeralWrapper.formatThreads(threads)})`,
+      () =>
+        `Executing ${hostname} in ${convertTimeMsToTimeElapsedString(
+          hackingTime * 1000,
+          true,
+        )} (t=${numeralWrapper.formatThreads(threads)})`,
     );
 
     return netscriptDelay(hackingTime * 1000, workerScript).then(function () {
@@ -366,9 +367,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
         workerScript.log(
           "hack",
-          `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(
-            moneyGained,
-          )} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`,
+          () =>
+            `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(
+              moneyGained,
+            )} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`,
         );
         server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
         if (stock) {
@@ -384,9 +386,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
         workerScript.log(
           "hack",
-          `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(
-            expGainedOnFailure,
-          )} exp (t=${numeralWrapper.formatThreads(threads)})`,
+          () =>
+            `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(
+              expGainedOnFailure,
+            )} exp (t=${numeralWrapper.formatThreads(threads)})`,
         );
         return Promise.resolve(0);
       }
@@ -460,7 +463,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         if (entry === null) continue;
         out.push(entry);
       }
-      workerScript.log("scan", `returned ${server.serversOnNetwork.length} connections for ${server.hostname}`);
+      workerScript.log("scan", () => `returned ${server.serversOnNetwork.length} connections for ${server.hostname}`);
       return out;
     },
     hack: function (hostname: any, { threads: requestedThreads, stock }: any = {}): any {
@@ -473,7 +476,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       // Check argument validity
       const server = safeGetServer(hostname, "hackAnalyzeThreads");
       if (!(server instanceof Server)) {
-        workerScript.log("hackAnalyzeThreads", "Cannot be executed on this server.");
+        workerScript.log("hackAnalyzeThreads", () => "Cannot be executed on this server.");
         return -1;
       }
       if (isNaN(hackAmount)) {
@@ -496,7 +499,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       const server = safeGetServer(hostname, "hackAnalyze");
       if (!(server instanceof Server)) {
-        workerScript.log("hackAnalyze", "Cannot be executed on this server.");
+        workerScript.log("hackAnalyze", () => "Cannot be executed on this server.");
         return false;
       }
 
@@ -510,7 +513,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       const server = safeGetServer(hostname, "hackAnalyzeChance");
       if (!(server instanceof Server)) {
-        workerScript.log("hackAnalyzeChance", "Cannot be executed on this server.");
+        workerScript.log("hackAnalyzeChance", () => "Cannot be executed on this server.");
         return false;
       }
 
@@ -520,7 +523,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       if (time === undefined) {
         throw makeRuntimeErrorMsg("sleep", "Takes 1 argument.");
       }
-      workerScript.log("sleep", `Sleeping for ${time} milliseconds`);
+      workerScript.log("sleep", () => `Sleeping for ${time} milliseconds`);
       return netscriptDelay(time, workerScript).then(function () {
         return Promise.resolve(true);
       });
@@ -529,7 +532,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       if (time === undefined) {
         throw makeRuntimeErrorMsg("asleep", "Takes 1 argument.");
       }
-      workerScript.log("asleep", `Sleeping for ${time} milliseconds`);
+      workerScript.log("asleep", () => `Sleeping for ${time} milliseconds`);
       return netscriptDelay(time, workerScript).then(function () {
         return Promise.resolve(true);
       });
@@ -542,7 +545,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "grow");
       if (!(server instanceof Server)) {
-        workerScript.log("grow", "Cannot be executed on this server.");
+        workerScript.log("grow", () => "Cannot be executed on this server.");
         return false;
       }
 
@@ -560,10 +563,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       const growTime = calculateGrowTime(server, Player);
       workerScript.log(
         "grow",
-        `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
-          growTime * 1000,
-          true,
-        )} (t=${numeralWrapper.formatThreads(threads)}).`,
+        () =>
+          `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
+            growTime * 1000,
+            true,
+          )} (t=${numeralWrapper.formatThreads(threads)}).`,
       );
       return netscriptDelay(growTime * 1000, workerScript).then(function () {
         if (workerScript.env.stopFlag) {
@@ -577,10 +581,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         const logGrowPercent = moneyAfter / moneyBefore - 1;
         workerScript.log(
           "grow",
-          `Available money on '${server.hostname}' grown by ${numeralWrapper.formatPercentage(
-            logGrowPercent,
-            6,
-          )}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)}).`,
+          () =>
+            `Available money on '${server.hostname}' grown by ${numeralWrapper.formatPercentage(
+              logGrowPercent,
+              6,
+            )}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)}).`,
         );
         workerScript.scriptRef.onlineExpGained += expGain;
         Player.gainHackingExp(expGain);
@@ -596,7 +601,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       // Check argument validity
       const server = safeGetServer(hostname, "growthAnalyze");
       if (!(server instanceof Server)) {
-        workerScript.log("growthAnalyze", "Cannot be executed on this server.");
+        workerScript.log("growthAnalyze", () => "Cannot be executed on this server.");
         return false;
       }
       if (typeof growth !== "number" || isNaN(growth) || growth < 1 || !isFinite(growth)) {
@@ -616,7 +621,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "weaken");
       if (!(server instanceof Server)) {
-        workerScript.log("weaken", "Cannot be executed on this server.");
+        workerScript.log("weaken", () => "Cannot be executed on this server.");
         return false;
       }
 
@@ -629,16 +634,17 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       const weakenTime = calculateWeakenTime(server, Player);
       workerScript.log(
         "weaken",
-        `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
-          weakenTime * 1000,
-          true,
-        )} (t=${numeralWrapper.formatThreads(threads)})`,
+        () =>
+          `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
+            weakenTime * 1000,
+            true,
+          )} (t=${numeralWrapper.formatThreads(threads)})`,
       );
       return netscriptDelay(weakenTime * 1000, workerScript).then(function () {
         if (workerScript.env.stopFlag) return Promise.reject(workerScript);
         const host = GetServer(workerScript.hostname);
         if (host === null) {
-          workerScript.log("weaken", "Server is null, did it die?");
+          workerScript.log("weaken", () => "Server is null, did it die?");
           return Promise.resolve(0);
         }
         const coreBonus = 1 + (host.cpuCores - 1) / 16;
@@ -647,9 +653,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         const expGain = calculateHackingExpGain(server, Player) * threads;
         workerScript.log(
           "weaken",
-          `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(
-            expGain,
-          )} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
+          () =>
+            `'${server.hostname}' security level weakened to ${
+              server.hackDifficulty
+            }. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
         );
         workerScript.scriptRef.onlineExpGained += expGain;
         Player.gainHackingExp(expGain);
@@ -721,12 +728,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         for (fn in possibleLogs) {
           workerScript.disableLogs[fn] = true;
         }
-        workerScript.log("disableLog", `Disabled logging for all functions`);
+        workerScript.log("disableLog", () => `Disabled logging for all functions`);
       } else if (possibleLogs[fn] === undefined) {
         throw makeRuntimeErrorMsg("disableLog", `Invalid argument: ${fn}.`);
       } else {
         workerScript.disableLogs[fn] = true;
-        workerScript.log("disableLog", `Disabled logging for ${fn}`);
+        workerScript.log("disableLog", () => `Disabled logging for ${fn}`);
       }
     },
     enableLog: function (fn: any): any {
@@ -734,7 +741,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         throw makeRuntimeErrorMsg("enableLog", `Invalid argument: ${fn}.`);
       }
       delete workerScript.disableLogs[fn];
-      workerScript.log("enableLog", `Enabled logging for ${fn}`);
+      workerScript.log("enableLog", () => `Enabled logging for ${fn}`);
     },
     isLogEnabled: function (fn: any): any {
       if (possibleLogs[fn] === undefined) {
@@ -745,7 +752,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
     getScriptLogs: function (fn: any, hostname: any, ...scriptArgs: any): any {
       const runningScriptObj = getRunningScript(fn, hostname, "getScriptLogs", scriptArgs);
       if (runningScriptObj == null) {
-        workerScript.log("getScriptLogs", getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
+        workerScript.log("getScriptLogs", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
         return "";
       }
 
@@ -761,7 +768,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         runningScriptObj = getRunningScript(fn, hostname, "tail", scriptArgs);
       }
       if (runningScriptObj == null) {
-        workerScript.log("tail", getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
+        workerScript.log("tail", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
         return;
       }
 
@@ -774,7 +781,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "nuke");
       if (!(server instanceof Server)) {
-        workerScript.log("nuke", "Cannot be executed on this server.");
+        workerScript.log("nuke", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.NukeProgram.name)) {
@@ -784,10 +791,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         throw makeRuntimeErrorMsg("nuke", "Not enough ports opened to use NUKE.exe virus.");
       }
       if (server.hasAdminRights) {
-        workerScript.log("nuke", `Already have root access to '${server.hostname}'.`);
+        workerScript.log("nuke", () => `Already have root access to '${server.hostname}'.`);
       } else {
         server.hasAdminRights = true;
-        workerScript.log("nuke", `Executed NUKE.exe virus on '${server.hostname}' to gain root access.`);
+        workerScript.log("nuke", () => `Executed NUKE.exe virus on '${server.hostname}' to gain root access.`);
       }
       return true;
     },
@@ -798,18 +805,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "brutessh");
       if (!(server instanceof Server)) {
-        workerScript.log("brutessh", "Cannot be executed on this server.");
+        workerScript.log("brutessh", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.BruteSSHProgram.name)) {
         throw makeRuntimeErrorMsg("brutessh", "You do not have the BruteSSH.exe program!");
       }
       if (!server.sshPortOpen) {
-        workerScript.log("brutessh", `Executed BruteSSH.exe on '${server.hostname}' to open SSH port (22).`);
+        workerScript.log("brutessh", () => `Executed BruteSSH.exe on '${server.hostname}' to open SSH port (22).`);
         server.sshPortOpen = true;
         ++server.openPortCount;
       } else {
-        workerScript.log("brutessh", `SSH Port (22) already opened on '${server.hostname}'.`);
+        workerScript.log("brutessh", () => `SSH Port (22) already opened on '${server.hostname}'.`);
       }
       return true;
     },
@@ -820,18 +827,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "ftpcrack");
       if (!(server instanceof Server)) {
-        workerScript.log("ftpcrack", "Cannot be executed on this server.");
+        workerScript.log("ftpcrack", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.FTPCrackProgram.name)) {
         throw makeRuntimeErrorMsg("ftpcrack", "You do not have the FTPCrack.exe program!");
       }
       if (!server.ftpPortOpen) {
-        workerScript.log("ftpcrack", `Executed FTPCrack.exe on '${server.hostname}' to open FTP port (21).`);
+        workerScript.log("ftpcrack", () => `Executed FTPCrack.exe on '${server.hostname}' to open FTP port (21).`);
         server.ftpPortOpen = true;
         ++server.openPortCount;
       } else {
-        workerScript.log("ftpcrack", `FTP Port (21) already opened on '${server.hostname}'.`);
+        workerScript.log("ftpcrack", () => `FTP Port (21) already opened on '${server.hostname}'.`);
       }
       return true;
     },
@@ -842,18 +849,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "relaysmtp");
       if (!(server instanceof Server)) {
-        workerScript.log("relaysmtp", "Cannot be executed on this server.");
+        workerScript.log("relaysmtp", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.RelaySMTPProgram.name)) {
         throw makeRuntimeErrorMsg("relaysmtp", "You do not have the relaySMTP.exe program!");
       }
       if (!server.smtpPortOpen) {
-        workerScript.log("relaysmtp", `Executed relaySMTP.exe on '${server.hostname}' to open SMTP port (25).`);
+        workerScript.log("relaysmtp", () => `Executed relaySMTP.exe on '${server.hostname}' to open SMTP port (25).`);
         server.smtpPortOpen = true;
         ++server.openPortCount;
       } else {
-        workerScript.log("relaysmtp", `SMTP Port (25) already opened on '${server.hostname}'.`);
+        workerScript.log("relaysmtp", () => `SMTP Port (25) already opened on '${server.hostname}'.`);
       }
       return true;
     },
@@ -864,18 +871,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "httpworm");
       if (!(server instanceof Server)) {
-        workerScript.log("httpworm", "Cannot be executed on this server.");
+        workerScript.log("httpworm", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.HTTPWormProgram.name)) {
         throw makeRuntimeErrorMsg("httpworm", "You do not have the HTTPWorm.exe program!");
       }
       if (!server.httpPortOpen) {
-        workerScript.log("httpworm", `Executed HTTPWorm.exe on '${server.hostname}' to open HTTP port (80).`);
+        workerScript.log("httpworm", () => `Executed HTTPWorm.exe on '${server.hostname}' to open HTTP port (80).`);
         server.httpPortOpen = true;
         ++server.openPortCount;
       } else {
-        workerScript.log("httpworm", `HTTP Port (80) already opened on '${server.hostname}'.`);
+        workerScript.log("httpworm", () => `HTTP Port (80) already opened on '${server.hostname}'.`);
       }
       return true;
     },
@@ -886,18 +893,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       const server = safeGetServer(hostname, "sqlinject");
       if (!(server instanceof Server)) {
-        workerScript.log("sqlinject", "Cannot be executed on this server.");
+        workerScript.log("sqlinject", () => "Cannot be executed on this server.");
         return false;
       }
       if (!Player.hasProgram(Programs.SQLInjectProgram.name)) {
         throw makeRuntimeErrorMsg("sqlinject", "You do not have the SQLInject.exe program!");
       }
       if (!server.sqlPortOpen) {
-        workerScript.log("sqlinject", `Executed SQLInject.exe on '${server.hostname}' to open SQL port (1433).`);
+        workerScript.log("sqlinject", () => `Executed SQLInject.exe on '${server.hostname}' to open SQL port (1433).`);
         server.sqlPortOpen = true;
         ++server.openPortCount;
       } else {
-        workerScript.log("sqlinject", `SQL Port (1433) already opened on '${server.hostname}'.`);
+        workerScript.log("sqlinject", () => `SQL Port (1433) already opened on '${server.hostname}'.`);
       }
       return true;
     },
@@ -946,11 +953,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         return runScriptFromScript("spawn", scriptServer, scriptname, args, workerScript, threads);
       }, spawnDelay * 1e3);
 
-      workerScript.log("spawn", `Will execute '${scriptname}' in ${spawnDelay} seconds`);
+      workerScript.log("spawn", () => `Will execute '${scriptname}' in ${spawnDelay} seconds`);
 
       workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
       if (killWorkerScript(workerScript)) {
-        workerScript.log("spawn", "Exiting...");
+        workerScript.log("spawn", () => "Exiting...");
       }
     },
     kill: function (filename: any, hostname: any, ...scriptArgs: any): any {
@@ -970,7 +977,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         const server = safeGetServer(hostname, "kill");
         const runningScriptObj = getRunningScript(filename, hostname, "kill", scriptArgs);
         if (runningScriptObj == null) {
-          workerScript.log("kill", getCannotFindRunningScriptErrorMessage(filename, hostname, scriptArgs));
+          workerScript.log("kill", () => getCannotFindRunningScriptErrorMessage(filename, hostname, scriptArgs));
           return false;
         }
 
@@ -979,18 +986,21 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       if (res) {
         if (killByPid) {
-          workerScript.log("kill", `Killing script with PID ${filename}`);
+          workerScript.log("kill", () => `Killing script with PID ${filename}`);
         } else {
-          workerScript.log("kill", `Killing '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}.`);
+          workerScript.log(
+            "kill",
+            () => `Killing '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}.`,
+          );
         }
         return true;
       } else {
         if (killByPid) {
-          workerScript.log("kill", `No script with PID ${filename}`);
+          workerScript.log("kill", () => `No script with PID ${filename}`);
         } else {
           workerScript.log(
             "kill",
-            `No such script '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}`,
+            () => `No such script '${filename}' on '${hostname}' with args: ${arrayToString(scriptArgs)}`,
           );
         }
         return false;
@@ -1009,7 +1019,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       WorkerScriptStartStopEventEmitter.emit();
       workerScript.log(
         "killall",
-        `Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`,
+        () => `Killing all scripts on '${server.hostname}'. May take a few minutes for the scripts to die.`,
       );
 
       return scriptsRunning;
@@ -1017,9 +1027,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
     exit: function (): any {
       workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
       if (killWorkerScript(workerScript)) {
-        workerScript.log("exit", "Exiting...");
+        workerScript.log("exit", () => "Exiting...");
       } else {
-        workerScript.log("exit", "Failed. This is a bug. Report to dev.");
+        workerScript.log("exit", () => "Failed. This is a bug. Report to dev.");
       }
     },
     scp: async function (scriptname: any, hostname1: any, hostname2: any): Promise<boolean> {
@@ -1086,18 +1096,18 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         }
 
         if (!found) {
-          workerScript.log("scp", `File '${scriptname}' does not exist.`);
+          workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
           return Promise.resolve(false);
         }
 
         for (let i = 0; i < destServer.messages.length; ++i) {
           if (destServer.messages[i] === scriptname) {
-            workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
+            workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
             return Promise.resolve(true); // Already exists
           }
         }
         destServer.messages.push(scriptname);
-        workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
+        workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
         return Promise.resolve(true);
       }
 
@@ -1111,7 +1121,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
           }
         }
         if (txtFile === undefined) {
-          workerScript.log("scp", `File '${scriptname}' does not exist.`);
+          workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
           return Promise.resolve(false);
         }
 
@@ -1119,13 +1129,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
           if (destServer.textFiles[i].fn === scriptname) {
             // Overwrite
             destServer.textFiles[i].text = txtFile.text;
-            workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
+            workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
             return Promise.resolve(true);
           }
         }
         const newFile = new TextFile(txtFile.fn, txtFile.text);
         destServer.textFiles.push(newFile);
-        workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
+        workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
         return Promise.resolve(true);
       }
 
@@ -1138,14 +1148,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         }
       }
       if (sourceScript == null) {
-        workerScript.log("scp", `File '${scriptname}' does not exist.`);
+        workerScript.log("scp", () => `File '${scriptname}' does not exist.`);
         return Promise.resolve(false);
       }
 
       // Overwrite script if it already exists
       for (let i = 0; i < destServer.scripts.length; ++i) {
         if (scriptname == destServer.scripts[i].filename) {
-          workerScript.log("scp", `WARNING: File '${scriptname}' overwritten on '${destServer.hostname}'`);
+          workerScript.log("scp", () => `WARNING: File '${scriptname}' overwritten on '${destServer?.hostname}'`);
           const oldScript = destServer.scripts[i];
           // If it's the exact same file don't actually perform the
           // copy to avoid recompiling uselessly. Players tend to scp
@@ -1164,7 +1174,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       newScript.ramUsage = sourceScript.ramUsage;
       newScript.server = destServer.hostname;
       destServer.scripts.push(newScript);
-      workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
+      workerScript.log("scp", () => `File '${scriptname}' copied over to '${destServer?.hostname}'.`);
       return new Promise((resolve) => {
         if (destServer === null) {
           resolve(false);
@@ -1274,7 +1284,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
     getHackingLevel: function (): any {
       updateDynamicRam("getHackingLevel", getRamCost("getHackingLevel"));
       Player.updateSkillLevels();
-      workerScript.log("getHackingLevel", `returned ${Player.hacking}`);
+      workerScript.log("getHackingLevel", () => `returned ${Player.hacking}`);
       return Player.hacking;
     },
     getHackingMultipliers: function (): any {
@@ -1322,7 +1332,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerMoneyAvailable", getRamCost("getServerMoneyAvailable"));
       const server = safeGetServer(hostname, "getServerMoneyAvailable");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerMoneyAvailable", "Cannot be executed on this server.");
+        workerScript.log("getServerMoneyAvailable", () => "Cannot be executed on this server.");
         return 0;
       }
       if (failOnHacknetServer(server, "getServerMoneyAvailable")) {
@@ -1332,13 +1342,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         // Return player's money
         workerScript.log(
           "getServerMoneyAvailable",
-          `returned player's money: ${numeralWrapper.formatMoney(Player.money)}`,
+          () => `returned player's money: ${numeralWrapper.formatMoney(Player.money)}`,
         );
         return Player.money;
       }
       workerScript.log(
         "getServerMoneyAvailable",
-        `returned ${numeralWrapper.formatMoney(server.moneyAvailable)} for '${server.hostname}'`,
+        () => `returned ${numeralWrapper.formatMoney(server.moneyAvailable)} for '${server.hostname}'`,
       );
       return server.moneyAvailable;
     },
@@ -1346,7 +1356,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerSecurityLevel", getRamCost("getServerSecurityLevel"));
       const server = safeGetServer(hostname, "getServerSecurityLevel");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerSecurityLevel", "Cannot be executed on this server.");
+        workerScript.log("getServerSecurityLevel", () => "Cannot be executed on this server.");
         return 1;
       }
       if (failOnHacknetServer(server, "getServerSecurityLevel")) {
@@ -1354,7 +1364,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       workerScript.log(
         "getServerSecurityLevel",
-        `returned ${numeralWrapper.formatServerSecurity(server.hackDifficulty)} for '${server.hostname}'`,
+        () => `returned ${numeralWrapper.formatServerSecurity(server.hackDifficulty)} for '${server.hostname}'`,
       );
       return server.hackDifficulty;
     },
@@ -1362,11 +1372,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerBaseSecurityLevel", getRamCost("getServerBaseSecurityLevel"));
       workerScript.log(
         "getServerBaseSecurityLevel",
-        `getServerBaseSecurityLevel is deprecated because it's not useful.`,
+        () => `getServerBaseSecurityLevel is deprecated because it's not useful.`,
       );
       const server = safeGetServer(hostname, "getServerBaseSecurityLevel");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerBaseSecurityLevel", "Cannot be executed on this server.");
+        workerScript.log("getServerBaseSecurityLevel", () => "Cannot be executed on this server.");
         return 1;
       }
       if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) {
@@ -1374,7 +1384,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       workerScript.log(
         "getServerBaseSecurityLevel",
-        `returned ${numeralWrapper.formatServerSecurity(server.baseDifficulty)} for '${server.hostname}'`,
+        () => `returned ${numeralWrapper.formatServerSecurity(server.baseDifficulty)} for '${server.hostname}'`,
       );
       return server.baseDifficulty;
     },
@@ -1382,7 +1392,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerMinSecurityLevel", getRamCost("getServerMinSecurityLevel"));
       const server = safeGetServer(hostname, "getServerMinSecurityLevel");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerMinSecurityLevel", "Cannot be executed on this server.");
+        workerScript.log("getServerMinSecurityLevel", () => "Cannot be executed on this server.");
         return 1;
       }
       if (failOnHacknetServer(server, "getServerMinSecurityLevel")) {
@@ -1390,7 +1400,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       workerScript.log(
         "getServerMinSecurityLevel",
-        `returned ${numeralWrapper.formatServerSecurity(server.minDifficulty)} for ${server.hostname}`,
+        () => `returned ${numeralWrapper.formatServerSecurity(server.minDifficulty)} for ${server.hostname}`,
       );
       return server.minDifficulty;
     },
@@ -1398,7 +1408,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerRequiredHackingLevel", getRamCost("getServerRequiredHackingLevel"));
       const server = safeGetServer(hostname, "getServerRequiredHackingLevel");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerRequiredHackingLevel", "Cannot be executed on this server.");
+        workerScript.log("getServerRequiredHackingLevel", () => "Cannot be executed on this server.");
         return 1;
       }
       if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) {
@@ -1406,7 +1416,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       workerScript.log(
         "getServerRequiredHackingLevel",
-        `returned ${numeralWrapper.formatSkill(server.requiredHackingSkill)} for '${server.hostname}'`,
+        () => `returned ${numeralWrapper.formatSkill(server.requiredHackingSkill)} for '${server.hostname}'`,
       );
       return server.requiredHackingSkill;
     },
@@ -1414,7 +1424,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerMaxMoney", getRamCost("getServerMaxMoney"));
       const server = safeGetServer(hostname, "getServerMaxMoney");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerMaxMoney", "Cannot be executed on this server.");
+        workerScript.log("getServerMaxMoney", () => "Cannot be executed on this server.");
         return 0;
       }
       if (failOnHacknetServer(server, "getServerMaxMoney")) {
@@ -1422,7 +1432,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       }
       workerScript.log(
         "getServerMaxMoney",
-        `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`,
+        () => `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`,
       );
       return server.moneyMax;
     },
@@ -1430,48 +1440,54 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getServerGrowth", getRamCost("getServerGrowth"));
       const server = safeGetServer(hostname, "getServerGrowth");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerGrowth", "Cannot be executed on this server.");
+        workerScript.log("getServerGrowth", () => "Cannot be executed on this server.");
         return 1;
       }
       if (failOnHacknetServer(server, "getServerGrowth")) {
         return 1;
       }
-      workerScript.log("getServerGrowth", `returned ${server.serverGrowth} for '${server.hostname}'`);
+      workerScript.log("getServerGrowth", () => `returned ${server.serverGrowth} for '${server.hostname}'`);
       return server.serverGrowth;
     },
     getServerNumPortsRequired: function (hostname: any): any {
       updateDynamicRam("getServerNumPortsRequired", getRamCost("getServerNumPortsRequired"));
       const server = safeGetServer(hostname, "getServerNumPortsRequired");
       if (!(server instanceof Server)) {
-        workerScript.log("getServerNumPortsRequired", "Cannot be executed on this server.");
+        workerScript.log("getServerNumPortsRequired", () => "Cannot be executed on this server.");
         return 5;
       }
       if (failOnHacknetServer(server, "getServerNumPortsRequired")) {
         return 5;
       }
-      workerScript.log("getServerNumPortsRequired", `returned ${server.numOpenPortsRequired} for '${server.hostname}'`);
+      workerScript.log(
+        "getServerNumPortsRequired",
+        () => `returned ${server.numOpenPortsRequired} for '${server.hostname}'`,
+      );
       return server.numOpenPortsRequired;
     },
     getServerRam: function (hostname: any): any {
       updateDynamicRam("getServerRam", getRamCost("getServerRam"));
-      workerScript.log("getServerRam", `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`);
+      workerScript.log(
+        "getServerRam",
+        () => `getServerRam is deprecated in favor of getServerMaxRam / getServerUsedRam`,
+      );
       const server = safeGetServer(hostname, "getServerRam");
       workerScript.log(
         "getServerRam",
-        `returned [${numeralWrapper.formatRAM(server.maxRam)}, ${numeralWrapper.formatRAM(server.ramUsed)}]`,
+        () => `returned [${numeralWrapper.formatRAM(server.maxRam)}, ${numeralWrapper.formatRAM(server.ramUsed)}]`,
       );
       return [server.maxRam, server.ramUsed];
     },
     getServerMaxRam: function (hostname: any): any {
       updateDynamicRam("getServerMaxRam", getRamCost("getServerMaxRam"));
       const server = safeGetServer(hostname, "getServerMaxRam");
-      workerScript.log("getServerMaxRam", `returned ${numeralWrapper.formatRAM(server.maxRam)}`);
+      workerScript.log("getServerMaxRam", () => `returned ${numeralWrapper.formatRAM(server.maxRam)}`);
       return server.maxRam;
     },
     getServerUsedRam: function (hostname: any): any {
       updateDynamicRam("getServerUsedRam", getRamCost("getServerUsedRam"));
       const server = safeGetServer(hostname, "getServerUsedRam");
-      workerScript.log("getServerUsedRam", `returned ${numeralWrapper.formatRAM(server.ramUsed)}`);
+      workerScript.log("getServerUsedRam", () => `returned ${numeralWrapper.formatRAM(server.ramUsed)}`);
       return server.ramUsed;
     },
     serverExists: function (hostname: any): any {
@@ -1531,7 +1547,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       const cost = getPurchaseServerCost(ram);
       if (cost === Infinity) {
-        workerScript.log("getPurchasedServerCost", `Invalid argument: ram='${ram}'`);
+        workerScript.log("getPurchasedServerCost", () => `Invalid argument: ram='${ram}'`);
         return Infinity;
       }
 
@@ -1542,28 +1558,29 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       let hostnameStr = String(name);
       hostnameStr = hostnameStr.replace(/\s+/g, "");
       if (hostnameStr == "") {
-        workerScript.log("purchaseServer", `Invalid argument: hostname='${hostnameStr}'`);
+        workerScript.log("purchaseServer", () => `Invalid argument: hostname='${hostnameStr}'`);
         return "";
       }
 
       if (Player.purchasedServers.length >= getPurchaseServerLimit()) {
         workerScript.log(
           "purchaseServer",
-          `You have reached the maximum limit of ${getPurchaseServerLimit()} servers. You cannot purchase any more.`,
+          () =>
+            `You have reached the maximum limit of ${getPurchaseServerLimit()} servers. You cannot purchase any more.`,
         );
         return "";
       }
 
       const cost = getPurchaseServerCost(ram);
       if (cost === Infinity) {
-        workerScript.log("purchaseServer", `Invalid argument: ram='${ram}'`);
+        workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}'`);
         return "";
       }
 
       if (Player.money < cost) {
         workerScript.log(
           "purchaseServer",
-          `Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`,
+          () => `Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`,
         );
         return "";
       }
@@ -1585,7 +1602,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       Player.loseMoney(cost, "servers");
       workerScript.log(
         "purchaseServer",
-        `Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`,
+        () => `Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`,
       );
       return newServ.hostname;
     },
@@ -1595,12 +1612,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       hostnameStr = hostnameStr.replace(/\s\s+/g, "");
       const server = GetServer(hostnameStr);
       if (!(server instanceof Server)) {
-        workerScript.log("deleteServer", `Invalid argument: hostname='${hostnameStr}'`);
+        workerScript.log("deleteServer", () => `Invalid argument: hostname='${hostnameStr}'`);
         return false;
       }
 
       if (!server.purchasedByPlayer || server.hostname === "home") {
-        workerScript.log("deleteServer", "Cannot delete non-purchased server.");
+        workerScript.log("deleteServer", () => "Cannot delete non-purchased server.");
         return false;
       }
 
@@ -1608,19 +1625,22 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       // Can't delete server you're currently connected to
       if (server.isConnectedTo) {
-        workerScript.log("deleteServer", "You are currently connected to the server you are trying to delete.");
+        workerScript.log("deleteServer", () => "You are currently connected to the server you are trying to delete.");
         return false;
       }
 
       // A server cannot delete itself
       if (hostname === workerScript.hostname) {
-        workerScript.log("deleteServer", "Cannot delete the server this script is running on.");
+        workerScript.log("deleteServer", () => "Cannot delete the server this script is running on.");
         return false;
       }
 
       // Delete all scripts running on server
       if (server.runningScripts.length > 0) {
-        workerScript.log("deleteServer", `Cannot delete server '${hostname}' because it still has scripts running.`);
+        workerScript.log(
+          "deleteServer",
+          () => `Cannot delete server '${hostname}' because it still has scripts running.`,
+        );
         return false;
       }
 
@@ -1637,7 +1657,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       if (!found) {
         workerScript.log(
           "deleteServer",
-          `Could not identify server ${hostname} as a purchased server. This is a bug. Report to dev.`,
+          () => `Could not identify server ${hostname} as a purchased server. This is a bug. Report to dev.`,
         );
         return false;
       }
@@ -1651,14 +1671,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       for (let i = 0; i < homeComputer.serversOnNetwork.length; ++i) {
         if (hostname == homeComputer.serversOnNetwork[i]) {
           homeComputer.serversOnNetwork.splice(i, 1);
-          workerScript.log("deleteServer", `Deleted server '${hostnameStr}`);
+          workerScript.log("deleteServer", () => `Deleted server '${hostnameStr}`);
           return true;
         }
       }
       // Wasn't found on home computer
       workerScript.log(
         "deleteServer",
-        `Could not find server ${hostname} as a purchased server. This is a bug. Report to dev.`,
+        () => `Could not find server ${hostname} as a purchased server. This is a bug. Report to dev.`,
       );
       return false;
     },
@@ -1896,7 +1916,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
 
       const status = s.removeFile(fn);
       if (!status.res) {
-        workerScript.log("rm", status.msg + "");
+        workerScript.log("rm", () => status.msg + "");
       }
 
       return status.res;
@@ -1973,7 +1993,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getHackTime", getRamCost("getHackTime"));
       const server = safeGetServer(hostname, "getHackTime");
       if (!(server instanceof Server)) {
-        workerScript.log("getHackTime", "invalid for this kind of server");
+        workerScript.log("getHackTime", () => "invalid for this kind of server");
         return Infinity;
       }
       if (failOnHacknetServer(server, "getHackTime")) {
@@ -1986,7 +2006,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getGrowTime", getRamCost("getGrowTime"));
       const server = safeGetServer(hostname, "getGrowTime");
       if (!(server instanceof Server)) {
-        workerScript.log("getGrowTime", "invalid for this kind of server");
+        workerScript.log("getGrowTime", () => "invalid for this kind of server");
         return Infinity;
       }
       if (failOnHacknetServer(server, "getGrowTime")) {
@@ -1999,7 +2019,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
       updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime"));
       const server = safeGetServer(hostname, "getWeakenTime");
       if (!(server instanceof Server)) {
-        workerScript.log("getWeakenTime", "invalid for this kind of server");
+        workerScript.log("getWeakenTime", () => "invalid for this kind of server");
         return Infinity;
       }
       if (failOnHacknetServer(server, "getWeakenTime")) {
@@ -2030,7 +2050,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         if (runningScriptObj == null) {
           workerScript.log(
             "getScriptIncome",
-            `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
+            () => `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
           );
           return -1;
         }
@@ -2052,7 +2072,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
         if (runningScriptObj == null) {
           workerScript.log(
             "getScriptExpGain",
-            `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
+            () => `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
           );
           return -1;
         }
@@ -2095,7 +2115,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
     },
     wget: async function (url: any, target: any, hostname: any = workerScript.hostname): Promise<boolean> {
       if (!isScriptFilename(target) && !target.endsWith(".txt")) {
-        workerScript.log("wget", `Invalid target file: '${target}'. Must be a script or text file.`);
+        workerScript.log("wget", () => `Invalid target file: '${target}'. Must be a script or text file.`);
         return Promise.resolve(false);
       }
       const s = safeGetServer(hostname, "wget");
@@ -2110,19 +2130,22 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
               res = s.writeToTextFile(target, data);
             }
             if (!res.success) {
-              workerScript.log("wget", "Failed.");
+              workerScript.log("wget", () => "Failed.");
               return resolve(false);
             }
             if (res.overwritten) {
-              workerScript.log("wget", `Successfully retrieved content and overwrote '${target}' on '${hostname}'`);
+              workerScript.log(
+                "wget",
+                () => `Successfully retrieved content and overwrote '${target}' on '${hostname}'`,
+              );
               return resolve(true);
             }
-            workerScript.log("wget", `Successfully retrieved content to new file '${target}' on '${hostname}'`);
+            workerScript.log("wget", () => `Successfully retrieved content to new file '${target}' on '${hostname}'`);
             return resolve(true);
           },
           "text",
         ).fail(function (e) {
-          workerScript.log("wget", JSON.stringify(e));
+          workerScript.log("wget", () => JSON.stringify(e));
           return resolve(false);
         });
       });
diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts
index 0e78ebf0f..68e10b1c2 100644
--- a/src/NetscriptFunctions/Bladeburner.ts
+++ b/src/NetscriptFunctions/Bladeburner.ts
@@ -344,13 +344,13 @@ export function NetscriptBladeburner(
           player.agility >= 100
         ) {
           player.bladeburner = new Bladeburner(player);
-          workerScript.log("joinBladeburnerDivision", "You have been accepted into the Bladeburner division");
+          workerScript.log("joinBladeburnerDivision", () => "You have been accepted into the Bladeburner division");
 
           return true;
         } else {
           workerScript.log(
             "joinBladeburnerDivision",
-            "You do not meet the requirements for joining the Bladeburner division",
+            () => "You do not meet the requirements for joining the Bladeburner division",
           );
           return false;
         }
diff --git a/src/NetscriptFunctions/CodingContract.ts b/src/NetscriptFunctions/CodingContract.ts
index 9c382c072..9f36aa9f9 100644
--- a/src/NetscriptFunctions/CodingContract.ts
+++ b/src/NetscriptFunctions/CodingContract.ts
@@ -53,20 +53,24 @@ export function NetscriptCodingContract(
       const serv = helper.getServer(hostname, "codingcontract.attempt");
       if (contract.isSolution(answer)) {
         const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
-        workerScript.log("attempt", `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
+        workerScript.log("attempt", () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
         serv.removeContract(filename);
         return returnReward ? reward : true;
       } else {
         ++contract.tries;
         if (contract.tries >= contract.getMaxNumTries()) {
-          workerScript.log("attempt", `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
+          workerScript.log(
+            "attempt",
+            () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`,
+          );
           serv.removeContract(filename);
         } else {
           workerScript.log(
             "attempt",
-            `Coding Contract attempt '${filename}' failed. ${
-              contract.getMaxNumTries() - contract.tries
-            } attempts remaining.`,
+            () =>
+              `Coding Contract attempt '${filename}' failed. ${
+                contract.getMaxNumTries() - contract.tries
+              } attempts remaining.`,
           );
         }
 
diff --git a/src/NetscriptFunctions/Gang.ts b/src/NetscriptFunctions/Gang.ts
index 34082282e..d8b6793fa 100644
--- a/src/NetscriptFunctions/Gang.ts
+++ b/src/NetscriptFunctions/Gang.ts
@@ -167,9 +167,9 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
       if (gang === null) throw new Error("Should not be called without Gang");
       const recruited = gang.recruitMember(name);
       if (recruited) {
-        workerScript.log("recruitMember", `Successfully recruited Gang Member '${name}'`);
+        workerScript.log("recruitMember", () => `Successfully recruited Gang Member '${name}'`);
       } else {
-        workerScript.log("recruitMember", `Failed to recruit Gang Member '${name}'`);
+        workerScript.log("recruitMember", () => `Failed to recruit Gang Member '${name}'`);
       }
 
       return recruited;
@@ -189,11 +189,14 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
       const member = getGangMember("setMemberTask", memberName);
       const success = member.assignToTask(taskName);
       if (success) {
-        workerScript.log("setMemberTask", `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`);
+        workerScript.log(
+          "setMemberTask",
+          () => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
+        );
       } else {
         workerScript.log(
           "setMemberTask",
-          `Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
+          () => `Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
         );
       }
 
@@ -248,9 +251,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
       if (!equipment) return false;
       const res = member.buyUpgrade(equipment, player, gang);
       if (res) {
-        workerScript.log("purchaseEquipment", `Purchased '${equipName}' for Gang member '${memberName}'`);
+        workerScript.log("purchaseEquipment", () => `Purchased '${equipName}' for Gang member '${memberName}'`);
       } else {
-        workerScript.log("purchaseEquipment", `Failed to purchase '${equipName}' for Gang member '${memberName}'`);
+        workerScript.log(
+          "purchaseEquipment",
+          () => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
+        );
       }
 
       return res;
@@ -271,10 +277,10 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
       if (gang === null) throw new Error("Should not be called without Gang");
       if (engage) {
         gang.territoryWarfareEngaged = true;
-        workerScript.log("setTerritoryWarfare", "Engaging in Gang Territory Warfare");
+        workerScript.log("setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
       } else {
         gang.territoryWarfareEngaged = false;
-        workerScript.log("setTerritoryWarfare", "Disengaging in Gang Territory Warfare");
+        workerScript.log("setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
       }
     },
     getChanceToWinClash: function (otherGang: any): number {
diff --git a/src/NetscriptFunctions/Hacknet.ts b/src/NetscriptFunctions/Hacknet.ts
index 56fc3b4c1..4626a50c5 100644
--- a/src/NetscriptFunctions/Hacknet.ts
+++ b/src/NetscriptFunctions/Hacknet.ts
@@ -109,7 +109,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
       }
       const node = getHacknetNode(i, "upgradeCache");
       if (!(node instanceof HacknetServer)) {
-        workerScript.log("upgradeCache", "Can only be called on hacknet servers");
+        workerScript.log("upgradeCache", () => "Can only be called on hacknet servers");
         return false;
       }
       const res = purchaseCacheUpgrade(player, node, n);
@@ -136,7 +136,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
       }
       const node = getHacknetNode(i, "upgradeCache");
       if (!(node instanceof HacknetServer)) {
-        workerScript.log("getCacheUpgradeCost", "Can only be called on hacknet servers");
+        workerScript.log("getCacheUpgradeCost", () => "Can only be called on hacknet servers");
         return -1;
       }
       return node.calculateCacheUpgradeCost(n);
diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts
index f7c38ca07..c7c2ebb89 100644
--- a/src/NetscriptFunctions/Singularity.ts
+++ b/src/NetscriptFunctions/Singularity.ts
@@ -186,7 +186,10 @@ export function NetscriptSingularity(
       }
 
       if (!augs.includes(name)) {
-        workerScript.log("purchaseAugmentation", `Faction '${faction}' does not have the '${name}' augmentation.`);
+        workerScript.log(
+          "purchaseAugmentation",
+          () => `Faction '${faction}' does not have the '${name}' augmentation.`,
+        );
         return false;
       }
 
@@ -194,25 +197,25 @@ export function NetscriptSingularity(
       if (!isNeuroflux) {
         for (let j = 0; j < player.queuedAugmentations.length; ++j) {
           if (player.queuedAugmentations[j].name === aug.name) {
-            workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`);
+            workerScript.log("purchaseAugmentation", () => `You already have the '${name}' augmentation.`);
             return false;
           }
         }
         for (let j = 0; j < player.augmentations.length; ++j) {
           if (player.augmentations[j].name === aug.name) {
-            workerScript.log("purchaseAugmentation", `You already have the '${name}' augmentation.`);
+            workerScript.log("purchaseAugmentation", () => `You already have the '${name}' augmentation.`);
             return false;
           }
         }
       }
 
       if (fac.playerReputation < aug.baseRepRequirement) {
-        workerScript.log("purchaseAugmentation", `You do not have enough reputation with '${fac.name}'.`);
+        workerScript.log("purchaseAugmentation", () => `You do not have enough reputation with '${fac.name}'.`);
         return false;
       }
 
       const res = purchaseAugmentation(aug, fac, true);
-      workerScript.log("purchaseAugmentation", res);
+      workerScript.log("purchaseAugmentation", () => res);
       if (isString(res) && res.startsWith("You purchased")) {
         player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
         return true;
@@ -224,7 +227,7 @@ export function NetscriptSingularity(
       helper.updateDynamicRam("softReset", getRamCost("softReset"));
       helper.checkSingularityAccess("softReset", 3);
 
-      workerScript.log("softReset", "Soft resetting. This will cause this script to be killed");
+      workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed");
       setTimeout(() => {
         prestigeAugmentation();
         runAfterReset(cbScript);
@@ -239,11 +242,14 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("installAugmentations", 3);
 
       if (player.queuedAugmentations.length === 0) {
-        workerScript.log("installAugmentations", "You do not have any Augmentations to be installed.");
+        workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed.");
         return false;
       }
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
-      workerScript.log("installAugmentations", "Installing Augmentations. This will cause this script to be killed");
+      workerScript.log(
+        "installAugmentations",
+        () => "Installing Augmentations. This will cause this script to be killed",
+      );
       setTimeout(() => {
         installAugmentations();
         runAfterReset(cbScript);
@@ -258,11 +264,11 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("goToLocation", 1);
       const location = Object.values(Locations).find((l) => l.name === locationName);
       if (!location) {
-        workerScript.log("goToLocation", `No location named ${locationName}`);
+        workerScript.log("goToLocation", () => `No location named ${locationName}`);
         return false;
       }
       if (player.city !== location.city) {
-        workerScript.log("goToLocation", `No location named ${locationName} in ${player.city}`);
+        workerScript.log("goToLocation", () => `No location named ${locationName} in ${player.city}`);
         return false;
       }
       Router.toLocation(location);
@@ -274,7 +280,7 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("universityCourse", 1);
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("universityCourse", txt);
+        workerScript.log("universityCourse", () => txt);
       }
 
       let costMult, expMult;
@@ -283,7 +289,7 @@ export function NetscriptSingularity(
           if (player.city != CityName.Aevum) {
             workerScript.log(
               "universityCourse",
-              "You cannot study at 'Summit University' because you are not in 'Aevum'.",
+              () => "You cannot study at 'Summit University' because you are not in 'Aevum'.",
             );
             return false;
           }
@@ -295,7 +301,7 @@ export function NetscriptSingularity(
           if (player.city != CityName.Sector12) {
             workerScript.log(
               "universityCourse",
-              "You cannot study at 'Rothman University' because you are not in 'Sector-12'.",
+              () => "You cannot study at 'Rothman University' because you are not in 'Sector-12'.",
             );
             return false;
           }
@@ -307,7 +313,7 @@ export function NetscriptSingularity(
           if (player.city != CityName.Volhaven) {
             workerScript.log(
               "universityCourse",
-              "You cannot study at 'ZB Institute of Technology' because you are not in 'Volhaven'.",
+              () => "You cannot study at 'ZB Institute of Technology' because you are not in 'Volhaven'.",
             );
             return false;
           }
@@ -316,11 +322,11 @@ export function NetscriptSingularity(
           expMult = 4;
           break;
         default:
-          workerScript.log("universityCourse", `Invalid university name: '${universityName}'.`);
+          workerScript.log("universityCourse", () => `Invalid university name: '${universityName}'.`);
           return false;
       }
 
-      let task;
+      let task = "";
       switch (className.toLowerCase()) {
         case "Study Computer Science".toLowerCase():
           task = CONSTANTS.ClassStudyComputerScience;
@@ -341,11 +347,11 @@ export function NetscriptSingularity(
           task = CONSTANTS.ClassLeadership;
           break;
         default:
-          workerScript.log("universityCourse", `Invalid class name: ${className}.`);
+          workerScript.log("universityCourse", () => `Invalid class name: ${className}.`);
           return false;
       }
       player.startClass(Router, costMult, expMult, task);
-      workerScript.log("universityCourse", `Started ${task} at ${universityName}`);
+      workerScript.log("universityCourse", () => `Started ${task} at ${universityName}`);
       return true;
     },
 
@@ -354,13 +360,16 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("gymWorkout", 1);
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("gymWorkout", txt);
+        workerScript.log("gymWorkout", () => txt);
       }
       let costMult, expMult;
       switch (gymName.toLowerCase()) {
         case LocationName.AevumCrushFitnessGym.toLowerCase():
           if (player.city != CityName.Aevum) {
-            workerScript.log("gymWorkout", "You cannot workout at 'Crush Fitness' because you are not in 'Aevum'.");
+            workerScript.log(
+              "gymWorkout",
+              () => "You cannot workout at 'Crush Fitness' because you are not in 'Aevum'.",
+            );
             return false;
           }
           player.location = LocationName.AevumCrushFitnessGym;
@@ -369,7 +378,10 @@ export function NetscriptSingularity(
           break;
         case LocationName.AevumSnapFitnessGym.toLowerCase():
           if (player.city != CityName.Aevum) {
-            workerScript.log("gymWorkout", "You cannot workout at 'Snap Fitness' because you are not in 'Aevum'.");
+            workerScript.log(
+              "gymWorkout",
+              () => "You cannot workout at 'Snap Fitness' because you are not in 'Aevum'.",
+            );
             return false;
           }
           player.location = LocationName.AevumSnapFitnessGym;
@@ -378,7 +390,10 @@ export function NetscriptSingularity(
           break;
         case LocationName.Sector12IronGym.toLowerCase():
           if (player.city != CityName.Sector12) {
-            workerScript.log("gymWorkout", "You cannot workout at 'Iron Gym' because you are not in 'Sector-12'.");
+            workerScript.log(
+              "gymWorkout",
+              () => "You cannot workout at 'Iron Gym' because you are not in 'Sector-12'.",
+            );
             return false;
           }
           player.location = LocationName.Sector12IronGym;
@@ -389,7 +404,7 @@ export function NetscriptSingularity(
           if (player.city != CityName.Sector12) {
             workerScript.log(
               "gymWorkout",
-              "You cannot workout at 'Powerhouse Gym' because you are not in 'Sector-12'.",
+              () => "You cannot workout at 'Powerhouse Gym' because you are not in 'Sector-12'.",
             );
             return false;
           }
@@ -401,7 +416,7 @@ export function NetscriptSingularity(
           if (player.city != CityName.Volhaven) {
             workerScript.log(
               "gymWorkout",
-              "You cannot workout at 'Millenium Fitness Gym' because you are not in 'Volhaven'.",
+              () => "You cannot workout at 'Millenium Fitness Gym' because you are not in 'Volhaven'.",
             );
             return false;
           }
@@ -410,7 +425,7 @@ export function NetscriptSingularity(
           expMult = 4;
           break;
         default:
-          workerScript.log("gymWorkout", `Invalid gym name: ${gymName}. gymWorkout() failed`);
+          workerScript.log("gymWorkout", () => `Invalid gym name: ${gymName}. gymWorkout() failed`);
           return false;
       }
 
@@ -432,10 +447,10 @@ export function NetscriptSingularity(
           player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymAgility);
           break;
         default:
-          workerScript.log("gymWorkout", `Invalid stat: ${stat}.`);
+          workerScript.log("gymWorkout", () => `Invalid stat: ${stat}.`);
           return false;
       }
-      workerScript.log("gymWorkout", `Started training ${stat} at ${gymName}`);
+      workerScript.log("gymWorkout", () => `Started training ${stat} at ${gymName}`);
       return true;
     },
 
@@ -455,11 +470,11 @@ export function NetscriptSingularity(
           }
           player.loseMoney(CONSTANTS.TravelCost, "other");
           player.city = cityname;
-          workerScript.log("travelToCity", `Traveled to ${cityname}`);
+          workerScript.log("travelToCity", () => `Traveled to ${cityname}`);
           player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50);
           return true;
         default:
-          workerScript.log("travelToCity", `Invalid city name: '${cityname}'.`);
+          workerScript.log("travelToCity", () => `Invalid city name: '${cityname}'.`);
           return false;
       }
     },
@@ -469,12 +484,12 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("purchaseTor", 1);
 
       if (player.hasTorRouter()) {
-        workerScript.log("purchaseTor", "You already have a TOR router!");
+        workerScript.log("purchaseTor", () => "You already have a TOR router!");
         return false;
       }
 
       if (player.money < CONSTANTS.TorRouterCost) {
-        workerScript.log("purchaseTor", "You cannot afford to purchase a Tor router.");
+        workerScript.log("purchaseTor", () => "You cannot afford to purchase a Tor router.");
         return false;
       }
       player.loseMoney(CONSTANTS.TorRouterCost, "other");
@@ -493,7 +508,7 @@ export function NetscriptSingularity(
       player.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
       darkweb.serversOnNetwork.push(player.getHomeComputer().hostname);
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
-      workerScript.log("purchaseTor", "You have purchased a Tor router!");
+      workerScript.log("purchaseTor", () => "You have purchased a Tor router!");
       return true;
     },
     purchaseProgram: function (programName: any): any {
@@ -501,35 +516,28 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("purchaseProgram", 1);
 
       if (!player.hasTorRouter()) {
-        workerScript.log("purchaseProgram", "You do not have the TOR router.");
+        workerScript.log("purchaseProgram", () => "You do not have the TOR router.");
         return false;
       }
 
       programName = programName.toLowerCase();
 
-      let item = null;
-      for (const key in DarkWebItems) {
-        const i = DarkWebItems[key];
-        if (i.program.toLowerCase() == programName) {
-          item = i;
-        }
-      }
-
+      const item = Object.values(DarkWebItems).find((i) => i.program.toLowerCase() === programName);
       if (item == null) {
-        workerScript.log("purchaseProgram", `Invalid program name: '${programName}.`);
+        workerScript.log("purchaseProgram", () => `Invalid program name: '${programName}.`);
         return false;
       }
 
       if (player.money < item.price) {
         workerScript.log(
           "purchaseProgram",
-          `Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`,
+          () => `Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`,
         );
         return false;
       }
 
       if (player.hasProgram(item.program)) {
-        workerScript.log("purchaseProgram", `You already have the '${item.program}' program`);
+        workerScript.log("purchaseProgram", () => `You already have the '${item.program}' program`);
         return true;
       }
 
@@ -537,7 +545,7 @@ export function NetscriptSingularity(
       player.getHomeComputer().programs.push(item.program);
       workerScript.log(
         "purchaseProgram",
-        `You have purchased the '${item.program}' program. The new program can be found on your home computer.`,
+        () => `You have purchased the '${item.program}' program. The new program can be found on your home computer.`,
       );
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50);
       return true;
@@ -593,7 +601,7 @@ export function NetscriptSingularity(
       helper.checkSingularityAccess("installBackdoor", 1);
       const baseserver = player.getCurrentServer();
       if (!(baseserver instanceof Server)) {
-        workerScript.log("installBackdoor", "cannot backdoor this kind of server");
+        workerScript.log("installBackdoor", () => "cannot backdoor this kind of server");
         return Promise.resolve();
       }
       const server = baseserver as Server;
@@ -607,14 +615,14 @@ export function NetscriptSingularity(
 
       workerScript.log(
         "installBackdoor",
-        `Installing backdoor on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(installTime, true)}`,
+        () => `Installing backdoor on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(installTime, true)}`,
       );
 
       return netscriptDelay(installTime, workerScript).then(function () {
         if (workerScript.env.stopFlag) {
           return Promise.reject(workerScript);
         }
-        workerScript.log("installBackdoor", `Successfully installed backdoor on '${server.hostname}'`);
+        workerScript.log("installBackdoor", () => `Successfully installed backdoor on '${server.hostname}'`);
 
         server.backdoorInstalled = true;
 
@@ -627,7 +635,7 @@ export function NetscriptSingularity(
     getStats: function (): any {
       helper.updateDynamicRam("getStats", getRamCost("getStats"));
       helper.checkSingularityAccess("getStats", 1);
-      workerScript.log("getStats", `getStats is deprecated, please use getplayer`);
+      workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`);
 
       return {
         hacking: player.hacking,
@@ -642,7 +650,7 @@ export function NetscriptSingularity(
     getCharacterInformation: function (): any {
       helper.updateDynamicRam("getCharacterInformation", getRamCost("getCharacterInformation"));
       helper.checkSingularityAccess("getCharacterInformation", 1);
-      workerScript.log("getCharacterInformation", `getCharacterInformation is deprecated, please use getplayer`);
+      workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`);
 
       return {
         bitnode: player.bitNodeN,
@@ -691,7 +699,7 @@ export function NetscriptSingularity(
       helper.updateDynamicRam("hospitalize", getRamCost("hospitalize"));
       helper.checkSingularityAccess("hospitalize", 1);
       if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
-        workerScript.log("hospitalize", "Cannot go to the hospital because the player is busy.");
+        workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy.");
         return;
       }
       return player.hospitalize();
@@ -707,7 +715,7 @@ export function NetscriptSingularity(
       if (player.isWorking) {
         Router.toTerminal();
         const txt = player.singularityStopWork();
-        workerScript.log("stopAction", txt);
+        workerScript.log("stopAction", () => txt);
         return true;
       }
       return false;
@@ -719,13 +727,16 @@ export function NetscriptSingularity(
       // Check if we're at max cores
       const homeComputer = player.getHomeComputer();
       if (homeComputer.cpuCores >= 8) {
-        workerScript.log("upgradeHomeCores", `Your home computer is at max cores.`);
+        workerScript.log("upgradeHomeCores", () => `Your home computer is at max cores.`);
         return false;
       }
 
       const cost = player.getUpgradeHomeCoresCost();
       if (player.money < cost) {
-        workerScript.log("upgradeHomeCores", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`);
+        workerScript.log(
+          "upgradeHomeCores",
+          () => `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`,
+        );
         return false;
       }
 
@@ -735,7 +746,7 @@ export function NetscriptSingularity(
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
       workerScript.log(
         "upgradeHomeCores",
-        `Purchased an additional core for home computer! It now has ${homeComputer.cpuCores} cores.`,
+        () => `Purchased an additional core for home computer! It now has ${homeComputer.cpuCores} cores.`,
       );
       return true;
     },
@@ -752,13 +763,16 @@ export function NetscriptSingularity(
       // Check if we're at max RAM
       const homeComputer = player.getHomeComputer();
       if (homeComputer.maxRam >= CONSTANTS.HomeComputerMaxRam) {
-        workerScript.log("upgradeHomeRam", `Your home computer is at max RAM.`);
+        workerScript.log("upgradeHomeRam", () => `Your home computer is at max RAM.`);
         return false;
       }
 
       const cost = player.getUpgradeHomeRamCost();
       if (player.money < cost) {
-        workerScript.log("upgradeHomeRam", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`);
+        workerScript.log(
+          "upgradeHomeRam",
+          () => `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`,
+        );
         return false;
       }
 
@@ -768,9 +782,10 @@ export function NetscriptSingularity(
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
       workerScript.log(
         "upgradeHomeRam",
-        `Purchased additional RAM for home computer! It now has ${numeralWrapper.formatRAM(
-          homeComputer.maxRam,
-        )} of RAM.`,
+        () =>
+          `Purchased additional RAM for home computer! It now has ${numeralWrapper.formatRAM(
+            homeComputer.maxRam,
+          )} of RAM.`,
       );
       return true;
     },
@@ -791,13 +806,13 @@ export function NetscriptSingularity(
 
       // Make sure its a valid company
       if (companyName == null || companyName === "" || !(Companies[companyName] instanceof Company)) {
-        workerScript.log("workForCompany", `Invalid company: '${companyName}'`);
+        workerScript.log("workForCompany", () => `Invalid company: '${companyName}'`);
         return false;
       }
 
       // Make sure player is actually employed at the comapny
       if (!Object.keys(player.jobs).includes(companyName)) {
-        workerScript.log("workForCompany", `You do not have a job at '${companyName}'`);
+        workerScript.log("workForCompany", () => `You do not have a job at '${companyName}'`);
         return false;
       }
 
@@ -805,13 +820,13 @@ export function NetscriptSingularity(
       const companyPositionName = player.jobs[companyName];
       const companyPosition = CompanyPositions[companyPositionName];
       if (companyPositionName === "" || !(companyPosition instanceof CompanyPosition)) {
-        workerScript.log("workForCompany", "You do not have a job");
+        workerScript.log("workForCompany", () => "You do not have a job");
         return false;
       }
 
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("workForCompany", txt);
+        workerScript.log("workForCompany", () => txt);
       }
 
       if (companyPosition.isPartTimeJob()) {
@@ -819,7 +834,10 @@ export function NetscriptSingularity(
       } else {
         player.startWork(Router, companyName);
       }
-      workerScript.log("workForCompany", `Began working at '${player.companyName}' as a '${companyPositionName}'`);
+      workerScript.log(
+        "workForCompany",
+        () => `Began working at '${player.companyName}' as a '${companyPositionName}'`,
+      );
       return true;
     },
     applyToCompany: function (companyName: any, field: any): any {
@@ -870,24 +888,24 @@ export function NetscriptSingularity(
           res = player.applyForPartTimeWaiterJob(true);
           break;
         default:
-          workerScript.log("applyToCompany", `Invalid job: '${field}'.`);
+          workerScript.log("applyToCompany", () => `Invalid job: '${field}'.`);
           return false;
       }
       // TODO https://github.com/danielyxie/bitburner/issues/1378
       // The player object's applyForJob function can return string with special error messages
       // if (isString(res)) {
-      //   workerScript.log("applyToCompany", res);
+      //   workerScript.log("applyToCompany",()=> res);
       //   return false;
       // }
       if (res) {
         workerScript.log(
           "applyToCompany",
-          `You were offered a new job at '${companyName}' as a '${player.jobs[companyName]}'`,
+          () => `You were offered a new job at '${companyName}' as a '${player.jobs[companyName]}'`,
         );
       } else {
         workerScript.log(
           "applyToCompany",
-          `You failed to get a new job/promotion at '${companyName}' in the '${field}' field.`,
+          () => `You failed to get a new job/promotion at '${companyName}' in the '${field}' field.`,
         );
       }
       return res;
@@ -922,7 +940,7 @@ export function NetscriptSingularity(
       getFaction("joinFaction", name);
 
       if (!player.factionInvitations.includes(name)) {
-        workerScript.log("joinFaction", `You have not been invited by faction '${name}'`);
+        workerScript.log("joinFaction", () => `You have not been invited by faction '${name}'`);
         return false;
       }
       const fac = Factions[name];
@@ -936,7 +954,7 @@ export function NetscriptSingularity(
         }
       }
       player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
-      workerScript.log("joinFaction", `Joined the '${name}' faction.`);
+      workerScript.log("joinFaction", () => `Joined the '${name}' faction.`);
       return true;
     },
     workForFaction: function (name: any, type: any): any {
@@ -946,18 +964,18 @@ export function NetscriptSingularity(
 
       // if the player is in a gang and the target faction is any of the gang faction, fail
       if (player.inGang() && AllGangs[name] !== undefined) {
-        workerScript.log("workForFaction", `Faction '${name}' does not offer work at the moment.`);
+        workerScript.log("workForFaction", () => `Faction '${name}' does not offer work at the moment.`);
         return;
       }
 
       if (!player.factions.includes(name)) {
-        workerScript.log("workForFaction", `You are not a member of '${name}'`);
+        workerScript.log("workForFaction", () => `You are not a member of '${name}'`);
         return false;
       }
 
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("workForFaction", txt);
+        workerScript.log("workForFaction", () => txt);
       }
 
       const fac = Factions[name];
@@ -1049,34 +1067,34 @@ export function NetscriptSingularity(
         case "hacking contracts":
         case "hackingcontracts":
           if (!hackAvailable.includes(fac.name)) {
-            workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with hacking contracts.`);
+            workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with hacking contracts.`);
             return false;
           }
           player.startFactionHackWork(Router, fac);
-          workerScript.log("workForFaction", `Started carrying out hacking contracts for '${fac.name}'`);
+          workerScript.log("workForFaction", () => `Started carrying out hacking contracts for '${fac.name}'`);
           return true;
         case "field":
         case "fieldwork":
         case "field work":
           if (!fdWkAvailable.includes(fac.name)) {
-            workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with field missions.`);
+            workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with field missions.`);
             return false;
           }
           player.startFactionFieldWork(Router, fac);
-          workerScript.log("workForFaction", `Started carrying out field missions for '${fac.name}'`);
+          workerScript.log("workForFaction", () => `Started carrying out field missions for '${fac.name}'`);
           return true;
         case "security":
         case "securitywork":
         case "security work":
           if (!scWkAvailable.includes(fac.name)) {
-            workerScript.log("workForFaction", `Faction '${fac.name}' do not need help with security work.`);
+            workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with security work.`);
             return false;
           }
           player.startFactionSecurityWork(Router, fac);
-          workerScript.log("workForFaction", `Started carrying out security work for '${fac.name}'`);
+          workerScript.log("workForFaction", () => `Started carrying out security work for '${fac.name}'`);
           return true;
         default:
-          workerScript.log("workForFaction", `Invalid work type: '${type}`);
+          workerScript.log("workForFaction", () => `Invalid work type: '${type}`);
       }
       return true;
     },
@@ -1104,13 +1122,13 @@ export function NetscriptSingularity(
       const faction = getFaction("donateToFaction", name);
 
       if (typeof amt !== "number" || amt <= 0) {
-        workerScript.log("donateToFaction", `Invalid donation amount: '${amt}'.`);
+        workerScript.log("donateToFaction", () => `Invalid donation amount: '${amt}'.`);
         return false;
       }
       if (player.money < amt) {
         workerScript.log(
           "donateToFaction",
-          `You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`,
+          () => `You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`,
         );
         return false;
       }
@@ -1118,7 +1136,8 @@ export function NetscriptSingularity(
       if (faction.favor < repNeededToDonate) {
         workerScript.log(
           "donateToFaction",
-          `You do not have enough favor to donate to this faction. Have ${faction.favor}, need ${repNeededToDonate}`,
+          () =>
+            `You do not have enough favor to donate to this faction. Have ${faction.favor}, need ${repNeededToDonate}`,
         );
         return false;
       }
@@ -1127,9 +1146,10 @@ export function NetscriptSingularity(
       player.loseMoney(amt, "other");
       workerScript.log(
         "donateToFaction",
-        `${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation(
-          repGain,
-        )} reputation`,
+        () =>
+          `${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation(
+            repGain,
+          )} reputation`,
       );
       return true;
     },
@@ -1139,41 +1159,39 @@ export function NetscriptSingularity(
 
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("createProgram", txt);
+        workerScript.log("createProgram", () => txt);
       }
 
       name = name.toLowerCase();
 
-      let p = null;
-      for (const key in Programs) {
-        if (Programs[key].name.toLowerCase() == name) {
-          p = Programs[key];
-        }
-      }
+      const p = Object.values(Programs).find((p) => p.name.toLowerCase() === name);
 
       if (p == null) {
-        workerScript.log("createProgram", `The specified program does not exist: '${name}`);
+        workerScript.log("createProgram", () => `The specified program does not exist: '${name}`);
         return false;
       }
 
       if (player.hasProgram(p.name)) {
-        workerScript.log("createProgram", `You already have the '${p.name}' program`);
+        workerScript.log("createProgram", () => `You already have the '${p.name}' program`);
         return false;
       }
 
       const create = p.create;
       if (create === null) {
-        workerScript.log("createProgram", `You cannot create the '${p.name}' program`);
+        workerScript.log("createProgram", () => `You cannot create the '${p.name}' program`);
         return false;
       }
 
       if (!create.req(player)) {
-        workerScript.log("createProgram", `Hacking level is too low to create '${p.name}' (level ${create.level} req)`);
+        workerScript.log(
+          "createProgram",
+          () => `Hacking level is too low to create '${p.name}' (level ${create.level} req)`,
+        );
         return false;
       }
 
       player.startCreateProgramWork(Router, p.name, create.time, create.level);
-      workerScript.log("createProgram", `Began creating program: '${name}'`);
+      workerScript.log("createProgram", () => `Began creating program: '${name}'`);
       return true;
     },
     commitCrime: function (crimeRoughName: any): any {
@@ -1182,7 +1200,7 @@ export function NetscriptSingularity(
 
       if (player.isWorking) {
         const txt = player.singularityStopWork();
-        workerScript.log("commitCrime", txt);
+        workerScript.log("commitCrime", () => txt);
       }
 
       // Set Location to slums
@@ -1193,7 +1211,7 @@ export function NetscriptSingularity(
         // couldn't find crime
         throw helper.makeRuntimeErrorMsg("commitCrime", `Invalid crime: '${crimeRoughName}'`);
       }
-      workerScript.log("commitCrime", `Attempting to commit ${crime.name}...`);
+      workerScript.log("commitCrime", () => `Attempting to commit ${crime.name}...`);
       return crime.commit(Router, player, 1, workerScript);
     },
     getCrimeChance: function (crimeRoughName: any): any {
diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts
index 904cb800f..80fa4adb3 100644
--- a/src/NetscriptFunctions/Sleeve.ts
+++ b/src/NetscriptFunctions/Sleeve.ts
@@ -25,7 +25,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
   const checkSleeveNumber = function (func: any, sleeveNumber: any): void {
     if (sleeveNumber >= player.sleeves.length || sleeveNumber < 0) {
       const msg = `Invalid sleeve number: ${sleeveNumber}`;
-      workerScript.log(func, msg);
+      workerScript.log(func, () => msg);
       throw helper.makeRuntimeErrorMsg(`sleeve.${func}`, msg);
     }
   };
diff --git a/src/NetscriptFunctions/StockMarket.ts b/src/NetscriptFunctions/StockMarket.ts
index 2e1b72bd0..a57dc03d9 100644
--- a/src/NetscriptFunctions/StockMarket.ts
+++ b/src/NetscriptFunctions/StockMarket.ts
@@ -315,18 +315,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
       checkTixApiAccess("purchase4SMarketData");
 
       if (player.has4SData) {
-        workerScript.log("purchase4SMarketData", "Already purchased 4S Market Data.");
+        workerScript.log("purchase4SMarketData", () => "Already purchased 4S Market Data.");
         return true;
       }
 
       if (player.money < getStockMarket4SDataCost()) {
-        workerScript.log("purchase4SMarketData", "Not enough money to purchase 4S Market Data.");
+        workerScript.log("purchase4SMarketData", () => "Not enough money to purchase 4S Market Data.");
         return false;
       }
 
       player.has4SData = true;
       player.loseMoney(getStockMarket4SDataCost(), "stock");
-      workerScript.log("purchase4SMarketData", "Purchased 4S Market Data");
+      workerScript.log("purchase4SMarketData", () => "Purchased 4S Market Data");
       return true;
     },
     purchase4SMarketDataTixApi: function () {
@@ -334,18 +334,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
       checkTixApiAccess("purchase4SMarketDataTixApi");
 
       if (player.has4SDataTixApi) {
-        workerScript.log("purchase4SMarketDataTixApi", "Already purchased 4S Market Data TIX API");
+        workerScript.log("purchase4SMarketDataTixApi", () => "Already purchased 4S Market Data TIX API");
         return true;
       }
 
       if (player.money < getStockMarket4STixApiCost()) {
-        workerScript.log("purchase4SMarketDataTixApi", "Not enough money to purchase 4S Market Data TIX API");
+        workerScript.log("purchase4SMarketDataTixApi", () => "Not enough money to purchase 4S Market Data TIX API");
         return false;
       }
 
       player.has4SDataTixApi = true;
       player.loseMoney(getStockMarket4STixApiCost(), "stock");
-      workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API");
+      workerScript.log("purchase4SMarketDataTixApi", () => "Purchased 4S Market Data TIX API");
       return true;
     },
   };
diff --git a/src/NetscriptWorker.ts b/src/NetscriptWorker.ts
index 76cbc573f..3f3e8daee 100644
--- a/src/NetscriptWorker.ts
+++ b/src/NetscriptWorker.ts
@@ -535,7 +535,7 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
     }
 
     killWorkerScript(s);
-    w.log("", "Script finished running");
+    w.log("", () => "Script finished running");
   }).catch(function (w) {
     if (w instanceof Error) {
       dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
@@ -561,9 +561,9 @@ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseS
         msg += errorMsg;
 
         dialogBoxCreate(msg);
-        w.log("", "Script crashed with runtime error");
+        w.log("", () => "Script crashed with runtime error");
       } else {
-        w.log("", "Script killed");
+        w.log("", () => "Script killed");
         return; // Already killed, so stop here
       }
       w.running = false;
@@ -645,7 +645,7 @@ export function runScriptFromScript(
   }
 
   if (typeof scriptname !== "string" || !Array.isArray(args)) {
-    workerScript.log(caller, `Invalid arguments: scriptname='${scriptname} args='${args}'`);
+    workerScript.log(caller, () => `Invalid arguments: scriptname='${scriptname} args='${args}'`);
     console.error(`runScriptFromScript() failed due to invalid arguments`);
     return 0;
   }
@@ -658,14 +658,14 @@ export function runScriptFromScript(
   // Check if the script is already running
   const runningScriptObj = server.getRunningScript(scriptname, args);
   if (runningScriptObj != null) {
-    workerScript.log(caller, `'${scriptname}' is already running on '${server.hostname}'`);
+    workerScript.log(caller, () => `'${scriptname}' is already running on '${server.hostname}'`);
     return 0;
   }
 
   // 'null/undefined' arguments are not allowed
   for (let i = 0; i < args.length; ++i) {
     if (args[i] == null) {
-      workerScript.log(caller, "Cannot execute a script with null/undefined as an argument");
+      workerScript.log(caller, () => "Cannot execute a script with null/undefined as an argument");
       return 0;
     }
   }
@@ -684,19 +684,20 @@ export function runScriptFromScript(
     const ramAvailable = server.maxRam - server.ramUsed;
 
     if (server.hasAdminRights == false) {
-      workerScript.log(caller, `You do not have root access on '${server.hostname}'`);
+      workerScript.log(caller, () => `You do not have root access on '${server.hostname}'`);
       return 0;
     } else if (ramUsage > ramAvailable) {
       workerScript.log(
         caller,
-        `Cannot run script '${scriptname}' (t=${threads}) on '${server.hostname}' because there is not enough available RAM!`,
+        () =>
+          `Cannot run script '${scriptname}' (t=${threads}) on '${server.hostname}' because there is not enough available RAM!`,
       );
       return 0;
     } else {
       // Able to run script
       workerScript.log(
         caller,
-        `'${scriptname}' on '${server.hostname}' with ${threads} threads and args: ${arrayToString(args)}.`,
+        () => `'${scriptname}' on '${server.hostname}' with ${threads} threads and args: ${arrayToString(args)}.`,
       );
       const runningScriptObj = new RunningScript(script, args);
       runningScriptObj.threads = threads;
@@ -706,6 +707,6 @@ export function runScriptFromScript(
     break;
   }
 
-  workerScript.log(caller, `Could not find script '${scriptname}' on '${server.hostname}'`);
+  workerScript.log(caller, () => `Could not find script '${scriptname}' on '${server.hostname}'`);
   return 0;
 }
diff --git a/src/StockMarket/BuyingAndSelling.tsx b/src/StockMarket/BuyingAndSelling.tsx
index 4c68a1740..9ce482f9d 100644
--- a/src/StockMarket/BuyingAndSelling.tsx
+++ b/src/StockMarket/BuyingAndSelling.tsx
@@ -51,7 +51,7 @@ export function buyStock(
   }
   if (stock == null || isNaN(shares)) {
     if (workerScript) {
-      workerScript.log("buyStock", `Invalid arguments: stock='${stock}' shares='${shares}'`);
+      workerScript.log("buyStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
     }
@@ -68,7 +68,8 @@ export function buyStock(
     if (workerScript) {
       workerScript.log(
         "buyStock",
-        `You do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}.`,
+        () =>
+          `You do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}.`,
       );
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate(
@@ -86,9 +87,10 @@ export function buyStock(
     if (workerScript) {
       workerScript.log(
         "buyStock",
-        `Purchasing '${shares + stock.playerShares + stock.playerShortShares}' shares would exceed ${
-          stock.symbol
-        }'s maximum (${stock.maxShares}) number of shares`,
+        () =>
+          `Purchasing '${shares + stock.playerShares + stock.playerShortShares}' shares would exceed ${
+            stock.symbol
+          }'s maximum (${stock.maxShares}) number of shares`,
       );
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate(
@@ -116,7 +118,7 @@ export function buyStock(
       `Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(
         totalPrice,
       )}. ` + `Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`;
-    workerScript.log("buyStock", resultTxt);
+    workerScript.log("buyStock", () => resultTxt);
   } else if (opts.suppressDialog !== true) {
     dialogBoxCreate(
       <>
@@ -146,7 +148,7 @@ export function sellStock(
   // Sanitize/Validate arguments
   if (stock == null || shares < 0 || isNaN(shares)) {
     if (workerScript) {
-      workerScript.log("sellStock", `Invalid arguments: stock='${stock}' shares='${shares}'`);
+      workerScript.log("sellStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate(
         "Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer",
@@ -192,7 +194,7 @@ export function sellStock(
     const resultTxt =
       `Sold ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
       `After commissions, you gained a total of ${numeralWrapper.formatMoney(gains)}.`;
-    workerScript.log("sellStock", resultTxt);
+    workerScript.log("sellStock", () => resultTxt);
   } else if (opts.suppressDialog !== true) {
     dialogBoxCreate(
       <>
@@ -226,7 +228,7 @@ export function shortStock(
   }
   if (stock == null || isNaN(shares)) {
     if (workerScript) {
-      workerScript.log("shortStock", `Invalid arguments: stock='${stock}' shares='${shares}'`);
+      workerScript.log("shortStock", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate(
         "Failed to initiate a short position in a stock. This is probably " +
@@ -245,7 +247,8 @@ export function shortStock(
     if (workerScript) {
       workerScript.log(
         "shortStock",
-        "You do not have enough " +
+        () =>
+          "You do not have enough " +
           "money to purchase this short position. You need " +
           numeralWrapper.formatMoney(totalPrice),
       );
@@ -265,9 +268,10 @@ export function shortStock(
     if (workerScript) {
       workerScript.log(
         "shortStock",
-        `This '${shares + stock.playerShares + stock.playerShortShares}' short shares would exceed ${
-          stock.symbol
-        }'s maximum (${stock.maxShares}) number of shares.`,
+        () =>
+          `This '${shares + stock.playerShares + stock.playerShortShares}' short shares would exceed ${
+            stock.symbol
+          }'s maximum (${stock.maxShares}) number of shares.`,
       );
     } else if (opts.suppressDialog !== true) {
       dialogBoxCreate(
@@ -296,7 +300,7 @@ export function shortStock(
         CONSTANTS.StockMarketCommission,
       )} ` +
       `in commission fees.`;
-    workerScript.log("shortStock", resultTxt);
+    workerScript.log("shortStock", () => resultTxt);
   } else if (!opts.suppressDialog) {
     dialogBoxCreate(
       <>
@@ -325,7 +329,7 @@ export function sellShort(
 ): boolean {
   if (stock == null || isNaN(shares) || shares < 0) {
     if (workerScript) {
-      workerScript.log("sellShort", `Invalid arguments: stock='${stock}' shares='${shares}'`);
+      workerScript.log("sellShort", () => `Invalid arguments: stock='${stock}' shares='${shares}'`);
     } else if (!opts.suppressDialog) {
       dialogBoxCreate(
         "Failed to sell a short position in a stock. This is probably " +
@@ -349,7 +353,7 @@ export function sellShort(
     if (workerScript) {
       workerScript.log(
         "sellShort",
-        `Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug`,
+        () => `Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug`,
       );
     } else if (!opts.suppressDialog) {
       dialogBoxCreate(
@@ -383,7 +387,7 @@ export function sellShort(
     const resultTxt =
       `Sold your short position of ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
       `After commissions, you gained a total of ${numeralWrapper.formatMoney(totalGain)}`;
-    workerScript.log("sellShort", resultTxt);
+    workerScript.log("sellShort", () => resultTxt);
   } else if (!opts.suppressDialog) {
     dialogBoxCreate(
       <>
diff --git a/src/StockMarket/StockMarket.tsx b/src/StockMarket/StockMarket.tsx
index c45064a3a..5debf153e 100644
--- a/src/StockMarket/StockMarket.tsx
+++ b/src/StockMarket/StockMarket.tsx
@@ -37,7 +37,7 @@ export function placeOrder(
 ): boolean {
   if (!(stock instanceof Stock)) {
     if (workerScript) {
-      workerScript.log("placeOrder", `Invalid stock: '${stock}'`);
+      workerScript.log("placeOrder", () => `Invalid stock: '${stock}'`);
     } else {
       dialogBoxCreate(`ERROR: Invalid stock passed to placeOrder() function`);
     }
@@ -45,7 +45,7 @@ export function placeOrder(
   }
   if (typeof shares !== "number" || typeof price !== "number") {
     if (workerScript) {
-      workerScript.log("placeOrder", `Invalid arguments: shares='${shares}' price='${price}'`);
+      workerScript.log("placeOrder", () => `Invalid arguments: shares='${shares}' price='${price}'`);
     } else {
       dialogBoxCreate("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument");
     }