Simple Bot that uses math to choose the most profitable upgrade.
How It Works
Bot takes the following steps.
- Checks cost and production growth of all the possible upgrades
- Calculates profitable ratio of each upgrade
- Sorts elements by ratio descending
- Chooses the first element
- Checks if you can purchase upgrade now, if not, it waits to collect money
- Checks if you can buy new node in less than 30 seconds (you can customize this time), if so, it buys it
- Repeat…
Profitable ratio = Production growth / upgrade cost
Production growth = Production after upgrade – current production
This guide is based on my previous “Automation for Hacknet Nodes”.
How to Use
Take the following steps.
- Run the terminal
- Type ‘nano hacknet-bot.js’
- Copy and paste the code below into this file
- Save the file (ctrl + s)
- Back to the terminal
- Type ‘run hacknet-bot.js’
Code
/** @param {NS} ns **/ export async function main(ns) { // helpers const getMoney = () => ns.getPlayer().money; const getProd = (level, ram, cores) => (level * 1.5) * Math.pow(1.035, ram - 1) * ((cores + 5) / 6); // your production multiplier const PROD_MULTIPLIER = ns.getHacknetMultipliers().production; // maximum waiting time for collecting money for new node (default 30s) const WAITING_TIME = ns.args[0] || 30; while (true) { const ratios = []; let hacknetProduction = 0; // loop through all nodes for (let index = 0; index < ns.hacknet.numNodes(); index++) { // get current node stats const { level, ram, cores, production } = ns.hacknet.getNodeStats(index); hacknetProduction += production; // get upgrades cost const levelUpgradeCost = ns.hacknet.getLevelUpgradeCost(index); const ramUpgradeCost = ns.hacknet.getRamUpgradeCost(index); const coreUpgradeCost = ns.hacknet.getCoreUpgradeCost(index); // get prod. growth / cost ratios const levelUpgradeRatio = ((getProd(level + 1, ram, cores) * PROD_MULTIPLIER) - production) / levelUpgradeCost; const ramUpgradeRatio = ((getProd(level, ram * 2, cores) * PROD_MULTIPLIER) - production) / ramUpgradeCost; const coreUpgradeRatio = ((getProd(level, ram, cores + 1) * PROD_MULTIPLIER) - production) / coreUpgradeCost; // possible upgrades of current node const currentNodeUpgrades = [ {ratio: levelUpgradeRatio, cost: levelUpgradeCost, nodeIndex: index, upgrade: "level"}, {ratio: ramUpgradeRatio, cost: ramUpgradeCost, nodeIndex: index, upgrade: "ram"}, {ratio: coreUpgradeRatio, cost: coreUpgradeCost, nodeIndex: index, upgrade: "core"} ]; // push current node upgrades to all upgrades ratios.push(...currentNodeUpgrades); } // get the most profitable upgrade const { cost, nodeIndex, upgrade } = ratios.sort((a, b) => b.ratio - a.ratio)[0]; // wait until you have the money for upgrade while (getMoney() < cost) { await ns.sleep(1); } // execute upgrade switch (upgrade) { case "level": await ns.hacknet.upgradeLevel(nodeIndex); break; case "ram": await ns.hacknet.upgradeRam(nodeIndex); break; case "core": await ns.hacknet.upgradeCore(nodeIndex); break; default: continue; } // check if you can purchase new node const purchaseNodeCost = ns.hacknet.getPurchaseNodeCost(); const missingMoneyForNewNode = purchaseNodeCost - getMoney(); if (missingMoneyForNewNode < 0) { ns.hacknet.purchaseNode(); } // else check if you can buy new node in less than WAITING_TIME (default 30s) else if (missingMoneyForNewNode < hacknetProduction * WAITING_TIME) { while (getMoney() < purchaseNodeCost) { await ns.sleep(1); } ns.hacknet.purchaseNode(); } // sleep 1ms to prevent crash because of infinite loop await ns.sleep(1); } }
You can customize the time of waiting for purchase node (by default 30s) by passing an additional script argument. For example:
run hacknet-bot.js 120
This is all about Bitburner – Optimized Hacknet Bot; I hope you enjoy reading the Guide! If you feel like we should add more information or we forget/mistake, please let us know via commenting below, and thanks! See you soon!
- All Bitburner Posts List
Nice!
I started using it and came upon a problem when all hacknodes are maxed out.
The script gets stuck in the waiting for money loop before the switch.
To fix it I added a “if (cost != Infinity) {” involving the while and the switch.
I also added some prints to see what the script is doing in the logs.
/** @param {NS} ns **/export async function main(ns) {
ns.disableLog(‘sleep’)
// helpers
const getMoney = () => ns.getPlayer().money;
const getProd = (level, ram, cores) => (level * 1.5) * Math.pow(1.035, ram – 1) * ((cores + 5) / 6);
// your production multiplier
const PROD_MULTIPLIER = ns.getHacknetMultipliers().production;
// maximum waiting time for collecting money for new node (default 30s)
const WAITING_TIME = ns.args[0] || 30;
while (true) {
const ratios = [];
let hacknetProduction = 0;
// loop through all nodes
for (let index = 0; index b.ratio – a.ratio)[0];
ns.print(“Cost: “, cost)
if (cost != Infinity) {
ns.print(`Gonna buy ${upgrade} for ${ns.nFormat(cost, “$0.000a”)}`)
// wait until you have the money for upgrade
while (getMoney() < cost) {
await ns.sleep(1);
}
// execute upgrade
switch (upgrade) {
case "level":
await ns.hacknet.upgradeLevel(nodeIndex);
break;
case "ram":
await ns.hacknet.upgradeRam(nodeIndex);
break;
case "core":
await ns.hacknet.upgradeCore(nodeIndex);
break;
default:
continue;
}
}
// check if you can purchase new node
const purchaseNodeCost = ns.hacknet.getPurchaseNodeCost();
const missingMoneyForNewNode = purchaseNodeCost – getMoney();
ns.print("MissingMoneyForNewNode: ", ns.nFormat(missingMoneyForNewNode, "$0.000a"))
if (missingMoneyForNewNode < 0) {
ns.hacknet.purchaseNode();
}
// else check if you can buy new node in less than WAITING_TIME (default 30s)
else if (missingMoneyForNewNode < hacknetProduction * WAITING_TIME) {
while (getMoney() < purchaseNodeCost) {
await ns.sleep(1);
}
ns.hacknet.purchaseNode();
}
// sleep 1ms to prevent crash because of infinite loop
await ns.sleep(1);
}
}
hi tracer!
thanks for your fix, could you paste your script into a pastebin or something like that?
i’m getting issues when copying your comment and rewriting the parts that show syntax errors due to incorrect formatting. must be something im missing.
have a good one