Finished the tutorial and wondering how to progress? Want to improve your hacking script or maybe you want to start automating other parts of the game?
This is a spoiler free guide that points you in the right direction.
Hacking scripts: How to improve
In addition the the ingame tutorial, there’s a good guide on how to get a decent hacking script started in the online documentation.
At this point you have a script that will continuously weaken, grow and hack a given server. You might think it’s slow (and you’d be right) and that’s because there are several improvements you can make.
When writing scripts you might notice that their ram requirements increase as you use more ns functions. Since only weaken() grow() and hack() benefit from using additional threads, separating them from everything else will let you run more threads and thus gain a higher payoff.
At this point it’s worth having the API documentation handy.
To let us run our important functions with as many threads as possible, figure out how to make the simplest possible script that will run only weaken() on a target given by argument and nothing more. Then take your hacking script from the tutorial, and instead of running weaken() directly, find a way to run the weaken script and passing the target to it as an argument, using as many threads as free ram allows. Then, find a way to wait until it finishes. Repeat this process for grow() and hack().
Because we now only use a small fraction of our RAM on control with 1 thread, we can spend the entire rest of our RAM on running the functions that actually care about threads, with as many threads as possible. This can more than double your income.
If you deploy this hacking script to each server you have root on, you should be progressing quite well. But if we analyze ram usage on our rooted servers, we see that the actual weaken.ns, grow.ns and hack.ns scripts don’t use all the available ram because the control script takes up quite a chunk. But if we are just attacking the most profitable target with all of these servers of ours anyway, why not stick to a single control script on one server and let it control the others?
The goal here is to write a control script that we run on our home computer, which can spawn weaken.ns grow.ns and hack.ns on other servers – leaving us with all their memory free for doing important jobs. If the control script takes approximately twice the ram of a single thread of weaken.ns, grow.ns or hack.ns, we get 2 additional threads on each of our rooted servers for free by using this technique. In the early game when most of your ram comes from random servers you’ve rooted, this can count for quite an increase.
In general for optimizations, it’s important to measure what parts of our algorithms has the longest impact on performance. Let’s assume we’ve gotten to the point where a server is prepped (min security and max money reached) so that our loop is approximately weaken -> grow -> weaken -> hack.
Start by printing to log the time spent on each step. In my case, the obvious time sink was the weaken directly after grow, because the grow increased security significantly. What if we could start weakening while the grow is in progress, thus doing the tasks in parallel? We actually can:
The time taken by weaken(), grow() and hack() is calculated by the server and player status at the start of the operation. The effect happens at the end. Thus, if we start our weaken before the grow finishes, it will be way faster. Figure out a way to see how long weaken() and grow() will take (hint: the documentation has functions for this). Then instead of using all available memory for starting grow, use half. Then start weaken with the other half. If weaken would run faster, you need to sleep your script a bit before you run weaken.
Note that the optimal split is likely far from 50/50. You can either experiment with the ratio, or use the analyze functions from the documentation to calculate the optimal split so that the weaken has just enough power to counteract the effect of the grow.
grow() grows the server by a certain % of it’s current money. Ideally, we want to make sure that a single grow() will bring it back up to full. Find a way to calculate how many threads of hack and grow you need to keep the cycle short.
The last and hardest optimization to consider is to batch an entire cycle and launch them simultaneously, so that hack() grow() and weaken() all hit within a short time of eachoter. If you manage this, you can take great advantage of larger servers in the later game, because a single full-threaded hack will remove all money, leaving you a long time to rebuild it’s stash. If you instead queue several batches of scripts that all hit after one another and steal a smaller % of the money, you gain a lot more money over time per GB ram than otherwise.
This last optimization however is a non trivial problem, and requires extensive planning, analysis and refactoring to get right.
Finding and cracking servers: Get more ram for attacking or a juicier target
Once a server is cracked, you can decide what to do with it:
- An easy first step is to ns.tprint() the name of the server so you are aware.
- Another is to copy and run hacking scripts to it so it can immediately start gaining you money.
- A third is to make a ranking of all possible hacking targets, sort them by some metric and either print the result, or redirect all your servers to hack the new target if it is better than your old one. A simple heuristic is max money divided by min security. A more precise one is max money divided by time it would take to hack, grow back and weaken down, functions for which can be found in the documentation.
- Bitburner: Time Calculation Script (How to Get the Time)
- Bitburner: Early Hacknet Auto Management Script
- Bitburner: How to Add Custom Stats to the HUD (Heads up Display)
- Bitburner: Automation for Hacknet Nodes
- Bitburner: Combat Gang Management Script (Fully Automatic)