NETSCRIPT: Add ramOverride() function (#1346)

This adds a way to dynamically change the static RAM limit of a script,
which is also its current RAM usage. This makes it possible for scripts
to dynamically change their memory footprint, opening up new strategies
beyond current ram-dodging.

Calling functions still permanently increases the *dynamic* memory
limit; RAM-dodging is still the optimal strategy for avoiding RAM costs,
in that sense.

This also adds dynamicRamUsage to the info returned by
`getRunningScript`, to allow introspection on the currently needed ram.
This commit is contained in:
David Walker
2024-06-28 18:42:20 -07:00
committed by GitHub
parent 1c20a24079
commit 9c9a69f2e2
9 changed files with 119 additions and 5 deletions
+6 -1
View File
@@ -1,5 +1,6 @@
import type { NetscriptContext } from "./APIWrapper";
import type { RunningScript as IRunningScript, Person as IPerson, Server as IServer, ScriptArg } from "@nsdefs";
import type { WorkerScript } from "./WorkerScript";
import React from "react";
import { killWorkerScript } from "./killWorkerScript";
@@ -336,6 +337,9 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
ws.dynamicRamUsage = Math.min(ws.dynamicRamUsage + ramCost, RamCostConstants.Max);
// This constant is just a handful of ULPs, and gives protection against
// rounding issues without exposing rounding exploits in ramUsage.
// Most RAM calculations are guarded with roundToTwo(), but we use direct
// addition and this multiplication here for speed, since dynamic RAM
// checking is a speed-critical component.
if (ws.dynamicRamUsage > 1.00000000000001 * ws.scriptRef.ramUsage) {
log(ctx, () => "Insufficient static ram available.");
const functionsUsed = Object.keys(ws.dynamicLoadedFns).join(", ");
@@ -671,10 +675,11 @@ function getCannotFindRunningScriptErrorMessage(ident: ScriptIdentifier): string
* @param runningScript Existing, internal RunningScript
* @returns A sanitized, NS-facing copy of the RunningScript
*/
function createPublicRunningScript(runningScript: RunningScript): IRunningScript {
function createPublicRunningScript(runningScript: RunningScript, workerScript?: WorkerScript): IRunningScript {
const logProps = runningScript.tailProps;
return {
args: runningScript.args.slice(),
dynamicRamUsage: workerScript && roundToTwo(workerScript.dynamicRamUsage),
filename: runningScript.filename,
logs: runningScript.logs.map((x) => "" + x),
offlineExpGained: runningScript.offlineExpGained,