Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
fe9ab58
revamped tutorial and blast radius
Aug 26, 2026
3b73346
spacing
Aug 26, 2026
c6350ab
blah
Aug 26, 2026
42dd594
attempt
Aug 26, 2026
374150e
better
Aug 26, 2026
dc74aa7
ok first draft ish
Aug 26, 2026
f054996
more
Aug 26, 2026
2c2cf2f
less bad
Aug 26, 2026
fbe9b41
less bad 2
Aug 26, 2026
4314c5d
briefer
Aug 26, 2026
82c8f5b
brie
Aug 26, 2026
639b325
bre
Aug 27, 2026
77acc69
reverted nansense
Aug 27, 2026
61fb619
zz
Aug 27, 2026
29cdb3c
betterer
Aug 27, 2026
583dc8b
.
Aug 27, 2026
be31a78
ok second draft ish
Aug 27, 2026
90a6cd7
run!
Aug 27, 2026
3942c82
being more permissive
Aug 27, 2026
550f86f
+
Aug 27, 2026
62e404f
better second draft!
Aug 27, 2026
eb568a6
a
Aug 27, 2026
cf4eb52
...
Aug 27, 2026
c437b1f
final second draft
Aug 27, 2026
00df9e6
yeah I said that was final but ...
Aug 27, 2026
422767c
!
Aug 27, 2026
ed3bc64
.
Aug 27, 2026
1b3d2ad
boing
Aug 27, 2026
49f4f34
.
Aug 27, 2026
76d7c91
reverting nonsense
Aug 27, 2026
d4224c5
deleted comments
Aug 27, 2026
a26b449
cleaner
Aug 27, 2026
fc0e435
tiny
Aug 27, 2026
65a6bd2
uiop
Aug 27, 2026
54e1d46
just learned how themes work
Aug 28, 2026
03e63db
REMOVED HACKNET
Aug 28, 2026
1907a89
moved hacknet info rewrite to a separate branch
Aug 28, 2026
7b2750e
3rd draft
Sep 1, 2026
2157207
wording tweaks
Sep 1, 2026
a15aa5e
briefer
Sep 2, 2026
ed4cf9d
not going to get much better ...
Sep 2, 2026
ec5b9d6
nit = picked
Sep 2, 2026
3124bb4
shorter clearer
Sep 2, 2026
948ad37
RAM!
Sep 2, 2026
3e25daa
ELDRITCH THINGS
Sep 2, 2026
81965b6
glarp
Sep 2, 2026
6f9d262
sheesh
Sep 2, 2026
33221d2
?????
Sep 2, 2026
e7eaa06
Merge branch 'bitburner-official:dev' into docs-content
branchtheory Sep 2, 2026
203c9eb
basically done
Sep 4, 2026
863f90e
Merge branch 'docs-content' of https://github.com/branchtheory/bitbur…
Sep 4, 2026
c5a4832
ready
Sep 4, 2026
cc66147
infelicities ejected
Sep 4, 2026
5375dde
readier
Sep 4, 2026
a63660a
.
Sep 4, 2026
0f4fdf8
prettier
Sep 4, 2026
a0ab610
moved grow.ts and weaken.ts changes into a separate PR
Sep 4, 2026
8e2aae6
keeping up with the refactor
Sep 4, 2026
8bd6f9f
Explained the purpose of the DocumentationRoot useEffect
Sep 4, 2026
24808af
prettier griefing me again
Sep 4, 2026
7533f0f
Reworded variable for precision
branchtheory Sep 5, 2026
bb308a9
Missed a reference
branchtheory Sep 5, 2026
7af815c
My vision is augmented.
Sep 7, 2026
a828568
Merge branch 'docs-content' of https://github.com/branchtheory/bitbur…
Sep 7, 2026
d94a062
Finito
Sep 7, 2026
82f06e4
last minute fix of a last minute fix
Sep 7, 2026
d7f7786
Refactored out 'styled'
Sep 8, 2026
03349f8
easier reviewing order
Sep 8, 2026
e64a7df
Much cleaner handling of bad terminal commands
Sep 8, 2026
f2e96d7
fix
Sep 8, 2026
a778f5d
Type issue
Sep 8, 2026
ddbb3e4
Removed bad ideas
Sep 8, 2026
eb5dd3c
Tiny refactor
Sep 8, 2026
dbd6dfa
Merge branch 'dev' into docs-content
branchtheory Sep 8, 2026
b94873c
Correction
Sep 8, 2026
eeb4091
Merge branch 'docs-content' of https://github.com/branchtheory/bitbur…
Sep 8, 2026
c83cee7
adding isRunning
Sep 8, 2026
42f5b66
Removed pointless stuff
Sep 8, 2026
8c7b1cc
isRunning additions
Sep 8, 2026
b362fad
Tiny tweak
branchtheory Sep 8, 2026
1d6617c
Update
Sep 9, 2026
31c75ab
Merge branch 'docs-content' of https://github.com/branchtheory/bitbur…
Sep 9, 2026
4139cfd
Update
branchtheory Sep 9, 2026
c6e80e7
IS isRunning
Sep 9, 2026
640c1ff
Switch
Sep 9, 2026
580679f
better
branchtheory Sep 10, 2026
2999577
better
branchtheory Sep 10, 2026
fe2641f
better
branchtheory Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Documentation/doc/en/help/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Since this guide is written as a basic introduction to Bitburner, it will not ex
## 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](../basic/scripts.md) called `n00dles.js` and ran it on the `n00dles` server.
In this introductory tutorial, you created a [Script](../basic/scripts.md) called `hacking.js` and ran it on the `home` server.
Comment thread
branchtheory marked this conversation as resolved.
Now, we'll kill this [Script](../basic/scripts.md). There are two ways to do this:

- You can go to the Terminal and enter: `kill n00dles.js`
- You can go to the `Active Scripts` page (Alt + s) and press the `Kill Script` button for `n00dles.js`.
- You can go to the Terminal and enter: `kill hacking.js`
- You can go to the `Active Scripts` page (Alt + s) and press the `Kill Script` button for `hacking.js`.

If you skipped the introductory tutorial, then ignore the part above.
Instead, go to the `Hacknet Nodes` page (Alt + h) and purchase a [Hacknet Node](../basic/hacknet_nodes.md) to start generating some passive income.
Expand Down
15 changes: 15 additions & 0 deletions src/Documentation/ui/DocumentationRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Settings } from "../../Settings/Settings";
import { Router } from "../../ui/GameRoot";
import { Page } from "../../ui/Router";
import { DocumentationAutocomplete } from "./DocumentationAutocomplete";
import { iTutorialSteps, ITutorial } from "../../InteractiveTutorial";

export function DocumentationRoot({ docPage }: { docPage?: string }): React.ReactElement {
const history = useHistory();
Expand Down Expand Up @@ -70,6 +71,20 @@ export function DocumentationRoot({ docPage }: { docPage?: string }): React.Reac
}, 0);
});

/**
* During the tutorial, the player is given the link to the NS API page a few times. If they click one of the links,
* then when they come to the documentation step they'll still see the NS API docs. This ensures that when the player
* visits the documentation page for the Docs step, they see index.md / home.
*/
useEffect(() => {
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.DocumentationInfo) {
history.home();
}

// Lint doesn't like empty dependencies. But this really should only run on the first render. So:
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<>
<Box
Expand Down
11 changes: 0 additions & 11 deletions src/Hacknet/HacknetHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { HashManager } from "./HashManager";
import { HashUpgrades } from "./HashUpgrades";

import { generateRandomContract } from "../CodingContract/ContractGenerator";
import { iTutorialSteps, iTutorialNextStep, ITutorial } from "../InteractiveTutorial";
import { Player } from "@player";
import { GetServer } from "../Server/AllServers";
import { Server } from "../Server/Server";
Expand All @@ -36,16 +35,6 @@ export function hasHacknetServers(): boolean {
}

export function purchaseHacknet(): number {
/* INTERACTIVE TUTORIAL */
if (ITutorial.isRunning) {
if (ITutorial.currStep === iTutorialSteps.HacknetNodesIntroduction) {
iTutorialNextStep();
} else {
return -1;
}
}
/* END INTERACTIVE TUTORIAL */

const numOwned = Player.hacknetNodes.length;
if (hasHacknetServers()) {
const cost = getCostOfNextHacknetServer();
Expand Down
34 changes: 16 additions & 18 deletions src/InteractiveTutorial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ enum iTutorialSteps {
Start, // Intro, overview, and housekeeping

// Hacking
GoToCharacterStatsPage,
CharacterStatsDescription,
CharacterGoToTerminalPage,
TerminalIntro,
TerminalHelp,
TerminalLs,
TerminalScan,
TerminalScanAnalyze,
TerminalScanAnalyze2,
Expand All @@ -24,17 +18,22 @@ enum iTutorialSteps {
TerminalHome,
TerminalNano,
ScriptEditorEditAndSave,
ScriptEditorRam,
ScriptEditorGoToTerminalPage,
TerminalFree,
TerminalRun,
TerminalGoToActiveScriptsPage, // Also explains a bit about running scripts
ActiveScriptsDescription,
TerminalTail,
TerminalTailOutcome,
TerminalLs,
TerminalScp,
TerminalHelp,

// Finishing off
GoToHacknetNodesPage,
HacknetNodesIntroduction,
HacknetNodesGoToWorldPage,
TerminalGoToCharacterStatsPage,
CharacterStatsDescription,
CharacterStatsGoToWorldPage,
WorldDescription,
DocumentationInfo,

Expand All @@ -48,12 +47,6 @@ const ITutorial = {
// Keeps track of whether each step has been done
stepIsDone: {
[iTutorialSteps.Start]: false,
[iTutorialSteps.GoToCharacterStatsPage]: false,
[iTutorialSteps.CharacterStatsDescription]: false,
[iTutorialSteps.CharacterGoToTerminalPage]: false,
[iTutorialSteps.TerminalIntro]: false,
[iTutorialSteps.TerminalHelp]: false,
[iTutorialSteps.TerminalLs]: false,
[iTutorialSteps.TerminalScan]: false,
[iTutorialSteps.TerminalScanAnalyze]: false,
[iTutorialSteps.TerminalScanAnalyze2]: false,
Expand All @@ -65,15 +58,20 @@ const ITutorial = {
[iTutorialSteps.TerminalHome]: false,
[iTutorialSteps.TerminalNano]: false,
[iTutorialSteps.ScriptEditorEditAndSave]: false,
[iTutorialSteps.ScriptEditorRam]: false,
[iTutorialSteps.ScriptEditorGoToTerminalPage]: false,
[iTutorialSteps.TerminalFree]: false,
[iTutorialSteps.TerminalRun]: false,
[iTutorialSteps.TerminalGoToActiveScriptsPage]: false,
[iTutorialSteps.ActiveScriptsDescription]: false,
[iTutorialSteps.TerminalTail]: false,
[iTutorialSteps.TerminalTailOutcome]: false,
[iTutorialSteps.GoToHacknetNodesPage]: false,
[iTutorialSteps.HacknetNodesIntroduction]: false,
[iTutorialSteps.HacknetNodesGoToWorldPage]: false,
[iTutorialSteps.TerminalLs]: false,
[iTutorialSteps.TerminalScp]: false,
[iTutorialSteps.TerminalHelp]: false,
[iTutorialSteps.TerminalGoToCharacterStatsPage]: false,
[iTutorialSteps.CharacterStatsDescription]: false,
[iTutorialSteps.CharacterStatsGoToWorldPage]: false,
[iTutorialSteps.WorldDescription]: false,
[iTutorialSteps.DocumentationInfo]: false,
[iTutorialSteps.End]: false,
Expand Down
15 changes: 9 additions & 6 deletions src/ScriptEditor/ui/ScriptEditorRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { checkInfiniteLoop } from "../../Script/RamCalculations";

import { Settings } from "../../Settings/Settings";
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
import { tutorialScriptName } from "../../ui/InteractiveTutorial/InteractiveTutorialRoot";
import { debounce } from "lodash";
import { GetServer } from "../../Server/AllServers";

Expand Down Expand Up @@ -194,24 +195,26 @@ function Root(props: IProps): React.ReactElement {
const preSave = options.beautifyOnSave ? beautify : () => Promise.resolve();

// this is duplicate code with saving later.
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.ScriptEditorEditAndSave) {
if (
ITutorial.isRunning &&
(ITutorial.currStep === iTutorialSteps.ScriptEditorEditAndSave ||
ITutorial.currStep === iTutorialSteps.ScriptEditorRam)
) {
//Make sure filename + code properly follow tutorial
if (currentScript.path !== "n00dles.js") {
dialogBoxCreate("Don't change the script name for now.");
if (currentScript.path !== tutorialScriptName) {
dialogBoxCreate("Don't change the script's name for now.");
return;
}
const cleanCode = currentScript.code.replace(/\s/g, "");
const expectedCleanCode = `/**@param{NS}ns*/exportasyncfunctionmain(ns){while(true){awaitns.hack("n00dles");}}`;
if (!cleanCode.includes(expectedCleanCode)) {
dialogBoxCreate("Please copy and paste the code from the tutorial!");
dialogBoxCreate("Use the code from the tutorial panel. Don't change it for now.");
return;
}

//Save the script
await preSave();
saveScript(currentScript);
Router.toPage(Page.Terminal);

iTutorialNextStep();

return;
Expand Down
20 changes: 17 additions & 3 deletions src/ScriptEditor/ui/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { DocumentationAutocomplete } from "../../Documentation/ui/DocumentationA
import { openDocumentationPopUp } from "../../Documentation/root";
import { defaultNsApiPage, openDocExternally } from "../../ui/React/Documentation";
import { DocumentationLink } from "../../ui/React/DocumentationLink";
import { iTutorialSteps, iTutorialNextStep, ITutorial } from "../../InteractiveTutorial";

type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;

Expand Down Expand Up @@ -70,14 +71,27 @@ export function Toolbar({ editor, onSave, onRun, onBeautify }: IProps) {
Beautify
</Button>
<Button
color={isUpdatingRAM ? "secondary" : "primary"}
sx={{ mx: 1, whiteSpace: "nowrap" }}
onClick={openRAMInfo}
sx={{
mx: 1,
whiteSpace: "nowrap",
color: isUpdatingRAM
? "secondary.main"
: ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.ScriptEditorRam
? "info.main"
: "primary.main",
}}
onClick={() => {
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.ScriptEditorRam) iTutorialNextStep();
openRAMInfo();
}}
>
{ram}
</Button>
<Tooltip title={parseKeyCombinationsToString(CurrentKeyBindings[ScriptEditorAction.Save])}>
<Button
color={
ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.ScriptEditorEditAndSave ? "info" : "primary"
}
onClick={() => {
onSave().catch((error) => console.error(error));
}}
Expand Down
2 changes: 1 addition & 1 deletion src/Sidebar/ui/SidebarAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export function SidebarAccordion({
<ListItem classes={li_classes} button onClick={() => setOpen((open) => !open)}>
<ListItemIcon>
<Tooltip title={!sidebarOpen ? key_ : ""}>
<Icon color={"primary"} />
<Icon color="primary" />
</Tooltip>
</ListItemIcon>
<ListItemText primary={<Typography>{key_}</Typography>} />
Expand Down
6 changes: 3 additions & 3 deletions src/Sidebar/ui/SidebarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface SidebarItemProps extends ICreateProps {
}

export const SidebarItem = memo(function SidebarItem(props: SidebarItemProps): React.ReactElement {
const color = props.flash ? "error" : props.active ? "primary" : "secondary";
const colorSelection = props.flash ? "info.main" : props.active ? "primary.main" : "secondary.main";
return (
<ListItem
classes={{ root: props.classes.listitem }}
Expand All @@ -36,12 +36,12 @@ export const SidebarItem = memo(function SidebarItem(props: SidebarItemProps): R
<ListItemIcon>
<Badge badgeContent={(props.count ?? 0) > 0 ? props.count : undefined} color="error">
<Tooltip title={!props.sidebarOpen ? props.key_ : ""}>
<props.icon color={color} />
<props.icon sx={{ color: colorSelection }} />
</Tooltip>
</Badge>
</ListItemIcon>
<ListItemText>
<Typography color={color}>{props.key_}</Typography>
<Typography sx={{ color: colorSelection }}>{props.key_}</Typography>
</ListItemText>
</ListItem>
);
Expand Down
57 changes: 35 additions & 22 deletions src/Sidebar/ui/SidebarRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,26 +127,39 @@ export function SidebarRoot(props: { page: Page }): React.ReactElement {
useCycleRerender();

let flash: Page | null = null;
switch (ITutorial.currStep) {
case iTutorialSteps.CharacterGoToTerminalPage:
case iTutorialSteps.ActiveScriptsDescription:
flash = Page.Terminal;
break;
case iTutorialSteps.GoToCharacterStatsPage:
flash = Page.Stats;
break;
case iTutorialSteps.TerminalGoToActiveScriptsPage:
flash = Page.ActiveScripts;
break;
case iTutorialSteps.GoToHacknetNodesPage:
flash = Page.Hacknet;
break;
case iTutorialSteps.HacknetNodesGoToWorldPage:
flash = Page.City;
break;
case iTutorialSteps.WorldDescription:
flash = Page.Documentation;
break;
let incrementTutorialStep = false;
if (ITutorial.isRunning) {
switch (ITutorial.currStep) {
case iTutorialSteps.ScriptEditorEditAndSave:
if (props.page !== Page.ScriptEditor) {
flash = Page.ScriptEditor;
}
break;
case iTutorialSteps.ScriptEditorGoToTerminalPage:
flash = Page.Terminal;
incrementTutorialStep = true;
break;
case iTutorialSteps.TerminalGoToActiveScriptsPage:
flash = Page.ActiveScripts;
incrementTutorialStep = true;
break;
case iTutorialSteps.ActiveScriptsDescription:
flash = Page.Terminal;
incrementTutorialStep = true;
break;
case iTutorialSteps.TerminalGoToCharacterStatsPage:
flash = Page.Stats;
incrementTutorialStep = true;
break;
case iTutorialSteps.CharacterStatsGoToWorldPage:
flash = Page.City;
incrementTutorialStep = true;
break;
case iTutorialSteps.WorldDescription:
flash = Page.Documentation;
incrementTutorialStep = true;
break;
}
}

const augmentationCount = Player.queuedAugmentations.length;
Expand Down Expand Up @@ -194,11 +207,11 @@ export function SidebarRoot(props: { page: Page }): React.ReactElement {
} else {
throw new Error("Can't handle click on Page " + page);
}
if (flash === page) {
if (flash === page && incrementTutorialStep) {
iTutorialNextStep();
}
},
[flash],
[flash, incrementTutorialStep],
);

/**
Expand Down
Loading
Loading