Skip to content

Commit

Permalink
BN9 tweaks
Browse files Browse the repository at this point in the history
- Configurable threshold for when to spend hashes to boost server income
- Always spend hashes to boost income in BN9
- Fix premature toasts when our next purchase costs more than current hash capacity
  • Loading branch information
alainbryden committed Dec 5, 2024
1 parent dfa7d9a commit c7cccc2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
11 changes: 8 additions & 3 deletions autopilot.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
log, getFilePath, getConfiguration, instanceCount, getNsDataThroughFile, runCommand, waitForProcessToComplete,
getActiveSourceFiles, tryGetBitNodeMultipliers, getStocksValue, unEscapeArrayArgs,
formatMoney, formatDuration, getErrorInfo, tail
formatMoney, formatDuration, formatNumber, getErrorInfo, tail
} from './helpers.js'

const argsSchema = [ // The set of all command line arguments
Expand All @@ -22,6 +22,7 @@ const argsSchema = [ // The set of all command line arguments
['disable-wait-for-4s', false], // If true, will doesn't wait for the 4S Tix API to be acquired under any circumstantes
['disable-rush-gangs', false], // Set to true to disable focusing work-for-faction on Karma until gangs are unlocked
['disable-casino', false], // Set to true to disable running the casino.js script automatically
['spend-hashes-on-server-hacking-threshold', 0.1], // Threshold for how good hacking multipliers must be to merit spending hashes for boosting hack income. Set to a large number to disable this entirely.
['on-completion-script', null], // Spawn this script when we defeat the bitnode
['on-completion-script-args', []], // Optional args to pass to the script when we defeat the bitnode
['xp-mode-interval-minutes', 55], // Every time this many minutes has elapsed, toggle daemon.js to runing in --xp-only mode, which prioritizes earning hack-exp rather than money
Expand Down Expand Up @@ -503,7 +504,10 @@ export async function main(ns) {
'/Temp/getServerRequiredHackingLevel-all.txt', incomeByServer.map(s => s.hostname));
const [bestServer, gain] = incomeByServer.filter(s => dictServerHackReqs[s.hostname] <= player.skills.hacking)
.reduce(([bestServer, bestIncome], target) => target.gainRate > bestIncome ? [target.hostname, target.gainRate] : [bestServer, bestIncome], [null, -1]);
if (bestServer && gain > 1) {
const spendHashesMultThreshold = options['spend-hashes-on-server-hacking-threshold'];
// If hacking gain multipliers are too low, assume the bitnode is meant to be won a different way and don't bother wasting hashes on boosting hack income
// The exception is that in BN9, despite high penalties, we're definitely meant to spend hashes to boost hack income
if (bestServer && (gain > spendHashesMultThreshold || resetInfo.currentNode == 9)) {
// Check whether we should be spending hashes to reduce minimum security
const serverMinSecurity = await getNsDataThroughFile(ns, 'ns.getServerMinSecurityLevel(ns.args[0])', null, [bestServer]);
const shouldReduceMinSecurity = serverMinSecurity > 2; // Each purchase reduces by 2%. Can't go below 1, but not worth the cost to keep going below 2.
Expand All @@ -525,7 +529,8 @@ export async function main(ns) {
launchScriptHelper(ns, 'spend-hacknet-hashes.js', spendHashesArgs);
}
} else if (gain <= 1)
log_once(ns, `INFO: Hack income is currently too severely penalized to merit launching spend-hacknet-hashes.js to boost servers.`);
log_once(ns, `INFO: The best server (${bestServer})'s hack income multiplier (${formatNumber(gain)}) is currently too severely penalized ` +
`(< ${spendHashesMultThreshold}) to merit launching spend-hacknet-hashes.js to boost servers. (Configure with --spend-hashes-on-server-hacking-threshold)`);
else
log(ns, `WARNING: strServerIncomeInfo was not empty, but could not determine best server:\n${strServerIncomeInfo}`);
}
Expand Down
19 changes: 13 additions & 6 deletions spend-hacknet-hashes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const argsSchema = [
['spend-on-server', null], // The server to boost, for spend options that take a server argument: 'Reduce Minimum Security' and 'Increase Maximum Money'
['no-capacity-upgrades', false], // By default, we will attempt to upgrade the hacknet node capacity if we cannot afford any purchases. Set to true to disable this.
['reserve', null], // The amount of player money to leave unpent when considering buying capacity upgrades (defaults to the amount in reserve.txt on home)
['ignore-reserve-if-upgrade-cost-less-than-pct', 0.01], // Hack to purchase capacity upgrades regardless of the curent global reserve if they cost less than this fraction of player money
['reserve-buffer', 1], // To avoid wasting hashes, spend if would be within this many hashes of our max capacity on the next tick.
['max-purchases-per-loop', 10000], // When we're producing hashes faster than we can spend them, this keeps things from getting hung up
];
Expand Down Expand Up @@ -152,11 +153,14 @@ export async function main(ns) {
`from capacity, but were only looking to reserve ${formatHashes(hashesEarnedNextTick)} hashes (earning ${formatHashes(globalProduction)} hashes/sec).`;
else
continue; // Current hash capacity suffices, go back to sleep
// If we aren't allowed to purchase capacity upgrades by configuration, we may need to warn the user if we're running out of space
if (options['no-capacity-upgrades']) { // If we aren't allowed to purchase capacity upgrades by configuration, we may need to warn the user if we're running out of space

// If we aren't allowed to purchase capacity upgrades by configuration (or can't afford it),
// we may need to warn the player via toast notification so that they can intervene.
// Don't create a toast notification unless we're nearing our capacity limit and at risk of wasting hashes.
const warnToast = remaining < hashesEarnedNextTick ? 'warning' : undefined;
if (options['no-capacity-upgrades']) { // If we aren't allowed to purchase capacity upgrades by configuration, warn the user so they can intervene
log(ns, `WARNING: Upgrade your hacknet cache! spend-hacknet-hashes.js --no-capacity-upgrades is set, ` +
`so we cannot increase our hash capacity. ${capacityMessage}`, false,
remaining < hashesEarnedNextTick ? 'warning' : undefined); // Only warn via toast if we are running out of capacity
`so we cannot increase our hash capacity. ${capacityMessage}`, false, warnToast);
} else { // Otherwise, try to upgrade hacknet capacity so we can save up for more upgrades
if (!notifiedMaxCapacity) // Log that we want to increase hash capacity (unless we've previously seen that we are maxed out)
log(ns, `INFO: ${capacityMessage}`);
Expand All @@ -168,7 +172,9 @@ export async function main(ns) {
const nextNodeCost = ns.hacknet.getPurchaseNodeCost();
const reservedMoney = options['reserve'] ?? Number(ns.read("reserve.txt") || 0);
const playerMoney = ns.getServerMoneyAvailable('home');
const spendableMoney = Math.max(0, playerMoney - reservedMoney);
const spendableMoney = Math.max(0, playerMoney - reservedMoney,
// Hack: Because managing global reserve is tricky. We tend to always want to purchase cheap upgrades
playerMoney * options['ignore-reserve-if-upgrade-cost-less-than-pct']);
// If it's cheaper to buy a new hacknet node than to upgrade the cache of an existing one, do so
if (nextNodeCost < nextCacheUpgradeCost && nextNodeCost < spendableMoney) {
if (ns.hacknet.purchaseNode())
Expand Down Expand Up @@ -205,7 +211,8 @@ export async function main(ns) {
if (Number.isFinite(nextCheapestCacheIncreaseCost)) {
if (playerMoney > nextCheapestCacheIncreaseCost)
message += ' Feel free to manually purchase this upgrade (despite the reserve/budget) if you deem it worthwhile.'
log(ns, `WARNING: spend-hacknet-hashes.js ${message}`, false, 'warning');
log(ns, `WARNING: spend-hacknet-hashes.js ${message}`, false, warnToast);

} else if (nextPurchaseCost > capacity) // If we can't afford anything, and have maxed our hash capacity, we may as well shut down.
return log(ns, `SUCCESS: We've maxed all purchases. ${message}`); // Shut down, because we will never be able to buy anything further.
else if (!notifiedMaxCapacity) { // The first time we discover we are at max hash capacity (infinite cost) notify the user
Expand Down

0 comments on commit c7cccc2

Please sign in to comment.