mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 22:38:34 +02:00
619 lines
22 KiB
TypeScript
619 lines
22 KiB
TypeScript
import React, { useEffect } from "react";
|
|
|
|
import Paper from "@mui/material/Paper";
|
|
import Typography from "@mui/material/Typography";
|
|
import Button from "@mui/material/Button";
|
|
import { ITutorialEvents } from "./ITutorialEvents";
|
|
import { CopyableText } from "../React/CopyableText";
|
|
|
|
import ListItem from "@mui/material/ListItem";
|
|
import EqualizerIcon from "@mui/icons-material/Equalizer";
|
|
import LastPageIcon from "@mui/icons-material/LastPage";
|
|
import HelpIcon from "@mui/icons-material/Help";
|
|
import AccountTreeIcon from "@mui/icons-material/AccountTree";
|
|
import StorageIcon from "@mui/icons-material/Storage";
|
|
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
|
import { Theme } from "@mui/material/styles";
|
|
import { makeStyles } from "tss-react/mui";
|
|
|
|
import {
|
|
iTutorialPrevStep,
|
|
iTutorialNextStep,
|
|
ITutorial,
|
|
iTutorialSteps,
|
|
iTutorialEnd,
|
|
} from "../../InteractiveTutorial";
|
|
import { useRerender } from "../React/hooks";
|
|
import { Settings } from "../../Settings/Settings";
|
|
import { NsApiDocumentationLink } from "../React/NsApiDocumentationLink";
|
|
|
|
interface IContent {
|
|
content: React.ReactElement;
|
|
canNext: boolean;
|
|
}
|
|
|
|
const useStyles = makeStyles()((theme: Theme) => ({
|
|
textfield: {
|
|
borderBottom: "1px solid " + theme.palette.primary.main,
|
|
},
|
|
code: {
|
|
whiteSpace: "pre",
|
|
backgroundColor: theme.palette.background.paper,
|
|
},
|
|
}));
|
|
|
|
function Example({ content }: { content: string }): React.ReactElement {
|
|
const { classes } = useStyles();
|
|
return (
|
|
<>
|
|
<br />
|
|
<Typography>
|
|
Example:{" "}
|
|
<Typography component="span" classes={{ root: classes.textfield }}>
|
|
{content}
|
|
</Typography>
|
|
</Typography>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function InteractiveTutorialRoot(): React.ReactElement {
|
|
const { classes } = useStyles();
|
|
const rerender = useRerender();
|
|
|
|
const tutorialScriptName = `n00dles.js`;
|
|
|
|
const contents: Record<iTutorialSteps, IContent | undefined> = {
|
|
[iTutorialSteps.Start]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Welcome to Bitburner, a cyberpunk-themed incremental RPG! The game takes place in a dark, dystopian
|
|
future... The year is 2077...
|
|
<br />
|
|
<br />
|
|
This tutorial will show you the basics of the game. You may skip the tutorial at any time.
|
|
<br />
|
|
<br />
|
|
You can replay this tutorial by going to the Options tab and pressing "Reset tutorial".
|
|
<br />
|
|
<br />
|
|
You can also collapse this panel to temporarily hide this tutorial.
|
|
</Typography>
|
|
</>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.GoToCharacterPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>Let's start by heading to the Stats page. Click</Typography>
|
|
<ListItem>
|
|
<EqualizerIcon color={"error"} />
|
|
<Typography color={"error"}>Stats</Typography>
|
|
</ListItem>
|
|
|
|
<Typography>on the main navigation menu (left-hand side of the screen)</Typography>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.CharacterPage]: {
|
|
content: (
|
|
<>
|
|
<ListItem>
|
|
<EqualizerIcon color={"primary"} />
|
|
<Typography color={"primary"}>Stats</Typography>
|
|
</ListItem>
|
|
<Typography>
|
|
shows a lot of important information about your progress, such as your skills, money, and bonuses.
|
|
</Typography>
|
|
</>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.CharacterGoToTerminalPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>Let's head to your computer's terminal by clicking</Typography>
|
|
<ListItem>
|
|
<LastPageIcon color={"error"} />
|
|
<Typography color={"error"}>Terminal</Typography>
|
|
</ListItem>
|
|
<Typography>on the main navigation menu.</Typography>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalIntro]: {
|
|
content: (
|
|
<>
|
|
<ListItem>
|
|
<LastPageIcon color={"primary"} />
|
|
<Typography color={"primary"}>Terminal</Typography>
|
|
</ListItem>
|
|
<Typography>
|
|
is used to interface with your home computer as well as all of the other machines around the world.
|
|
</Typography>
|
|
<br />
|
|
<Typography>
|
|
In the next steps, the tutorial will show you how to use the most basic commands. In each step, we may show
|
|
you an example of how the terminal should look when you enter the command.
|
|
</Typography>
|
|
</>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.TerminalHelp]: {
|
|
content: (
|
|
<>
|
|
<Typography>Let's try it out. Start by entering "help" to the terminal</Typography>
|
|
<Typography>(Don't forget to press Enter after typing the command)</Typography>
|
|
<Example content="[home /]> help" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalLs]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
The "help" command displays a list of all available Terminal commands, how to use them, and a description of
|
|
what they do. <br />
|
|
<br />
|
|
Let's try another command. Enter "ls" ("ls" is short for "list" ).
|
|
</Typography>
|
|
<Example content="[home /]> ls" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalScan]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
The "ls" command is a basic command that lists the files on the computer. Right now, it shows that you have
|
|
a program called NUKE.exe on your computer. We'll get to what this does later. <br />
|
|
<br />
|
|
Using your home computer's terminal, you can connect to other machines throughout the world. Let's do that
|
|
now by first entering "scan".
|
|
</Typography>
|
|
<Example content="[home /]> scan" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalScanAnalyze1]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
The "scan" command shows all available network connections. In other words, it displays a list of all
|
|
servers that can be connected to from your current machine. A server is identified by its hostname. <br />
|
|
<br />
|
|
That's great and all, but there's so many servers. Which one should you go to?
|
|
</Typography>
|
|
|
|
<Typography>
|
|
The "scan-analyze" command gives some more detailed information about servers on the network. Try it now!
|
|
</Typography>
|
|
<Example content="[home /]> scan-analyze" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalScanAnalyze2]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
The "scan-analyze" command shows more detailed information about each server that you can connect to
|
|
(servers that are a distance of one node away). <br />
|
|
<br /> It is also possible to run scan-analyze with a higher depth. Let's try a depth of two with the
|
|
following command: "scan-analyze 2"
|
|
</Typography>
|
|
|
|
<Example content="[home /]> scan-analyze 2" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalConnect]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Now you can see information about all servers that are up to two nodes away, as well as figure out how to
|
|
navigate to those servers through the network. You can only connect to a server that is one node away. To
|
|
connect to a machine, use the "connect" command.
|
|
</Typography>
|
|
|
|
<Typography>
|
|
From the results of the "scan-analyze" command, we can see that the n00dles server is only one node away.
|
|
Let's connect to it now using "connect n00dles".
|
|
</Typography>
|
|
|
|
<Example content="[home /]> connect n00dles" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalAnalyze]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
You are now connected to another machine! What can you do now? You can hack it!
|
|
<br />
|
|
<br /> In the year 2077, currency has become digital and decentralized. People and corporations store their
|
|
money on servers and computers. Using your hacking abilities, you can hack servers to steal money and gain
|
|
experience. <br />
|
|
<br />
|
|
Before you try to hack a server, you should run diagnostics using the "analyze" command.
|
|
</Typography>
|
|
<Example content="[n00dles /]> analyze" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalNuke]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
When the "analyze" command finishes running, it will show useful information about hacking the server.
|
|
<br />
|
|
For this server, the required hacking skill is only 1, which means you can hack it right now. However, in
|
|
order to hack a server you must first gain root access. The NUKE.exe program that we saw earlier on your
|
|
home computer is a virus that will grant you root access to a machine if there are enough open ports.
|
|
</Typography>
|
|
<br />
|
|
<Typography>
|
|
The "analyze" command shows that there do not need to be any open ports on this machine for the NUKE program
|
|
to work, so go ahead and run the NUKE program using "run NUKE.exe".
|
|
</Typography>
|
|
<Example content="[n00dles /]> run NUKE.exe" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalManualHack]: {
|
|
content: (
|
|
<>
|
|
<Typography>You now have root access! You can hack the server using the "hack" command.</Typography>
|
|
<Typography> Try doing that now.</Typography>
|
|
<Example content="[n00dles /]> hack" />
|
|
</>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.TerminalHackingMechanics]: {
|
|
content: (
|
|
<Typography component="div">
|
|
You are now attempting to hack the server. Performing a hack takes time and only has a certain percentage
|
|
chance of success. This time and success chance is determined by a variety of factors, including your hacking
|
|
skill and the server's security level.
|
|
<br />
|
|
<br />
|
|
If your attempt to hack the server is successful, you will steal a certain percentage of the server's total
|
|
money. This percentage is affected by your hacking skill and the server's security level.
|
|
<br />
|
|
<br />
|
|
The amount of money on a server is not limitless. So, if you constantly hack a server and deplete its money,
|
|
then you will encounter diminishing returns in your hacking. You will need to use the "grow" command which
|
|
tricks the company into adding money to their server and the "weaken" command which decreases the server's
|
|
security level.
|
|
<br />
|
|
<Example content="[n00dles /]> grow" />
|
|
<Example content="[n00dles /]> weaken" />
|
|
</Typography>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.TerminalGoHome]: {
|
|
content: (
|
|
<>
|
|
<Typography>From any server you can get back home using the "home" command.</Typography>
|
|
<Typography>Let's head home before creating our first script!</Typography>
|
|
<Example content="[n00dles /]> home" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalCreateScript]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Hacking is the core mechanic of the game and is necessary for progressing. However, you don't want to be
|
|
hacking manually the entire time. You can automate your hacking by writing scripts!
|
|
<br />
|
|
<br />
|
|
To create a new script or edit an existing one, you can use the "nano" command.
|
|
</Typography>
|
|
|
|
<Typography>
|
|
Scripts must end with a script extension (.js, .jsx, .ts, .tsx). Let's make a script now by entering "
|
|
{`nano ${tutorialScriptName}`}"
|
|
</Typography>
|
|
<Example content={`[home /]> nano ${tutorialScriptName}`} />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalEditScript]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
This is the script editor. You can use it to program your scripts. Click this text to copy it and paste it
|
|
into the text editor:
|
|
</Typography>
|
|
<br />
|
|
<Typography component="div" classes={{ root: classes.code }}>
|
|
{
|
|
<CopyableText
|
|
value={`/** @param {NS} ns */
|
|
export async function main(ns) {
|
|
while (true) {
|
|
await ns.hack("n00dles");
|
|
}
|
|
}`}
|
|
/>
|
|
}
|
|
</Typography>
|
|
<br />
|
|
<Typography>
|
|
For anyone with basic programming experience, this code should be straightforward. This script will
|
|
continuously hack the n00dles server.
|
|
<br />
|
|
<br />
|
|
Use the search tool at the bottom to find and have a quick glance at documentation of any NS APIs.
|
|
<br />
|
|
<br />
|
|
To access <NsApiDocumentationLink />, press the link at the bottom.
|
|
<br />
|
|
<br />
|
|
To save and close the script editor, press the button at the bottom.
|
|
</Typography>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalFree]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Now we'll run the script. Scripts require a certain amount of RAM to run, and can be run on any machine
|
|
which you have root access to. Different servers have different amounts of RAM. You can also purchase more
|
|
RAM for your home server.
|
|
<br />
|
|
<br />
|
|
To check how much RAM is available on this machine, use the "free" command.
|
|
</Typography>
|
|
<Example content="[home /]> free" />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalRunScript]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
We have 8GB of free RAM on this machine, which is enough to run our script. Let's run our script using "
|
|
{`run ${tutorialScriptName}`}"
|
|
</Typography>
|
|
<Example content={`[home /]> run ${tutorialScriptName}`} />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalGoToActiveScriptsPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Your script is now running! It will continuously run in the background and will automatically stop if the
|
|
code ever completes (the {tutorialScriptName} will never complete because it runs an infinite loop). <br />
|
|
<br />
|
|
These scripts can passively earn you income and hacking experience. Your scripts will also earn money and
|
|
experience while you are offline, although at a slightly slower rate. <br />
|
|
<br />
|
|
Let's check out some statistics for our running scripts by clicking{" "}
|
|
</Typography>
|
|
<ListItem>
|
|
<StorageIcon color={"error"} />
|
|
<Typography color={"error"}>Active Scripts</Typography>
|
|
</ListItem>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.ActiveScriptsPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
This page displays information about all of your scripts that are running across every server. You can use
|
|
this to gauge how well your scripts are doing.
|
|
<br />
|
|
<br />
|
|
Click on Home to see the scripts running on it.
|
|
<br />
|
|
<br />
|
|
Then click on n00dles.js to see the scripts information.
|
|
<br />
|
|
<br />
|
|
Let's go back to
|
|
</Typography>
|
|
<ListItem>
|
|
<LastPageIcon color={"error"} />
|
|
<Typography color={"error"}>Terminal</Typography>
|
|
</ListItem>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.ActiveScriptsToTerminal]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
One last thing about scripts, each active script contains logs that detail what it's doing. We can check
|
|
these logs using the "tail" command. Do that now for the script we just ran by typing "
|
|
{`tail ${tutorialScriptName}`}"
|
|
</Typography>
|
|
<Example content={`[home /]> tail ${tutorialScriptName}`} />
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.TerminalTailScript]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
The log for this script won't show much right now (it might show nothing at all) because it just started
|
|
running...but check back again in a few minutes! <br />
|
|
<br />
|
|
This covers the basics of hacking. To learn more about writing scripts, select
|
|
</Typography>
|
|
<ListItem>
|
|
<HelpIcon color={"primary"} />
|
|
<Typography color={"primary"}>Documentation</Typography>
|
|
</ListItem>
|
|
<Typography>
|
|
in the main navigation menu to look at the documentation.
|
|
<br />
|
|
<br />
|
|
For now, let's move on to something else!
|
|
</Typography>
|
|
</>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.GoToHacknetNodesPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
Hacking is not the only way to earn money. One other way to passively earn money is by purchasing and
|
|
upgrading Hacknet Nodes. Let's go to
|
|
</Typography>
|
|
<ListItem>
|
|
<AccountTreeIcon color={"error"} />
|
|
<Typography color={"error"}>Hacknet</Typography>
|
|
</ListItem>
|
|
<Typography>through the main navigation menu now.</Typography>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.HacknetNodesIntroduction]: {
|
|
content: (
|
|
<Typography>
|
|
Here you can purchase new Hacknet Nodes and upgrade your existing ones. Let's purchase a new one now.
|
|
</Typography>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.HacknetNodesGoToWorldPage]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
You just purchased a Hacknet Node! This Hacknet Node will passively earn you money over time, both online
|
|
and offline. When you get enough money, you can upgrade your newly-purchased Hacknet Node below.
|
|
<br />
|
|
<br />
|
|
Let's go to
|
|
</Typography>
|
|
<ListItem>
|
|
<LocationCityIcon color={"error"} />
|
|
<Typography color={"error"}>City</Typography>
|
|
</ListItem>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.WorldDescription]: {
|
|
content: (
|
|
<>
|
|
<Typography>
|
|
This page lists all of the different locations you can currently travel to. Each location has something that
|
|
you can do. There's a lot of content out in the world, make sure you explore and discover!
|
|
<br />
|
|
<br />
|
|
Lastly, click on
|
|
</Typography>
|
|
<ListItem>
|
|
<HelpIcon color={"error"} />
|
|
<Typography color={"error"}>Documentation</Typography>
|
|
</ListItem>
|
|
</>
|
|
),
|
|
canNext: false,
|
|
},
|
|
[iTutorialSteps.DocumentationPageInfo]: {
|
|
content: (
|
|
<Typography component="div">
|
|
This page contains a lot of different documentation about the game's contents and mechanics. I know it's a
|
|
lot, but I highly suggest you read (or at least skim) through this before you start playing. Some pages are
|
|
inaccessible at the start and will be unlocked later.
|
|
<br />
|
|
<br />
|
|
If you click a link in these pages while holding Ctrl key (Control key on Mac keyboard), it will be opened in
|
|
a new tab. If you play the Steam version, that link will be opened in your default browser.
|
|
<br />
|
|
<br />
|
|
You should at least check these pages:
|
|
<ul>
|
|
<li>
|
|
The Beginner's guide contains the guide for new players, navigating you through most of the early game.
|
|
</li>
|
|
<li>The NS API documentation contains reference materials for all NS APIs.</li>
|
|
<li>The FAQ contains questions often asked by beginners of the game.</li>
|
|
</ul>
|
|
<Typography fontWeight="fontWeightBold">
|
|
This documentation page is the best place to get up-to-date information, especially when you get stuck. If
|
|
you have a question and cannot find the answer here, please ask us on Discord.
|
|
</Typography>
|
|
<br />
|
|
<Typography color={Settings.theme.warning}>
|
|
The documentation at readthedocs is outdated and unmaintained. Do not use them!
|
|
</Typography>
|
|
<br />
|
|
That's the end of the tutorial. Hope you enjoy the game!
|
|
</Typography>
|
|
),
|
|
canNext: true,
|
|
},
|
|
[iTutorialSteps.End]: {
|
|
content: <Typography></Typography>,
|
|
canNext: true,
|
|
},
|
|
};
|
|
|
|
useEffect(() => {
|
|
return ITutorialEvents.subscribe(rerender);
|
|
}, [rerender]);
|
|
|
|
const step = ITutorial.currStep;
|
|
const content = contents[step];
|
|
if (content === undefined) throw new Error("error in the tutorial");
|
|
return (
|
|
<>
|
|
<Paper square sx={{ maxWidth: "70vw", p: 2 }}>
|
|
{content.content}
|
|
<br />
|
|
{step !== iTutorialSteps.DocumentationPageInfo && (
|
|
<>
|
|
{step !== iTutorialSteps.Start && (
|
|
<Button onClick={iTutorialPrevStep} aria-label="previous" style={{ marginRight: "1em" }}>
|
|
Previous
|
|
</Button>
|
|
)}
|
|
{(content.canNext || ITutorial.stepIsDone[step]) && (
|
|
<Button onClick={iTutorialNextStep} aria-label="next">
|
|
Next
|
|
</Button>
|
|
)}
|
|
</>
|
|
)}
|
|
<br />
|
|
<br />
|
|
<Button onClick={iTutorialEnd}>
|
|
{step !== iTutorialSteps.DocumentationPageInfo ? "Exit Tutorial" : "Finish Tutorial"}
|
|
</Button>
|
|
</Paper>
|
|
</>
|
|
);
|
|
}
|