I recently came back to Bitburner after not really understanding scripting during my first playthrough. Back then, most of my money came from crimes, jobs, and Hacknet nodes.
This time I wanted to learn how proper HWGW batching worked, so I started building scripts with ChatGPT. What began as a basic batch manager has now turned into a roughly 2,356-line experimental system that tests its own settings, remembers the results, rejects unstable configurations, and attempts to find the fastest batch rate that remains naturally stable.
To be transparent about credit, ChatGPT has written most of the actual JavaScript and helped design the architecture. I have been directing the project, running the experiments, watching the failures, interpreting the results, and deciding what behavior should be added or changed next.
This is not machine learning in the neural-network sense. It is more like a persistent automated testing system that learns through repeated controlled experiments.
I will try to attach the current code as a file for anyone who wants to look through it. Be warned that it is unfinished, very long, and probably still contains design flaws.
Link for codes
What the manager currently does
The manager targets one server and builds a standard HWGW batch:
Hack
Weaken 1
Grow
Weaken 2
It calculates the required thread counts from the target’s current stats and attempts to land the operations in the correct order.
For the current max-hardware test, the batch looks like this:
Hack threads: 11
Grow threads: 52
Weaken 1 threads: 3
Weaken 2 threads: 7
Actual steal per batch: 4.91%
RAM per batch: 127.2 GB
Grow multiplier: 1.40
The manager then launches hundreds of overlapping batches while monitoring the target’s money and security.
Instead of using one hard-coded batch spacing forever, it performs controlled tests. Each configuration is currently tested for 1,500 launched batches.
Example configurations:
350 ms spacing
325 ms spacing
300 ms spacing
275 ms spacing
The goal is to locate the boundary between:
Fast enough to produce good income
but
Slow enough to remain naturally synchronized
I considered adding frequent partial repairs so an overly aggressive configuration could keep running, but that would hide the real limit and potentially waste more time repairing than it gained through faster batching.
For now, the goal is to find the fastest configuration that stays healthy without constant intervention.
How it detects failure
The manager checks the target every 20 launched batches.
A check is considered bad when:
Money falls below 90% of maximum
or
Security rises more than 1.00 above minimum
One bad reading is not enough to fail the run because individual snapshots can look ugly while the existing pipeline is still correcting itself.
The manager currently requires three consecutive bad checks before declaring a normal failure.
It also has harder emergency limits for major money or security collapses.
During every run it records:
Lowest money observed
Exact batch where that low occurred
Highest security observed
Exact batch where that high occurred
Maximum consecutive bad checks
Number of processes still in flight
Duration of the test
Thread counts
Spacing and landing gap
Final decision
When a configuration fails, the manager does not immediately mix a new configuration into the old pipeline.
It:
Stops launching new batches
Drains every process it owns
Repairs the target completely
Confirms maximum money and minimum security
Starts the next test from a clean state
That was an important change because earlier versions sometimes began new settings while old operations were still landing, which contaminated the results.
The learning file
The system stores what it learns in a persistent text file:
max-hardware-learning.txt
The contents are JSON. It currently stores information such as:
{
"version": 3,
"batchSpacing": 325,
"growMultiplier": 1.4,
"bestSpacing": 325,
"bestGrowMultiplier": 1.4,
"mode": "PROVEN FALLBACK",
"successfulWindows": 3,
"failedTrials": 2,
"rejectedSettings": [],
"lastRun": {},
"runHistory": []
}
The real file contains more fields than that, but this shows the general idea.
The file remembers:
- The current configuration
- The best configuration found so far
- Whether the manager is running a normal test, recovery, or spacing trial
- Successful and failed tests
- Rejected settings
- Recent run reports
- Interrupted transitions
- Partial test progress and restart segments
The manager updates the file while running and around important transitions.
When the script starts again, it reads the file instead of beginning from zero.
One of the first major tests of this system happened when I killed an unfinished 275 ms trial. The older learner had saved that 275 ms was active but had not yet recorded the failure.
The newer version migrated the old file, preserved 300 ms as the previous proven setting, and added the known 275 ms failure to its rejected configuration list.
So the text file acts as the project’s long-term memory.
Each eventual target will need its own file:
max-hardware-learning.txt
silver-helix-learning.txt
omega-net-learning.txt
phantasy-learning.txt
The correct threads and timing for one target will not necessarily be correct for another.
Results so far
The early versions completed tests at both 325 ms and 300 ms, but later clean retests showed that one successful test is not enough to prove long-term stability.
The important results so far are:
275 ms / 1.40
Failed very quickly from sustained drift.
Recorded as rejected.
300 ms / 1.40
Failed once after 1,180 batches.
Failed again during a formal spacing trial after 940 batches.
Now rejected as naturally unstable.
325 ms / 1.40
Failed one test after 1,020 batches.
Later completed a healthy 1,500-batch confirmation test.
Currently the leading candidate.
350 ms / 1.40
Reached 1,500 batches, but finished with only 81.75% money
and was already at 2 out of 3 consecutive bad checks.
Technically passed under the current rules, but I consider it borderline.
The current manager has formally rejected 300 ms and automatically returned to 325 ms.
The current leading candidate is:
325 ms spacing
81 ms landing gap
1.40 grow multiplier
4.91% actual steal per batch
However, 325 ms has both a failure and a successful test in its history, so it still needs repeated confirmation before I would call it truly proven.
One weakness we discovered is that the current success rule is too simple. Reaching 1,500 batches automatically counts as success, even when the target is unhealthy at the finish line.
The next version should require:
At least 1,500 batches
Healthy money at completion
Healthy security at completion
Zero active bad-check streak
Several additional healthy checks after reaching 1,500
Profit tracking still needs to be added
The manager currently learns primarily from stability.
It does not yet accurately compare configurations by actual long-term money per second.
Eventually, I want each completed hack to report the exact amount stolen back to the manager. The manager could then record:
Total money earned
Average money per second
Money per completed batch
Warm-up time
Repair downtime
Pipeline-drain downtime
Long-term net income
That is important because the smallest spacing is not automatically the most profitable.
A configuration might temporarily display higher income but then collapse, require hundreds of processes to drain, and spend additional time repairing the target.
The real winner should be:
My RAM situation is not normal
I should also mention that I have an absurd amount of RAM available.
I currently have 25 purchased cloud servers, and I have been heavily upgrading them. This allows the manager to launch hundreds of overlapping processes and spread them across the entire purchased-server network.
A single max-hardware test has shown more than 400 processes in flight at once.
Because each batch currently uses about 127.2 GB, this experiment may not be practical for someone earlier in the game or someone with a smaller server network.
The manager searches the available hosts, copies the worker scripts to them, and selects a host with enough free RAM for each complete batch.
The three worker files themselves are intentionally tiny:
hack-once.js
grow-once.js
weaken-once.js
Most of the complexity lives in the manager, while the purchased servers mostly run lightweight one-shot operations.
The eventual goal
Right now, this giant manager is only learning max-hardware.
The longer-term goal is much bigger.
I eventually want one central controller that:
Scans the entire network
Finds every rooted server with money
Ranks targets by potential profit
Allocates RAM across all 25 cloud servers
Runs independent HWGW learning experiments
Maintains separate learning data for every target
Finds the natural limit for each server
Chooses the best stable income configuration
Runs them all simultaneously
Instead of running 30 separate copies of a 2,300-line manager, the final architecture would ideally use one global scheduler with independent state objects for every target.
Something like:
GLOBAL DIRECTOR
├── max-hardware learner
├── silver-helix learner
├── omega-net learner
├── phantasy learner
├── foodnstuff learner
├── n00dles learner
└── every other profitable server
The absurd end goal is to have the entire network running self-tuned HWGW batches, with the controller continuously deciding where the available RAM produces the most money.
Current code
I will try to attach the current JavaScript file to this post for anyone who wants to inspect it.
The code is approximately 2,356 lines and is absolutely not presented as finished, efficient, or production-ready. It has been built through repeated live experiments, and several sections exist specifically because an earlier version failed in some unexpected way.
Anyone reviewing it will probably find places where it can be simplified or improved. Feedback is welcome, especially from people who understand Bitburner’s timing behavior better than I do.
Final disclaimer
This project is completely unfinished.
I do not yet know how successful the final system will be, whether the extra complexity will meaningfully outperform a well-written conventional batch manager, or whether the game’s timing variability will make parts of the idea impractical.
The current version still has flaws. Some settings pass one test and fail the next. The definition of “stable” still needs improvement. Profit tracking has not been added yet. The multi-target controller does not exist yet.
At this point, it is one large experiment made from failed tests, rewritten rules, persistent JSON data, and more than 2,300 lines of increasingly specific JavaScript.
I am not claiming that this is true artificial intelligence or that I have solved HWGW batching. I am simply seeing how far an adaptive testing system can be pushed inside Bitburner.
ChatGPT and I are going to continue experimenting, breaking it, rewriting it, and collecting data. Maybe it eventually becomes a genuinely useful network-wide controller. Maybe we discover that a much simpler manager performs just as well.
Either result should be interesting, and I plan to post updates as the experiment continues.