diff --git a/cypress.json b/cypress.json index 52a751f84..97707ced4 100644 --- a/cypress.json +++ b/cypress.json @@ -4,5 +4,7 @@ "trashAssetsBeforeRuns": true, "screenshotsFolder": ".cypress/screenshots", "videosFolder": ".cypress/videos", - "videoUploadOnPasses": false + "videoUploadOnPasses": false, + "viewportWidth": 1980, + "viewportHeight": 1080 } diff --git a/cypress/integration/netscript.spec.ts b/cypress/integration/netscript.spec.ts index a07421d54..58a31e9ef 100644 --- a/cypress/integration/netscript.spec.ts +++ b/cypress/integration/netscript.spec.ts @@ -2,7 +2,7 @@ export {}; describe("netscript", () => { it("creates and runs a NetScript 2.0 script", () => { - cy.findByRole("button", { name: "Exit Tutorial" }).click(); + cy.findByRole("button", { name: "SKIP TUTORIAL" }).click(); cy.findByText("Got it!").click(); cy.findByRole("textbox").type("connect n00dles{enter}"); @@ -32,7 +32,7 @@ describe("netscript", () => { }); it("errors and shows a dialog box when static RAM !== dynamic RAM", () => { - cy.findByRole("button", { name: "Exit Tutorial" }).click(); + cy.findByRole("button", { name: "SKIP TUTORIAL" }).click(); cy.findByText("Got it!").click(); cy.findByRole("textbox").type("nano script.js{enter}"); diff --git a/cypress/integration/tutorial.spec.ts b/cypress/integration/tutorial.spec.ts index f13eb7592..1198bf7f9 100644 --- a/cypress/integration/tutorial.spec.ts +++ b/cypress/integration/tutorial.spec.ts @@ -3,19 +3,19 @@ export {}; describe("tutorial", () => { it("completes the tutorial", () => { cy.findByText(/dark, dystopian future/); - cy.findByRole("button", { name: "Next" }).click(); + cy.findByRole("button", { name: "next" }).click(); cy.findByText(/heading to the Stats page/); cy.findByRole("button", { name: "Stats" }).click(); cy.findByText(/lot of important information/); - cy.findByRole("button", { name: "Next" }).click(); + cy.findByRole("button", { name: "next" }).click(); cy.findByText(/head to your computer's terminal/); cy.findByRole("button", { name: "Terminal" }).click(); cy.findByText(/is used to interface/); - cy.findByRole("button", { name: "Next" }).click(); + cy.findByRole("button", { name: "next" }).click(); cy.findByText(/Let's try it out/i); cy.findByRole("textbox").type("help{enter}"); @@ -29,7 +29,7 @@ describe("tutorial", () => { cy.findByText(/that's great and all/i); cy.findByRole("textbox").type("scan-analyze{enter}"); - cy.findByText(/this command shows more detailed information/i); + cy.findByText(/shows more detailed information/i); cy.findByRole("textbox").type("scan-analyze 2{enter}"); cy.findByText(/now you can see information/i); @@ -46,10 +46,11 @@ describe("tutorial", () => { cy.findByRole("textbox").type("hack{enter}"); cy.findByText(/now attempting to hack the server/i); - cy.findByRole("button", { name: "Next" }).click(); + cy.findByRole("button", { name: "next" }).click(); - cy.findByText(/hacking exp/i); - cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("nano n00dles.script{enter}"); + cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("home{enter}"); + + cy.findByRole("textbox").type("nano n00dles.script{enter}"); // monaco can take a bit cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type("while(true) {{}{enter}hack('n00dles');"); @@ -72,7 +73,7 @@ describe("tutorial", () => { cy.findByRole("textbox").type("tail n00dles.script{enter}"); cy.findByText(/The log for this script won't show much/i); - cy.findByRole("button", { name: "Next" }).click(); + cy.findByRole("button", { name: "next" }).click(); cy.findByText(/Hacking is not the only way to earn money/i); cy.findByRole("button", { name: "Hacknet" }).click(); @@ -87,7 +88,7 @@ describe("tutorial", () => { cy.findByRole("button", { name: "Tutorial" }).click(); cy.findByText(/a lot of different documentation about the game/i); - cy.findByRole("button", { name: "Finish Tutorial" }).click(); + cy.findByRole("button", { name: "next" }).click(); cy.findByText("Got it!").click(); cy.findByText(/Tutorial \(AKA Links to Documentation\)/i); diff --git a/src/InteractiveTutorial.js b/src/InteractiveTutorial.js index bbead93e9..18379f521 100644 --- a/src/InteractiveTutorial.js +++ b/src/InteractiveTutorial.js @@ -28,6 +28,7 @@ const orderedITutorialSteps = [ "TerminalNuke", // NUKE n00dles "TerminalManualHack", // Hack n00dles "TerminalHackingMechanics", // Explanation of hacking mechanics + "TerminalGoHome", // Go home before creating a script. "TerminalCreateScript", // Create a script using 'nano' "TerminalTypeScript", // Script Editor page - Type script and then save & close "TerminalFree", // Using 'Free' Terminal command diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index cd6929ad1..8039090ec 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -590,6 +590,14 @@ export class Terminal implements ITerminal { return; } break; + case iTutorialSteps.TerminalGoHome: + if (commandArray.length == 1 && commandArray[0] == "home") { + iTutorialNextStep(); + } else { + this.print("Bad command. Please follow the tutorial"); + return; + } + break; case iTutorialSteps.TerminalCreateScript: if (commandArray.length == 2 && commandArray[0] == "nano" && commandArray[1] == "n00dles.script") { iTutorialNextStep(); diff --git a/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx b/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx index dc5d86fe2..486d342d8 100644 --- a/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx +++ b/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx @@ -8,14 +8,19 @@ import ArrowForwardIos from "@mui/icons-material/ArrowForwardIos"; import ArrowBackIos from "@mui/icons-material/ArrowBackIos"; import { ITutorialEvents } from "./ITutorialEvents"; import { use } from "../Context"; +import { CopyableText } from "../React/CopyableText"; import ListItem from "@mui/material/ListItem"; +import TextField from "@mui/material/TextField"; 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 "@mui/styles/makeStyles"; +import createStyles from "@mui/styles/createStyles"; import { iTutorialPrevStep, @@ -30,439 +35,496 @@ interface IContent { canNext: boolean; } -const contents: { [number: string]: IContent | undefined } = { - [iTutorialSteps.Start as number]: { - content: ( - - Welcome to Bitburner, a cyberpunk-themed incremental RPG! The game takes place in a dark, dystopian future... - The year is 2077... -
-
- This tutorial will show you the basics of the game. You may skip the tutorial at any time. -
- ), - canNext: true, - }, - [iTutorialSteps.GoToCharacterPage as number]: { - content: ( - <> - Let's start by heading to the Stats page. Click - - - Stats - - - on the main navigation menu (left-hand side of the screen) - - ), - canNext: false, - }, - [iTutorialSteps.CharacterPage as number]: { - content: ( - <> - - - Stats - - - shows a lot of important information about your progress, such as your skills, money, and bonuses. - - - ), - canNext: true, - }, - [iTutorialSteps.CharacterGoToTerminalPage as number]: { - content: ( - <> - Let's head to your computer's terminal by clicking - - - Terminal - - on the main navigation menu. - - ), - canNext: false, - }, - [iTutorialSteps.TerminalIntro as number]: { - content: ( - <> - - - Terminal - - - is used to interface with your home computer as well as all of the other machines around the world. - - - ), - canNext: true, - }, - [iTutorialSteps.TerminalHelp as number]: { - content: ( - <> - - Let's try it out. Start by entering the help command - into the - - - - Terminal - - (Don't forget to press Enter after typing the command) - - ), - canNext: false, - }, - [iTutorialSteps.TerminalLs as number]: { - content: ( - <> - - The help command displays a list of all available - - - - Terminal - - - commands, how to use them, and a description of what they do.
-
- Let's try another command. Enter the ls command. -
- - ), - canNext: false, - }, - [iTutorialSteps.TerminalScan as number]: { - content: ( - - ls is a basic command that shows 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.
-
- Using your home computer's terminal, you can connect to other machines throughout the world. Let's do that now - by first entering the scan command. -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalScanAnalyze1 as number]: { - content: ( - - 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.
-
- That's great and all, but there's so many servers. Which one should you go to? The{" "} - scan-analyze command gives some more detailed information - about servers on the network. Try it now! -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalScanAnalyze2 as number]: { - content: ( - - You just ran scan-analyze with a depth of one. This - command shows more detailed information about each server that you can connect to (servers that are a distance - of one node away).
-
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. -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalConnect as number]: { - content: ( - - 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 [hostname] command. -
-
- From the results of the scan-analyze command, we can see - that the n00dles server is only one node away. Let's - connect so it now using: connect n00dles -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalAnalyze as number]: { - content: ( - - You are now connected to another machine! What can you do now? You can hack it! -
-
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.
-
- Before you try to hack a server, you should run diagnostics using the{" "} - analyze command. -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalNuke as number]: { - content: ( - - When the analyze command finishes running it will show - useful information about hacking the server.
-
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. -
-
The analyze results shows that there do not need to - be any open ports on this machine for the NUKE virus to work, so go ahead and run the virus using the{" "} - run NUKE.exe command. -
- ), - canNext: true, - }, - [iTutorialSteps.TerminalManualHack as number]: { - content: ( - - You now have root access! You can hack the server using the{" "} - hack command. Try doing that now. - - ), - canNext: true, - }, - [iTutorialSteps.TerminalHackingMechanics as number]: { - content: ( - - 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. -
-
- 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. -
-
- 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. -
- ), - canNext: true, - }, - [iTutorialSteps.TerminalCreateScript as number]: { - content: ( - - 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! -
-
- To create a new script or edit an existing one, you can use the{" "} - nano - command. Scripts must end with the .script extension. - Let's make a script now by entering nano n00dles.script{" "} - after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early) -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalTypeScript as number]: { - content: ( - <> - - This is the script editor. You can use it to program your scripts. Scripts are written in a simplified version - of javascript. Copy and paste the following code into the script editor:
-
-
-          while(true) {"{"}
-          hack('n00dles');
-          {"}"}
-        
- - For anyone with basic programming experience, this code should be straightforward. This script will - continuously hack the n00dles server. -
-
- To save and close the script editor, press the button in the bottom left, or press ctrl + b. -
- - ), - canNext: false, - }, - [iTutorialSteps.TerminalFree as number]: { - content: ( - - 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. -
-
- To check how much RAM is available on this machine, enter the{" "} - free command. -
- ), - canNext: false, - }, - [iTutorialSteps.TerminalRunScript as number]: { - content: ( - - We have 4GB of free RAM on this machine, which is enough to run our script. Let's run our script using{" "} - run n00dles.script. - - ), - canNext: false, - }, - [iTutorialSteps.TerminalGoToActiveScriptsPage as number]: { - content: ( - <> - - Your script is now running! It will continuously run in the background and will automatically stop if the code - ever completes (the n00dles.script will never complete - because it runs an infinite loop).
-
- 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.
-
- Let's check out some statistics for our running scripts by clicking{" "} -
- - - Active Scripts - - - ), - canNext: false, - }, - [iTutorialSteps.ActiveScriptsPage as number]: { - content: ( - <> - - 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. Let's go back to - - - - Terminal - - - ), - canNext: false, - }, - [iTutorialSteps.ActiveScriptsToTerminal as number]: { - content: ( - - 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 n00dles.script - - ), - canNext: false, - }, - [iTutorialSteps.TerminalTailScript as number]: { - content: ( - <> - - 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!
-
- This covers the basics of hacking. To learn more about writing scripts, select -
- - - Tutorial - - - in the main navigation menu to look at the documentation. - - If you are an experienced JavaScript developer, I would highly suggest you check out the section on - NetscriptJS/Netscript 2.0, it's faster and more powerful. - -
-
- For now, let's move on to something else! -
- - ), - canNext: true, - }, - [iTutorialSteps.GoToHacknetNodesPage as number]: { - content: ( - <> - - 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 - - - - Hacknet - - through the main navigation menu now. - - ), - canNext: true, - }, - [iTutorialSteps.HacknetNodesIntroduction as number]: { - content: ( - - here you can purchase new Hacknet Nodes and upgrade your existing ones. Let's purchase a new one now. - - ), - canNext: true, - }, - [iTutorialSteps.HacknetNodesGoToWorldPage as number]: { - content: ( - <> - - 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. -
-
- Let's go to -
- - - City - - - ), - canNext: true, - }, - [iTutorialSteps.WorldDescription as number]: { - content: ( - <> - - 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! -
-
- Lastly, click on -
- - - Tutorial - - - ), - canNext: true, - }, - [iTutorialSteps.TutorialPageInfo as number]: { - content: ( - - 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! - - ), - canNext: true, - }, - [iTutorialSteps.End as number]: { - content: , - canNext: true, - }, -}; +const useStyles = makeStyles((theme: Theme) => + createStyles({ + textfield: { + borderBottom: "1px solid " + theme.palette.primary.main, + }, + code: { + whiteSpace: "pre", + backgroundColor: theme.palette.background.paper, + }, + }), +); export function InteractiveTutorialRoot(): React.ReactElement { + const classes = useStyles(); + + const contents: { [number: string]: IContent | undefined } = { + [iTutorialSteps.Start as number]: { + content: ( + <> + + Welcome to Bitburner, a cyberpunk-themed incremental RPG! The game takes place in a dark, dystopian + future... The year is 2077... +
+
+ This tutorial will show you the basics of the game. You may skip the tutorial at any time. +
+ + ), + canNext: true, + }, + [iTutorialSteps.GoToCharacterPage as number]: { + content: ( + <> + Let's start by heading to the Stats page. Click + + + Stats + + + on the main navigation menu (left-hand side of the screen) + + ), + canNext: false, + }, + [iTutorialSteps.CharacterPage as number]: { + content: ( + <> + + + Stats + + + shows a lot of important information about your progress, such as your skills, money, and bonuses. + + + ), + canNext: true, + }, + [iTutorialSteps.CharacterGoToTerminalPage as number]: { + content: ( + <> + Let's head to your computer's terminal by clicking + + + Terminal + + on the main navigation menu. + + ), + canNext: false, + }, + [iTutorialSteps.TerminalIntro as number]: { + content: ( + <> + + + Terminal + + + is used to interface with your home computer as well as all of the other machines around the world. + + + ), + canNext: true, + }, + [iTutorialSteps.TerminalHelp as number]: { + content: ( + <> + Let's try it out. Start by entering + {"[home ~/]> help"} + (Don't forget to press Enter after typing the command) + + ), + canNext: false, + }, + [iTutorialSteps.TerminalLs as number]: { + content: ( + <> + {"[home ~/]> help"} + + displays a list of all available Terminal commands, how to use them, and a description of what they do.{" "} +
+
+ Let's try another command. Enter +
+ + {"[home ~/]> ls"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalScan as number]: { + content: ( + <> + {"[home ~/]> ls"} + + {" "} + is a basic command that shows 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.
+
+ Using your home computer's terminal, you can connect to other machines throughout the world. Let's do that + now by first entering +
+ {"[home ~/]> scan"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalScanAnalyze1 as number]: { + content: ( + <> + {"[home ~/]> scan"} + + 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.
+
+ That's great and all, but there's so many servers. Which one should you go to?{" "} +
+ + {"[home ~/]> scan-analyze"} + gives some more detailed information about servers on the network. Try it now! + + ), + canNext: false, + }, + [iTutorialSteps.TerminalScanAnalyze2 as number]: { + content: ( + <> + {"[home ~/]> scan-analyze"} + + shows more detailed information about each server that you can connect to (servers that are a distance of + one node away).
+
It is also possible to run scan-analyze with a higher depth. Let's try a depth of two with the + following command:{" "} +
+ + {"[home ~/]> scan-analyze 2"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalConnect as number]: { + content: ( + <> + + 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 + + {"[home ~/]> connect hostname"} + + From the results of + {"[home ~/]> scan-analyze 2"} + + + {" "} + we can see that the n00dles server is only one node away. Let's connect so it now using: + + + {"[home ~/]> connect n00dles"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalAnalyze as number]: { + content: ( + <> + + You are now connected to another machine! What can you do now? You can hack it! +
+
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.
+
+ Before you try to hack a server, you should run diagnostics using{" "} +
+ {"[n00dles ~/]> analyze"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalNuke as number]: { + content: ( + <> + When + {"[n00dles ~/]> analyze"} + + + finishes running it will show useful information about hacking the server.
+
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. +
+ {"[n00dles ~/]> analyze"} + + + {" "} + shows that there do not need to be any open ports on this machine for the NUKE virus to work, so go ahead + and run the virus using{" "} + + {"[n00dles ~/]> run NUKE.exe"} + + + + ), + canNext: true, + }, + [iTutorialSteps.TerminalManualHack as number]: { + content: ( + <> + You now have root access! You can hack the server using + {"[home ~/]> hack"} + + Try doing that now. + + ), + canNext: true, + }, + [iTutorialSteps.TerminalHackingMechanics as number]: { + content: ( + + 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. +
+
+ 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. +
+
+ 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. +
+ ), + canNext: true, + }, + [iTutorialSteps.TerminalGoHome as number]: { + content: ( + <> + From any server you can get back home using + {"[home ~/]> home"} + + Let's head home before creating our first script! + + ), + canNext: true, + }, + [iTutorialSteps.TerminalCreateScript as number]: { + content: ( + <> + + 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! +
+
+ To create a new script or edit an existing one, you can use{" "} +
+ {"[home ~/]> nano"} + + Scripts must end with the .script extension. Let's make a script now by entering + {"[home ~/]> nano n00dles.script"} + + + after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early) + + + ), + canNext: false, + }, + [iTutorialSteps.TerminalTypeScript as number]: { + content: ( + <> + + This is the script editor. You can use it to program your scripts. Scripts are written in a simplified + version of javascript. Copy and paste the following code into the script editor:
+
+ + + + + + For anyone with basic programming experience, this code should be straightforward. This script will + continuously hack the n00dles server. +
+
+ To save and close the script editor, press the button in the bottom left, or press ctrl + b. +
+ + ), + canNext: false, + }, + [iTutorialSteps.TerminalFree as number]: { + content: ( + <> + + 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. +
+
+ To check how much RAM is available on this machine, enter +
+ {"[home ~/]> free"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalRunScript as number]: { + content: ( + <> + + We have 8GB of free RAM on this machine, which is enough to run our script. Let's run our script using + + {"[home ~/]> run n00dles.script"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalGoToActiveScriptsPage as number]: { + content: ( + <> + + Your script is now running! It will continuously run in the background and will automatically stop if the + code ever completes (the n00dles.script will never complete because it runs an infinite loop).
+
+ 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.
+
+ Let's check out some statistics for our running scripts by clicking{" "} +
+ + + Active Scripts + + + ), + canNext: false, + }, + [iTutorialSteps.ActiveScriptsPage as number]: { + content: ( + <> + + 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. Let's go back to + + + + Terminal + + + ), + canNext: false, + }, + [iTutorialSteps.ActiveScriptsToTerminal as number]: { + content: ( + <> + + 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{" "} + + {"[home ~/]> tail n00dles.script"} + + ), + canNext: false, + }, + [iTutorialSteps.TerminalTailScript as number]: { + content: ( + <> + + 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!
+
+ This covers the basics of hacking. To learn more about writing scripts, select +
+ + + Tutorial + + + in the main navigation menu to look at the documentation. If you are an experienced JavaScript developer, I + would highly suggest you check out the section on NetscriptJS/Netscript 2.0, it's faster and more powerful. +
+
+ For now, let's move on to something else! +
+ + ), + canNext: true, + }, + [iTutorialSteps.GoToHacknetNodesPage as number]: { + content: ( + <> + + 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 + + + + Hacknet + + through the main navigation menu now. + + ), + canNext: true, + }, + [iTutorialSteps.HacknetNodesIntroduction as number]: { + content: ( + + here you can purchase new Hacknet Nodes and upgrade your existing ones. Let's purchase a new one now. + + ), + canNext: true, + }, + [iTutorialSteps.HacknetNodesGoToWorldPage as number]: { + content: ( + <> + + 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. +
+
+ Let's go to +
+ + + City + + + ), + canNext: true, + }, + [iTutorialSteps.WorldDescription as number]: { + content: ( + <> + + 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! +
+
+ Lastly, click on +
+ + + Tutorial + + + ), + canNext: true, + }, + [iTutorialSteps.TutorialPageInfo as number]: { + content: ( + + 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! + + ), + canNext: true, + }, + [iTutorialSteps.End as number]: { + content: , + canNext: true, + }, + }; + const setRerender = useState(false)[1]; function rerender(): void { setRerender((old) => !old); @@ -477,17 +539,23 @@ export function InteractiveTutorialRoot(): React.ReactElement { return ( {content.content} - - - - {content.canNext && ( - - - + {step !== iTutorialSteps.TutorialPageInfo && ( + <> + + + + {content.canNext && ( + + + + )} + )}

- +
); }