Files
bitburner-src/src/Documentation/doc/en/migrations/ns2.md
T
David Walker 4059be3d8c DOC: Move all docs into en/ subdirectory (#1505)
* DOC: Move all docs into en/ subdirectory

PR #1502 is working on adding a Chinese translation to the docs. In
general, I encouraged this (in #1452) as a path towards getting useful
translated content in the game without requiring a massive
refactor/rearchitecting of everything.

To support this, this takes the first step of moving our docs into an
en/ subdirectory, so that other languages can live alongside. No effort
is made at this time to support or select between alternate languages;
this is a pure-rename refactor.
2025-07-19 19:15:56 -07:00

3.5 KiB

"Netscript 2" Migration Guide

In previous versions, the game supported two script formats:

  • .script (also sometimes called "Netscript 1" or "NS1") files are ran through an interpreter that is based on a version of Javascript from 2009 (ES5).

  • .js (also sometimes called "Netscript 2" or "NS2") files are native javascript that is ran directly by the web browser. Modern features of javascript that are supported by your web browser are supported in .js files, because they are run as native js.

Support for running .script files was removed in version 3.0.

Why do I have to change anything?

Since all ES5 code is still valid Javascript, you may be wondering why the old code doesn't just work when renamed to .js. In this section, some key differences are explained.

  • API access method: In .script files, the game API is available at top-level scope within the file, as if they were at global scope. In .js files, the game API is passed as an argument into a script's main function, and is not available at top-level scope.
  • Execution differences: Running a .script file begins code execution at the top of the file. Running a .js file launches the main function (passing the game API in as the first argument, typically named ns).
  • Timing differences: In .script files, code execution contains automatic delays between every statement. In .js files, the code is being run natively so there are no builtin delays, so any needed delays must be added manually.

Basic steps for script migration

  1. Wrap the entire script inside of an exported main function, like so:
/** @param {NS} ns */
export async function main(ns) {
  // your code here
}
  1. Add ns. as a prefix to all game functions or objects (such as ns.hack() or ns.args).
  2. If a function returns a Promise, you need to put the await keyword before it (With the JSDoc comment you can hover over the function to see the return type). Note that only functions declared as async are allowed to await anything, and typically you should also await the calls to your own async functions.
  3. Because there are no forced delays, an infinite loop will cause the game to hang if a delay is not manually added. Such loops should await a function (usually ns.sleep()) at least once to avoid this.
  4. The var keyword is rarely used in modern js for declaring variables. let or const (if the variable is never reassigned) keywords are preferred. This change is not required.

Example migration

Original (early-hacking-template.script):

var target = "n00dles";
var moneyThresh = getServerMaxMoney(target) * 0.9;
var securityThresh = getServerMinSecurityLevel(target) + 5;

while (true) {
  if (getServerSecurityLevel(target) > securityThresh) {
    weaken(target);
  } else if (getServerMoneyAvailable(target) < moneyThresh) {
    grow(target);
  } else {
    hack(target);
  }
}

Migrated (early-hacking-template.js):

/** @param {NS} ns */
export async function main(ns) {
  const target = "n00dles";
  const moneyThresh = ns.getServerMaxMoney(target) * 0.9;
  const securityThresh = ns.getServerMinSecurityLevel(target) + 5;

  while (true) {
    if (ns.getServerSecurityLevel(target) > securityThresh) {
      await ns.weaken(target);
    } else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
      await ns.grow(target);
    } else {
      await ns.hack(target);
    }
  }
}

Additional problems or edge cases

To get additional help with the migration, please join the official Discord server.