mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-21 23:23:51 +01:00
Tutorial: Remove NS1 tutorial, change getting started guide to .js (#258)
This commit is contained in:
parent
b004b7203d
commit
addcee73fc
@ -28,7 +28,7 @@ entire "quest-line".
|
||||
First Steps
|
||||
-----------
|
||||
I'm going to assume you followed the introductory tutorial when you first began the game.
|
||||
In this introductory tutorial you created a script called :code:`n00dles.script` and ran it
|
||||
In this introductory tutorial you created a script called :code:`n00dles.js` and ran it
|
||||
on the :code:`n00dles` server. Right now, we'll kill this script. There are two ways
|
||||
to do this:
|
||||
|
||||
@ -37,7 +37,7 @@ to do this:
|
||||
$ kill n00dles.script
|
||||
|
||||
2. You can go to the :code:`Active Scripts` page (|Keyboard shortcut| Alt + s) and
|
||||
press the "Kill Script" button for :code:`n00dles.script`.
|
||||
press the "Kill Script" button for :code:`n00dles.js`.
|
||||
|
||||
If you skipped the introductory tutorial, then ignore the part above. Instead, go to the
|
||||
:code:`Hacknet Nodes` page (|Keyboard shortcut| Alt + h) and purchase a
|
||||
@ -67,11 +67,11 @@ the amount of money available on a server. The :js:func:`weaken` Netscript funct
|
||||
used to decrease a server's security level.
|
||||
|
||||
Now let's move on to actually creating the script.
|
||||
Go to your home computer and then create a script called :code:`early-hack-template.script` by
|
||||
Go to your home computer and then create a script called :code:`early-hack-template.js` by
|
||||
going to Terminal and entering the following two commands::
|
||||
|
||||
$ home
|
||||
$ nano early-hack-template.script
|
||||
$ nano early-hack-template.js
|
||||
|
||||
This will take you to the script editor, which you can use to code and create
|
||||
:ref:`gameplay_scripts`. It will be helpful to consult the :ref:`netscript` documentation.
|
||||
@ -80,49 +80,50 @@ Specifically, you'll want to take a look at :ref:`netscriptfunctions`.
|
||||
Enter the following code in the script editor:
|
||||
|
||||
.. code:: javascript
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
// Defines the "target server", which is the server
|
||||
// that we're going to hack. In this case, it's "n00dles"
|
||||
const target = "n00dles";
|
||||
|
||||
// Defines the "target server", which is the server
|
||||
// that we're going to hack. In this case, it's "n00dles"
|
||||
var target = "n00dles";
|
||||
// Defines how much money a server should have before we hack it
|
||||
// In this case, it is set to 75% of the server's max money
|
||||
const moneyThresh = ns.getServerMaxMoney(target) * 0.75;
|
||||
|
||||
// Defines how much money a server should have before we hack it
|
||||
// In this case, it is set to 75% of the server's max money
|
||||
var moneyThresh = getServerMaxMoney(target) * 0.75;
|
||||
// Defines the maximum security level the target server can
|
||||
// have. If the target's security level is higher than this,
|
||||
// we'll weaken it before doing anything else
|
||||
const securityThresh = ns.getServerMinSecurityLevel(target) + 5;
|
||||
|
||||
// Defines the maximum security level the target server can
|
||||
// have. If the target's security level is higher than this,
|
||||
// we'll weaken it before doing anything else
|
||||
var securityThresh = getServerMinSecurityLevel(target) + 5;
|
||||
// If we have the BruteSSH.exe program, use it to open the SSH Port
|
||||
// on the target server
|
||||
if (ns.fileExists("BruteSSH.exe", "home")) {
|
||||
ns.brutessh(target);
|
||||
}
|
||||
|
||||
// If we have the BruteSSH.exe program, use it to open the SSH Port
|
||||
// on the target server
|
||||
if (fileExists("BruteSSH.exe", "home")) {
|
||||
brutessh(target);
|
||||
}
|
||||
// Get root access to target server
|
||||
ns.nuke(target);
|
||||
|
||||
// Get root access to target server
|
||||
nuke(target);
|
||||
|
||||
// Infinite loop that continously hacks/grows/weakens the target server
|
||||
while(true) {
|
||||
if (getServerSecurityLevel(target) > securityThresh) {
|
||||
// If the server's security level is above our threshold, weaken it
|
||||
weaken(target);
|
||||
} else if (getServerMoneyAvailable(target) < moneyThresh) {
|
||||
// If the server's money is less than our threshold, grow it
|
||||
grow(target);
|
||||
} else {
|
||||
// Otherwise, hack it
|
||||
hack(target);
|
||||
// Infinite loop that continously hacks/grows/weakens the target server
|
||||
while(true) {
|
||||
if (ns.getServerSecurityLevel(target) > securityThresh) {
|
||||
// If the server's security level is above our threshold, weaken it
|
||||
await ns.weaken(target);
|
||||
} else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
|
||||
// If the server's money is less than our threshold, grow it
|
||||
await ns.grow(target);
|
||||
} else {
|
||||
// Otherwise, hack it
|
||||
await ns.hack(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The script above contains comments that document what it does, but let's go through it
|
||||
step-by-step anyways.
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
var target = "n00dles";
|
||||
const target = "n00dles";
|
||||
|
||||
This first command defines a string which contains our target server. That's the server
|
||||
that we're going to hack. For now, it's set to `n00dles` because that's the only
|
||||
@ -132,7 +133,7 @@ variable to be the hostname of another server.
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
var moneyThresh = getServerMaxMoney(target) * 0.75;
|
||||
const moneyThresh = ns.getServerMaxMoney(target) * 0.75;
|
||||
|
||||
This second command defines a numerical value representing the minimum
|
||||
amount of money that must be available on the target server in order for our script
|
||||
@ -143,7 +144,7 @@ The :js:func:`getServerMaxMoney` Netscript function is used to find this value
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
var securityThresh = getServerMinSecurityLevel(target) + 5;
|
||||
const securityThresh = ns.getServerMinSecurityLevel(target) + 5;
|
||||
|
||||
This third command defines a numerical value representing the maximum security level
|
||||
the target server can have. If the target server's security level is higher than
|
||||
@ -151,11 +152,11 @@ this value, then our script will :js:func:`weaken` the script before doing anyth
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
if (fileExists("BruteSSH.exe", "home")) {
|
||||
brutessh(target);
|
||||
if (ns.fileExists("BruteSSH.exe", "home")) {
|
||||
ns.brutessh(target);
|
||||
}
|
||||
|
||||
nuke(target);
|
||||
ns.nuke(target);
|
||||
|
||||
This section of code is used to gain root access on the target server. This is
|
||||
necessary for hacking. See :ref:`here for more details <gameplay_hacking>`.
|
||||
@ -163,15 +164,15 @@ necessary for hacking. See :ref:`here for more details <gameplay_hacking>`.
|
||||
.. code:: javascript
|
||||
|
||||
while (true) {
|
||||
if (getServerSecurityLevel(target) > securityThresh) {
|
||||
if (ns.getServerSecurityLevel(target) > securityThresh) {
|
||||
// If the server's security level is above our threshold, weaken it
|
||||
weaken(target);
|
||||
} else if (getServerMoneyAvailable(target) < moneyThresh) {
|
||||
await ns.weaken(target);
|
||||
} else if (ns.getServerMoneyAvailable(target) < moneyThresh) {
|
||||
// Otherwise, if the server's money is less than our threshold, grow it
|
||||
grow(target);
|
||||
await ns.grow(target);
|
||||
} else {
|
||||
// Otherwise, hack it
|
||||
hack(target);
|
||||
await ns.hack(target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,6 +180,12 @@ This is the main section that drives our script. It dictates the script's logic
|
||||
and carries out the hacking operations. The `while (true)` creates an infinite loop
|
||||
that will continuously run the hacking logic until the the script is killed.
|
||||
|
||||
The await keyword is needed for `hack` / `grow` / `weaken` because these commands take
|
||||
time to execute, unlike the others. If you forget to await these commands, you will get
|
||||
an exception saying you tried to do multiple things at once, because your code will
|
||||
immediately finish the function call without waiting for the operation to be done. Also
|
||||
important is that await can only be used in functions marked async (which main() is).
|
||||
|
||||
Running our Scripts
|
||||
-------------------
|
||||
Now we want to start running our hacking script so that it can start earning us
|
||||
@ -268,7 +275,7 @@ First, let's determine how many threads of our hacking script we can run.
|
||||
The script we wrote
|
||||
uses 2.6GB of RAM. You can check this using the following |Terminal| command::
|
||||
|
||||
$ mem early-hack-template.script
|
||||
$ mem early-hack-template.js
|
||||
|
||||
This means we can run 6 threads on a 16GB server. Now, to run our scripts on all of these
|
||||
servers, we have to do the following:
|
||||
@ -283,36 +290,36 @@ servers, we have to do the following:
|
||||
Here's the sequence of |Terminal| commands I used in order to achieve this::
|
||||
|
||||
$ home
|
||||
$ scp early-hack-template.script n00dles
|
||||
$ scp early-hack-template.script sigma-cosmetics
|
||||
$ scp early-hack-template.script joesguns
|
||||
$ scp early-hack-template.script nectar-net
|
||||
$ scp early-hack-template.script hong-fang-tea
|
||||
$ scp early-hack-template.script harakiri-sushi
|
||||
$ scp early-hack-template.js n00dles
|
||||
$ scp early-hack-template.js sigma-cosmetics
|
||||
$ scp early-hack-template.js joesguns
|
||||
$ scp early-hack-template.js nectar-net
|
||||
$ scp early-hack-template.js hong-fang-tea
|
||||
$ scp early-hack-template.js harakiri-sushi
|
||||
$ connect n00dles
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 1
|
||||
$ run early-hack-template.js -t 1
|
||||
$ home
|
||||
$ connect sigma-cosmetics
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 6
|
||||
$ run early-hack-template.js -t 6
|
||||
$ home
|
||||
$ connect joesguns
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 6
|
||||
$ run early-hack-template.js -t 6
|
||||
$ home
|
||||
$ connect hong-fang-tea
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 6
|
||||
$ run early-hack-template.js -t 6
|
||||
$ home
|
||||
$ connect harakiri-sushi
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 6
|
||||
$ run early-hack-template.js -t 6
|
||||
$ home
|
||||
$ connect hong-fang-tea
|
||||
$ connect nectar-net
|
||||
$ run NUKE.exe
|
||||
$ run early-hack-template.script -t 6
|
||||
$ run early-hack-template.js -t 6
|
||||
|
||||
.. note::
|
||||
|
||||
@ -322,7 +329,7 @@ Here's the sequence of |Terminal| commands I used in order to achieve this::
|
||||
This works for most commands in the game!
|
||||
|
||||
The :ref:`home_terminal_command` |Terminal| command is used to connect to the home
|
||||
computer. When running our scripts with the :code:`run early-hack-template.script -t 6`
|
||||
computer. When running our scripts with the :code:`run early-hack-template.js -t 6`
|
||||
command, the :code:`-t 6` specifies that the script should be run with 6 threads.
|
||||
|
||||
Note that the |nectar-net| server isn't in the home computer's immediate network.
|
||||
@ -371,13 +378,13 @@ script to target :code:`joesguns` instead of :code:`n00dles`.
|
||||
Go to |Terminal| and edit the hacking script by entering::
|
||||
|
||||
$ home
|
||||
$ nano early-hack-template.script
|
||||
$ nano early-hack-template.js
|
||||
|
||||
At the top of the script, change the `target` variable to be `joesguns`:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
var target = "joesguns";
|
||||
const target = "joesguns";
|
||||
|
||||
Note that this will **NOT** affect any instances of the script that are already running.
|
||||
This will only affect instances of the script that are ran from this point forward.
|
||||
@ -401,33 +408,38 @@ Netscript functions:
|
||||
Create the script by going to |Terminal| and typing::
|
||||
|
||||
$ home
|
||||
$ nano purchase-server-8gb.script
|
||||
$ nano purchase-server-8gb.js
|
||||
|
||||
Paste the following code into the script editor:
|
||||
|
||||
.. code:: javascript
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
// How much RAM each purchased server will have. In this case, it'll
|
||||
// be 8GB.
|
||||
const ram = 8;
|
||||
|
||||
// How much RAM each purchased server will have. In this case, it'll
|
||||
// be 8GB.
|
||||
var ram = 8;
|
||||
// Iterator we'll use for our loop
|
||||
let i = 0;
|
||||
|
||||
// Iterator we'll use for our loop
|
||||
var i = 0;
|
||||
|
||||
// Continuously try to purchase servers until we've reached the maximum
|
||||
// amount of servers
|
||||
while (i < getPurchasedServerLimit()) {
|
||||
// Check if we have enough money to purchase a server
|
||||
if (getServerMoneyAvailable("home") > getPurchasedServerCost(ram)) {
|
||||
// If we have enough money, then:
|
||||
// 1. Purchase the server
|
||||
// 2. Copy our hacking script onto the newly-purchased server
|
||||
// 3. Run our hacking script on the newly-purchased server with 3 threads
|
||||
// 4. Increment our iterator to indicate that we've bought a new server
|
||||
var hostname = purchaseServer("pserv-" + i, ram);
|
||||
scp("early-hack-template.script", hostname);
|
||||
exec("early-hack-template.script", hostname, 3);
|
||||
++i;
|
||||
// Continuously try to purchase servers until we've reached the maximum
|
||||
// amount of servers
|
||||
while (i < ns.getPurchasedServerLimit()) {
|
||||
// Check if we have enough money to purchase a server
|
||||
if (ns.getServerMoneyAvailable("home") > ns.getPurchasedServerCost(ram)) {
|
||||
// If we have enough money, then:
|
||||
// 1. Purchase the server
|
||||
// 2. Copy our hacking script onto the newly-purchased server
|
||||
// 3. Run our hacking script on the newly-purchased server with 3 threads
|
||||
// 4. Increment our iterator to indicate that we've bought a new server
|
||||
let hostname = ns.purchaseServer("pserv-" + i, ram);
|
||||
ns.scp("early-hack-template.script", hostname);
|
||||
ns.exec("early-hack-template.script", hostname, 3);
|
||||
++i;
|
||||
}
|
||||
//Make the script wait for a second before looping again.
|
||||
//Removing this line will cause an infinite loop and crash the game.
|
||||
await ns.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +455,7 @@ execute it on that server.
|
||||
|
||||
To run this script, go to |Terminal| and type::
|
||||
|
||||
$ run purchase-server-8gb.script
|
||||
$ run purchase-server-8gb.js
|
||||
|
||||
This purchase will continuously run until it has purchased the maximum number of servers.
|
||||
When this happens, it'll mean that you have a bunch of new servers that are all running
|
||||
@ -540,7 +552,7 @@ finish running. This will free up some RAM on your home computer. We don't want
|
||||
to go to waste, so we'll make use of it. Go to |Terminal| and enter the following commands::
|
||||
|
||||
$ home
|
||||
$ run early-hack-template.script -t 3
|
||||
$ run early-hack-template.js -t 3
|
||||
|
||||
Reaching a Hacking Level of 50
|
||||
------------------------------
|
||||
@ -680,10 +692,10 @@ All of these servers have 32GB of RAM. You can use the |Terminal| command
|
||||
go to |Terminal| and run::
|
||||
|
||||
$ home
|
||||
$ scp early-hack-template.script neo-net
|
||||
$ scp early-hack-template.script zer0
|
||||
$ scp early-hack-template.script max-hardware
|
||||
$ scp early-hack-template.script iron-gym
|
||||
$ scp early-hack-template.js neo-net
|
||||
$ scp early-hack-template.js zer0
|
||||
$ scp early-hack-template.js max-hardware
|
||||
$ scp early-hack-template.js iron-gym
|
||||
|
||||
Since each of these servers has 32GB of RAM, we can run our hacking script with 12 threads
|
||||
on each server. By now, you should know how to connect to servers. So find and connect to
|
||||
@ -691,7 +703,7 @@ each of the servers above using the :code:`scan-analyze 3` |Terminal| command. T
|
||||
following |Terminal| command to run our hacking
|
||||
script with 12 threads::
|
||||
|
||||
$ run early-hack-template.script -t 12
|
||||
$ run early-hack-template.js -t 12
|
||||
|
||||
Remember that if you have the |AutoLink| program, you can simply click on the hostname of a server
|
||||
after running :ref:`scan_analyze_terminal_command` to connect to it.
|
||||
@ -766,7 +778,7 @@ much more money, and then you can come back later on and get all these Augmentat
|
||||
|
||||
Right now, I suggest purchasing at the very least the :code:`Neurotrainer I` Augmentation from
|
||||
|CyberSec|. If you have the money to spare, I would also suggest getting :code:`BitWire` and
|
||||
several levels of the :code:`NeuroFlux Governor` Augmentations. Note that each time
|
||||
several levels of the :code:`NeuroFlux Governor` (:code:`NFG`) Augmentations. Note that each time
|
||||
you purchase an Augmentation,
|
||||
:ref:`the price of purchasing another increases by 90% <gameplay_augmentations_purchasingmultiple>`,
|
||||
so make sure you buy the most expensive Augmentation first. Don't worry, once you choose to
|
||||
@ -803,50 +815,51 @@ so you should write a script to automate the process. Here's a simple example fo
|
||||
startup script. Feel free to adjust it to your liking.
|
||||
|
||||
.. code:: javascript
|
||||
/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
// Array of all servers that don't need any ports opened
|
||||
// to gain root access. These have 16 GB of RAM
|
||||
const servers0Port = ["sigma-cosmetics",
|
||||
"joesguns",
|
||||
"nectar-net",
|
||||
"hong-fang-tea",
|
||||
"harakiri-sushi"];
|
||||
|
||||
// Array of all servers that don't need any ports opened
|
||||
// to gain root access. These have 16 GB of RAM
|
||||
var servers0Port = ["sigma-cosmetics",
|
||||
"joesguns",
|
||||
"nectar-net",
|
||||
"hong-fang-tea",
|
||||
"harakiri-sushi"];
|
||||
// Array of all servers that only need 1 port opened
|
||||
// to gain root access. These have 32 GB of RAM
|
||||
const servers1Port = ["neo-net",
|
||||
"zer0",
|
||||
"max-hardware",
|
||||
"iron-gym"];
|
||||
|
||||
// Array of all servers that only need 1 port opened
|
||||
// to gain root access. These have 32 GB of RAM
|
||||
var servers1Port = ["neo-net",
|
||||
"zer0",
|
||||
"max-hardware",
|
||||
"iron-gym"];
|
||||
// Copy our scripts onto each server that requires 0 ports
|
||||
// to gain root access. Then use nuke() to gain admin access and
|
||||
// run the scripts.
|
||||
for (let i = 0; i < servers0Port.length; ++i) {
|
||||
const serv = servers0Port[i];
|
||||
|
||||
// Copy our scripts onto each server that requires 0 ports
|
||||
// to gain root access. Then use nuke() to gain admin access and
|
||||
// run the scripts.
|
||||
for (var i = 0; i < servers0Port.length; ++i) {
|
||||
var serv = servers0Port[i];
|
||||
ns.scp("early-hack-template.script", serv);
|
||||
ns.nuke(serv);
|
||||
ns.exec("early-hack-template.script", serv, 6);
|
||||
}
|
||||
|
||||
scp("early-hack-template.script", serv);
|
||||
nuke(serv);
|
||||
exec("early-hack-template.script", serv, 6);
|
||||
// Wait until we acquire the "BruteSSH.exe" program
|
||||
while (!ns.fileExists("BruteSSH.exe")) {
|
||||
await ns.sleep(60000);
|
||||
}
|
||||
|
||||
// Copy our scripts onto each server that requires 1 port
|
||||
// to gain root access. Then use brutessh() and nuke()
|
||||
// to gain admin access and run the scripts.
|
||||
for (let i = 0; i < servers1Port.length; ++i) {
|
||||
const serv = servers1Port[i];
|
||||
|
||||
ns.scp("early-hack-template.script", serv);
|
||||
ns.brutessh(serv);
|
||||
ns.nuke(serv);
|
||||
ns.exec("early-hack-template.script", serv, 12);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until we acquire the "BruteSSH.exe" program
|
||||
while (!fileExists("BruteSSH.exe")) {
|
||||
sleep(60000);
|
||||
}
|
||||
|
||||
// Copy our scripts onto each server that requires 1 port
|
||||
// to gain root access. Then use brutessh() and nuke()
|
||||
// to gain admin access and run the scripts.
|
||||
for (var i = 0; i < servers1Port.length; ++i) {
|
||||
var serv = servers1Port[i];
|
||||
|
||||
scp("early-hack-template.script", serv);
|
||||
brutessh(serv);
|
||||
nuke(serv);
|
||||
exec("early-hack-template.script", serv, 12);
|
||||
}
|
||||
|
||||
Random Tips
|
||||
-----------
|
||||
* Early on in the game, it's better to spend your money on upgrading RAM and purchasing
|
||||
@ -861,7 +874,7 @@ Random Tips
|
||||
as useful as your hacking stat. Do not invest too much time or money into gaining combat
|
||||
stat exp.
|
||||
* As a rule of thumb, your hacking target should be the server with highest max money that's
|
||||
required hacking level is under 1/3 of your hacking level.
|
||||
required hacking level is under 1/2 of your hacking level.
|
||||
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@ import { ITutorialEvents } from "./ui/InteractiveTutorial/ITutorialEvents";
|
||||
// Ordered array of keys to Interactive Tutorial Steps
|
||||
enum iTutorialSteps {
|
||||
Start,
|
||||
NSSelection,
|
||||
GoToCharacterPage, // Click on 'Stats' page
|
||||
CharacterPage, // Introduction to 'Stats' page
|
||||
CharacterGoToTerminalPage, // Go back to Terminal
|
||||
@ -46,7 +45,6 @@ const ITutorial = {
|
||||
// Keeps track of whether each step has been done
|
||||
stepIsDone: {
|
||||
[iTutorialSteps.Start]: false,
|
||||
[iTutorialSteps.NSSelection]: false,
|
||||
[iTutorialSteps.GoToCharacterPage]: false,
|
||||
[iTutorialSteps.CharacterPage]: false,
|
||||
[iTutorialSteps.CharacterGoToTerminalPage]: false,
|
||||
|
@ -139,7 +139,7 @@ const Messages: Record<MessageFilenames, Message> = {
|
||||
|
||||
[MessageFilenames.Jumper1]: new Message(
|
||||
MessageFilenames.Jumper1,
|
||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
||||
`Soon you will be contacted by a hacking group known as ${FactionNames.CyberSec}. ` +
|
||||
"They can help you with your search. \n\n" +
|
||||
"You should join them, garner their favor, and " +
|
||||
"exploit them for their Augmentations. But do not trust them. " +
|
||||
|
@ -9,7 +9,6 @@ import ArrowBackIos from "@mui/icons-material/ArrowBackIos";
|
||||
import { ITutorialEvents } from "./ITutorialEvents";
|
||||
import { CopyableText } from "../React/CopyableText";
|
||||
|
||||
import List from "@mui/material/List";
|
||||
import ListItem from "@mui/material/ListItem";
|
||||
import EqualizerIcon from "@mui/icons-material/Equalizer";
|
||||
import LastPageIcon from "@mui/icons-material/LastPage";
|
||||
@ -28,7 +27,6 @@ import {
|
||||
iTutorialSteps,
|
||||
iTutorialEnd,
|
||||
} from "../../InteractiveTutorial";
|
||||
import { NSSelection } from "./NSSelection";
|
||||
|
||||
interface IContent {
|
||||
content: React.ReactElement;
|
||||
@ -47,23 +45,10 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
}),
|
||||
);
|
||||
|
||||
enum Language {
|
||||
None,
|
||||
NS1,
|
||||
NS2,
|
||||
}
|
||||
|
||||
export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
const [nsSelectionOpen, setNSSelectionOpen] = useState(false);
|
||||
const [language, setLanguage] = useState(Language.None);
|
||||
const classes = useStyles();
|
||||
|
||||
const tutorialScriptExtension = {
|
||||
[Language.None]: ".script",
|
||||
[Language.NS1]: ".script",
|
||||
[Language.NS2]: ".js",
|
||||
}[language];
|
||||
const tutorialScriptName = `n00dles${tutorialScriptExtension}`;
|
||||
const tutorialScriptName = `n00dles.js`;
|
||||
|
||||
const contents: { [number: string]: IContent | undefined } = {
|
||||
[iTutorialSteps.Start as number]: {
|
||||
@ -83,47 +68,6 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
),
|
||||
canNext: true,
|
||||
},
|
||||
[iTutorialSteps.NSSelection as number]: {
|
||||
content: (
|
||||
<>
|
||||
<Typography>The tutorial will adjust to your programming ability.</Typography>
|
||||
<Typography>Bitburner has 2 types of scripts:</Typography>
|
||||
<List>
|
||||
<ListItem>
|
||||
<Typography>NS1: Javascript from 2009, very simple. Recommended for beginners to programming.</Typography>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Typography>
|
||||
NS2: Native, modern Javascript. Recommended if you know any programming language or are serious about
|
||||
learning programming.
|
||||
</Typography>
|
||||
</ListItem>
|
||||
</List>
|
||||
<Typography>
|
||||
Both are available at all time and interchangeably. This choice is only for the tutorial.
|
||||
</Typography>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setLanguage(Language.NS1);
|
||||
iTutorialNextStep();
|
||||
}}
|
||||
>
|
||||
Use NS1
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setLanguage(Language.NS2);
|
||||
iTutorialNextStep();
|
||||
}}
|
||||
>
|
||||
Use NS2
|
||||
</Button>
|
||||
<Button onClick={() => setNSSelectionOpen(true)}>More info</Button>
|
||||
<br />
|
||||
</>
|
||||
),
|
||||
canNext: false,
|
||||
},
|
||||
[iTutorialSteps.GoToCharacterPage as number]: {
|
||||
content: (
|
||||
<>
|
||||
@ -320,7 +264,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
<Typography></Typography>
|
||||
</>
|
||||
),
|
||||
canNext: true,
|
||||
canNext: false,
|
||||
},
|
||||
[iTutorialSteps.TerminalManualHack as number]: {
|
||||
content: (
|
||||
@ -364,7 +308,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
<Typography>Let's head home before creating our first script!</Typography>
|
||||
</>
|
||||
),
|
||||
canNext: true,
|
||||
canNext: false,
|
||||
},
|
||||
[iTutorialSteps.TerminalCreateScript as number]: {
|
||||
content: (
|
||||
@ -378,9 +322,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
</Typography>
|
||||
<Typography classes={{ root: classes.textfield }}>{"[home ~/]> nano"}</Typography>
|
||||
|
||||
<Typography>
|
||||
Scripts must end with the {tutorialScriptExtension} extension. Let's make a script now by entering{" "}
|
||||
</Typography>
|
||||
<Typography>Scripts must end with the .js extension. Let's make a script now by entering </Typography>
|
||||
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> nano ${tutorialScriptName}`}</Typography>
|
||||
|
||||
<Typography>
|
||||
@ -394,20 +336,12 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
content: (
|
||||
<>
|
||||
<Typography>
|
||||
This is the script editor. You can use it to program your scripts.{" "}
|
||||
{language !== Language.NS2 && <>Scripts are written in a simplified version of javascript.</>} Copy and
|
||||
paste the following code into the script editor: <br />
|
||||
This is the script editor. You can use it to program your scripts. Copy and paste the following code into
|
||||
the script editor: <br />
|
||||
</Typography>
|
||||
|
||||
<Typography classes={{ root: classes.code }}>
|
||||
{language !== Language.NS2 && (
|
||||
<CopyableText
|
||||
value={`while(true) {
|
||||
hack('n00dles');
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
{language === Language.NS2 && (
|
||||
{
|
||||
<CopyableText
|
||||
value={`export async function main(ns) {
|
||||
while(true) {
|
||||
@ -415,7 +349,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
}
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
}
|
||||
</Typography>
|
||||
<Typography>
|
||||
For anyone with basic programming experience, this code should be straightforward. This script will
|
||||
@ -589,8 +523,17 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
content: (
|
||||
<Typography>
|
||||
This page contains a lot of different documentation about the game's content and mechanics. I know it's a lot,
|
||||
but I highly suggest you read (or at least skim) through this before you start playing . That's the end of the
|
||||
tutorial. Hope you enjoy the game!
|
||||
but I highly suggest you read (or at least skim) through this before you start playing.
|
||||
<br />
|
||||
<br />
|
||||
The{" "}
|
||||
<a href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html">
|
||||
Getting Started
|
||||
</a>{" "}
|
||||
contains the guide for new players, navigating you through most of early game.
|
||||
<br />
|
||||
<br />
|
||||
That's the end of the tutorial. Hope you enjoy the game!
|
||||
</Typography>
|
||||
),
|
||||
canNext: true,
|
||||
@ -614,7 +557,6 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
||||
if (content === undefined) throw new Error("error in the tutorial");
|
||||
return (
|
||||
<>
|
||||
<NSSelection open={nsSelectionOpen} onClose={() => setNSSelectionOpen(false)} />
|
||||
<Paper square sx={{ maxWidth: "70vw", p: 2 }}>
|
||||
{content.content}
|
||||
{step !== iTutorialSteps.TutorialPageInfo && (
|
||||
|
@ -1,82 +0,0 @@
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { Tab, Tabs, Typography } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
import { Modal } from "../React/Modal";
|
||||
|
||||
import * as monaco from "monaco-editor";
|
||||
|
||||
type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const ns1Example = `while(true) {
|
||||
hack('n00dles');
|
||||
}`;
|
||||
const ns2Example = `/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
while(true) {
|
||||
await ns.hack('n00dles');
|
||||
}
|
||||
}`;
|
||||
|
||||
export function NSSelection(props: IProps): React.ReactElement {
|
||||
const [value, setValue] = React.useState(0);
|
||||
|
||||
function handleChange(event: React.SyntheticEvent, tab: number): void {
|
||||
setValue(tab);
|
||||
}
|
||||
|
||||
function onMount(editor: IStandaloneCodeEditor): void {
|
||||
editor.updateOptions({ readOnly: true });
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose} sx={{ zIndex: 999999 }}>
|
||||
<Tabs variant="fullWidth" value={value} onChange={handleChange}>
|
||||
<Tab label="NS1" />
|
||||
<Tab label="NS2" />
|
||||
</Tabs>
|
||||
|
||||
{value === 0 && (
|
||||
<>
|
||||
<Typography>
|
||||
These scripts end with '.script'. Using a very old interpreted version of javascript. It is perfect for
|
||||
beginner to programming.
|
||||
</Typography>
|
||||
<Typography>Example script using NS1:</Typography>
|
||||
<Editor
|
||||
loading={<></>}
|
||||
defaultLanguage="javascript"
|
||||
defaultValue={ns1Example}
|
||||
height={`${300}px`}
|
||||
theme={"vs-dark"}
|
||||
onMount={onMount}
|
||||
options={{ fontSize: 30 }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{value === 1 && (
|
||||
<>
|
||||
<Typography>
|
||||
These scripts end with '.js'. Scripts using ns2 are running natively along the game. If you know any
|
||||
programming language you should be using this. However if you're unfamiliar with javascript Promises you
|
||||
might want to read up on them a little bit before diving in.
|
||||
</Typography>
|
||||
<Typography>Example script using NS2:</Typography>
|
||||
<Editor
|
||||
loading={<></>}
|
||||
defaultLanguage="javascript"
|
||||
defaultValue={ns2Example}
|
||||
height={`${300}px`}
|
||||
theme={"vs-dark"}
|
||||
options={{ fontSize: 30 }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user