- Allocate resources from one server to work on another.
- Weaken and grow first, before beginning to hack.
- Allocate resources toward the most efficient available task, subject to some allowances for early progression.
- Minimize RAM usage (scheduling overhead of around 30GB).
I designed a system with three main components:
- A spider to find and hack servers.
- A distributor to coordinate work among the available owned servers.
- Two simple workers.
The spider is very straightfoward, as you will see below in spider2.js. It uses a breadth first search across the nodes starting from home, hacking any nodes we have the capability to. It stores the hacked node list in a newline separated file, so that other scripts don't have to invoke a function or spend precious CPU time reconstructing the list.
The distributor is the most interesting part. The distributor consists of a loop that
- cancels all existing distributor controlled workers,
- schedules new workers, then
- awaits a signal that something material has changed.
We cancel all existing workers because it is easier to solve this problem if you don't have to keep track of state. Netscripts programming capabilities are some of the most challenging and inconsistent I've ever worked with, so I want to write as little complex code as possible. Cancelling all our existing workers has some minor drawbacks in terms of performance, but what it wins us in simplicity dominates such considerations. We'll be able to spend more time thinking about algorithmic improvements if we don't have to do fiddly things like managing state.
The new worker scheduling algorithm currently has two basic priorities. The first priority is to focus on weakening the weakest pending node. It iterates through the targets in the order the spider observed them (i.e. generally weakest first). If it encounters any that are significanly more secure than their minimum security level, it will dedicate as many threads as possible among all the hosts to weakening that server. It also spawns a small watcher script to notify the distributor when a node like this has been weakened down to the minimum level.
Currently, I only do this preparation step for security level, but I should probably also grow servers before beginning to hack them. That's a TODO for tomorrow night.
The second priority is to schedule "flexihack" workers. We try to schedule these backwards in the targets list, focusing on the highest growth servers first. I found the task of balancing grow and hack calls tedious, so my flexihack worker calls grow and hack adaptively (when the available money drops below 95% of max, grow is called). We also schedule a small group of flexihack workers on any totally weakened target, even if it's not the most optimal one, so that we can at least have some income from hacking early on. My current stance is to use one weaken worker per six flexihack workers, which seems to be about as much as is required to keep up with either six grow threads or six hack threads.
The signal can come from either the spider, when it gains enough strength to hack a new server, or the watcher, when a server has been sufficiently weakened (or, soon, grown). You can also run a small script called "signal.script" to manually reschedule (e.g. if you have bought servers manually, or grown your home server's RAM). The signal is just the presence of a certain file on the home computer.
My weaken worker is trivial.
flexihack costs about .5 GB more RAM than hack and grow separately, but that isn't even an order of magnitude. It's totally worth the gain in simplicity. To prevent overshooting hack/grow thresholds, we schedule flexihack workers in small batches. We accomplish this by adding a final, meaningless tag argument to the flexihack.script invocation, and using scriptKill to kill flexihack. flexihack keeps server money at about 95% of max.
I'm not sure whether any of this is really optimal, since I'm just playing around with this new system. I think the work scheduling stuff is pretty useful, but I'm not sure about the prioritization. That said, it's fun to talk about code, even when it's incorrect!
Please see the source code listings for all non-trivial scripts. I'd love to hear criticism, but try to only base it on things I'm likely to already know about the game as someone who has been playing it for two days! :) Pointers on how to write better JS are super helpful, since I've never spent much time in this language before.
there's some spots where u used script instead of .js
ex:
spider2.js
import {signal} from "hack-dist.script";
function prep(target) {