2018-06-14 21:51:06 +02:00
.. _netscriptjs:
2021-11-05 20:43:38 +01:00
NS2
===
The improved version of Netscript that
2021-11-04 01:27:32 +01:00
allows users to write full-fledged Javascript code in their scripts, while
2018-05-17 19:10:12 +02:00
still being able to access the Netscript functions.
2021-11-05 20:43:38 +01:00
ns2 was developed primarily by `Github user jaguilar <https://github.com/jaguilar> `_
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
On top of having almost all of the features and capabilities of JavaScript, ns2 is also
significantly faster than ns1.
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
This documentation will not go over any of the additional features of ns2, since
2018-05-17 19:10:12 +02:00
there is plenty of documentation on Javascript available on the web.
2018-12-12 21:18:13 +01:00
Browser compatibility
---------------------
2021-11-05 20:43:38 +01:00
As of the time of writing this, a few browsers do not support `dynamic import <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import> `_ functionality and therefore cannot run ns2 scripts. These browsers will thus only be capable of using ns1.
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
How to use ns2
2018-05-17 19:10:12 +02:00
----------------------
2021-11-05 20:43:38 +01:00
Working with ns2 scripts is the same as ns1 scripts. The only difference
2022-01-07 18:25:17 +01:00
is that ns2 scripts use the ".js" extension rather than ".script". E.g.::
2018-05-17 19:10:12 +02:00
2022-01-07 18:25:17 +01:00
$ nano foo.js
$ run foo.js -t 100 arg1 arg2 arg3
exec("foo.js", "purchasedServer1", "100", "randomArg");
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
The caveat when using ns2 to write scripts is that your code must be
2018-05-17 19:10:12 +02:00
asynchronous. Furthermore, instead of using the global scope and executing your code
2021-11-05 20:43:38 +01:00
sequentially, ns2 uses a :code: `main()` function as an entry point.
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
Furthermore, the "Netscript environment" must be passed into a ns2 script through
2018-05-17 19:10:12 +02:00
the main function. This environment includes all of the pre-defined Netscript functions
(:code: `hack()` , :code: `exec` , etc.) as well as the arguments you pass to the script.
Therefore, the signature of the :code: `main()` function must be::
export async function main(ns) {
ns.print("Starting script here");
2018-05-18 17:42:49 +02:00
await ns.hack("foodnstuff"); //Use Netscript hack function
ns.print(ns.args); //The script arguments must be prefaced with ns as well
2018-05-17 19:10:12 +02:00
}
Here is a summary of all rules you need to follow when writing Netscript JS code:
* Write :code: `await` before any call to the following Netscript functions:
* hack
* grow
* weaken
* sleep
2022-10-04 13:59:50 +02:00
* asleep
2018-05-17 19:10:12 +02:00
* prompt
2018-09-28 06:19:52 +02:00
* wget
2018-05-17 19:10:12 +02:00
* Any function that contains :code: `await` must be declared as :code: `async`
* Always :code: `await` any function that is marked as :code: `async`
* Any functions that you want to be visible from other scripts must be marked with :code: `export` .
2021-11-04 01:27:32 +01:00
* **Do not write any infinite loops without using a** :code: `sleep` **or one of the timed Netscript functions like** :code: `hack` . Doing so will freeze your game.
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
* Any global variable declared in a ns2 script is shared between all instances of that
2022-01-07 18:25:17 +01:00
script. For example, assume you write a script *foo.js* and declared a global variable like so::
2018-05-17 19:10:12 +02:00
2022-01-07 18:25:17 +01:00
//foo.js
2018-05-17 19:10:12 +02:00
let globalVariable;
export async function main(ns) {
globalVariable = ns.args.length;
while(true) {
2018-05-18 17:42:49 +02:00
ns.tprint(globalVariable);
await ns.sleep(3000);
2018-05-17 19:10:12 +02:00
}
}
2022-01-07 18:25:17 +01:00
Then, you ran multiple instances of *foo.js* ::
2018-05-17 19:10:12 +02:00
2022-01-07 18:25:17 +01:00
$ run foo.js 1
$ run foo.js 1 2 3
$ run foo.js 1 2 3 4 5
2018-05-17 19:10:12 +02:00
2022-01-07 18:25:17 +01:00
Then all three instances of foo.js will share the same instance of :code: `globalVariable` .
2018-05-17 19:10:12 +02:00
(In this example, the value of :code: `globalVariable` will be set to 5 because the
2022-01-07 18:25:17 +01:00
last instance of *foo.js* to run has 5 arguments. This means that all three instances of
2018-05-17 19:10:12 +02:00
the script will repeatedly print the value 5).
These global variables can be thought of as `C++ static class members <https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm> `_ ,
2021-11-05 20:43:38 +01:00
where a ns2 script is a class and a global variable is a static member within that class.
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
Example
-------
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
early-hack-template.script
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
.. code-block :: javascript
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
var target = args[0];
var moneyThresh = getServerMaxMoney(target) * 0.75;
var securityThresh = getServerMinSecurityLevel(target) + 5;
if (fileExists("BruteSSH.exe", "home")) {
brutessh(target);
2018-05-17 19:10:12 +02:00
}
2021-11-05 20:43:38 +01:00
nuke(target);
while(true) {
if (getServerSecurityLevel(target) > securityThresh) {
weaken(target);
} else if (getServerMoneyAvailable(target) < moneyThresh) {
grow(target);
} else {
hack(target);
2021-07-02 23:31:07 +02:00
}
2018-05-17 19:10:12 +02:00
}
2022-01-07 18:25:17 +01:00
early-hack-template.js
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
.. code-block :: javascript
2018-05-17 19:10:12 +02:00
export async function main(ns) {
2021-11-05 20:43:38 +01:00
var target = ns.args[0];
var moneyThresh = ns.getServerMaxMoney(target) * 0.75;
var securityThresh = ns.getServerMinSecurityLevel(target) + 5;
if (ns.fileExists("BruteSSH.exe", "home")) {
ns.brutessh(target);
}
ns.nuke(target);
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);
}
2018-05-17 19:10:12 +02:00
}
}
2021-11-05 20:43:38 +01:00
What's with the weird comment
-----------------------------
You may have noticed that every new ns2 file will contains the following comment.
.. code-block :: javascript
2022-10-04 13:59:50 +02:00
/** @param {NS} ns * /
2021-11-05 20:43:38 +01:00
2022-01-07 18:25:17 +01:00
This comment is used to help the text editor autocomplete functions in the Netscript API. You can enable it by pressing ctrl+space after `ns.`
2018-05-17 19:10:12 +02:00
2021-11-05 20:43:38 +01:00
.. image :: autocomplete.png
2018-05-17 19:10:12 +02:00
2022-01-07 18:25:17 +01:00
The comment can be safely removed but it is recommended to keep it as it will help you.