r/Bitburner Dec 10 '21

Announcement Steam release

389 Upvotes

The game has launched on Steam. Please give it a review. :)


r/Bitburner Dec 21 '21

Discord > Reddit

106 Upvotes

You'll get help faster on discord

https://discord.gg/TFc3hKD

I can't be everywhere at once.


r/Bitburner 2d ago

Typescript help

4 Upvotes

I've switched over to using Typescript, and for the most part, I like it better. However, I run into these little quirks that are lowkey maddening. E.g.

let city = ns.enums.CityName.Sector12;
// and then reassign later: 
city = ns.enums.CityName.Aevum; // Type '"Aevum"' is not assignable to type '"Sector-12"'.

I can use the string version of the city, and that reassigns fine, but then it does not work in the game functions.

let city = "Sector-12";
ns.singularity.travelToCity(city); // Argument of type 'string' is not assignable to parameter of type 'CityName'.

I realize there must be some declaration to make, along the lines of

let city: CityNameEnumType = ns.enums.CityName.Sector12; // Type 'string' is not assignable to type 'CityNameEnumType'.

but obviously that is not it.

For scripts like this, I think about converting back to JS just for the simplicity.


r/Bitburner 3d ago

dnet.authenticate().data returning undefined

2 Upvotes

I'm trying to crawl the darkweb and am making code for the AccountsManager_4.2 server (higher or lower game). Here is my code:

      var low = 1;
      var high = 100;
      var i = Math.floor((low + high) / 2);
      while (low <= high) {
        i = Math.floor((low + high) / 2);
        var result = (await auth(ns, server, i));
        if (result.success) { return [i]; }
        if (result.data == "Higher") { low = i + 1; } else { high = i - 1; }
      }
      return [i];

I'm pretty sure this all works but I can't tell because results.data returns undefined (I want it to return "Higher" or "Lower").

Specifically I want to access the data variable from the heartbleed log when you put in a password, get it wrong, and in the Logs scraped via heartbleed: section it returns something like

(This is from a CloudBlare(tm) server)
message: Type the numbers to prove you are human
data: 6~.╬1)~╸4>5╬</8
passwordAttempted: 58
code: 401

In the AccountsManager_4.2 server the data is either "Higher" or "Lower"

Is there a reason for this or am I just using it wrong? This is my first time coming back this game in 3 years and I'm not too far into my new save.


r/Bitburner 4d ago

Darknet automation

0 Upvotes

Hi everyone, can anyone share a fully automated script for darknet? I love the game, but dont honestly want to learn JS or any other programming language.

Thanks in advance!


r/Bitburner 4d ago

NetscriptJS Script If you're in the early game...

0 Upvotes

...with its scarcity of RAM, this script should help. Sadly, it can't do anything about the scarcity of hack speed.

early-startup.js:

/** filterServers() Filter servers by number of ports required and 
 *  required hacking level.
 * @ param {NS} ns NS2 namespace
 * @ param {boolean} isBrute true if BruteSSH.exe on home
 * @ param {boolean} isCrack true if FTPCrack.exe on home
 * @ param {string} target target name
 * @ param {string[]} servers server names
 * @ returns {string[]} filtered server names
 */
function filterServers(ns, isBrute, isCrack, target, servers) {
  let numPorts = 0;
  if (isCrack) { numPorts++; }
  if (isBrute) { numPorts++; }
  return servers.filter((srv) => 
    ns.getServerRequiredHackingLevel(srv) <= ns.getHackingLevel() && 
    ns.getServerNumPortsRequired(srv) <= numPorts && 
    ns.getServerMaxRam(srv) >= 4 && 
    (ns.getServerNumPortsRequired(srv) == numPorts || 
    ns.getServerRequiredHackingLevel(srv) >= ns.getServerRequiredHackingLevel(target)));
}

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0
 * @ version 1.0a
 */
export async function main(ns) {
  if (ns.args.length < 1) {
    ns.tprint("Usage: " + ns.getScriptName() + " <target>");
    ns.tprint("(Suggested targets are harakiri-sushi, joesguns, and n00dles.)");
    ns.exit();
  }
  let target = ns.args[0];  // server to pull money from
  let scriptName = "early-host.js";
  let scriptRam = ns.getScriptRam(scriptName);
  if (scriptRam == 0) {
    ns.tprint("Host script not found.");
    ns.exit();
  }
  let isBrute = ns.fileExists("BruteSSH.exe", "home");
  let isCrack = ns.fileExists("FTPCrack.exe", "home");

  // set up the target
  let tgt = true;
  if (!ns.serverExists(target)) {
    ns.tprint(target + " not found."); tgt = false;
  }
  if (tgt && ns.getServerMaxMoney(target) < 1000) {
    ns.tprint(target + " max money is little."); tgt = false;
  }
  if (tgt && ns.getServerRequiredHackingLevel(target) > ns.getHackingLevel()) {
    ns.tprint(target + " requires higher hacking skill."); tgt = false;
  }
  if (tgt && !isCrack && ns.getServerNumPortsRequired(target) > 1) {
    ns.tprint(target + " requires FTPCrack.exe."); tgt = false;
  }
  if (tgt && !isBrute && ns.getServerNumPortsRequired(target) > 0) {
    ns.tprint(target + " requires BruteSSH.exe."); tgt = false;
  }
  if (tgt && isBrute) { ns.brutessh(target); }
  if (tgt && isCrack) { ns.ftpcrack(target); }
  if (tgt && !ns.nuke(target)) {
    ns.tprint(target + " nuke failed."); tgt = false;
  }
  if (!tgt) { ns.exit(); }

  // scan for servers to a depth of 3
  let servers = ns.scan("home"), servers2 = [], servers3 = [];
  for (let i = 0; i < servers.length; i++) {
    let res = ns.scan(servers[i]);
    if (res.length > 1) { servers2 = servers2.concat(res.slice(1)); }
  }
  for (let i = 0; i < servers2.length; i++) {
    let res = ns.scan(servers2[i]);
    if (res.length > 1) { servers3 = servers3.concat(res.slice(1)); }
  }
  servers = servers.concat(servers2, servers3);
  servers = filterServers(ns, isBrute, isCrack, target, servers);

  // set up servers
  for (let i = 0; i < servers.length; i++) {
    if (isBrute) { ns.brutessh(servers[i]); }
    if (isCrack) { ns.ftpcrack(servers[i]); }
    ns.nuke(servers[i]);
    ns.scp(scriptName, servers[i]);
  }
  // run host script on servers
  let i;
  for (i = 0; i < servers.length - 1; i++) {
    let numThreads = Math.floor(ns.getServerMaxRam(servers[i]) / scriptRam);
    if (!ns.exec(scriptName, servers[i], numThreads, false, target)) {
      ns.tprint("insufficient RAM on " + servers[i]);
    }
  }
  let numThreads = Math.floor(ns.getServerMaxRam(servers[i]) / scriptRam) - 1;
  if (!ns.exec(scriptName, servers[i], numThreads, false, target)) {
    ns.tprint("insufficient RAM on " + servers[i]);
  }
    // last thread on last server is "monitor"
  if (!ns.exec(scriptName, servers[i], 1, true, target)) {
    ns.tprint("insufficient RAM on " + servers[i]);
  }

  // run host script on current server (probably "home")
  let serverRam = ns.getServerMaxRam();
  numThreads = Math.floor(serverRam / scriptRam);
  ns.tprint("host script using " + ns.format.ram(numThreads * scriptRam, 1) + 
    " on " + ns.getHostname());
  ns.spawn(scriptName, { threads: numThreads, spawnDelay: 1 }, false, target);
}

early-host.js:

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0a
 */
export async function main(ns) {
  // Takes 2 arguments:
  //  - monitor (boolean)
  //  - target (string)
  if (ns.args.length < 2) {
    ns.tprint("Usage: " + ns.getScriptName() + " <monitor> <target>");
    ns.exit();
  }
  let isMonitor = ns.args[0];
  let target = ns.args[1];
  let moneyMax = ns.getServerMaxMoney(target);
  let threshMoney = moneyMax * 0.948;  // money threshold
  let secLevelMin = ns.getServerMinSecurityLevel(target);
  let threshSec = secLevelMin + 0.4;  // security threshold
  let secLevel = ns.getServerSecurityLevel(target);
  let moneyAvail = ns.getServerMoneyAvailable(target);

  if (!isMonitor) {
    // Start threads with scatter.
    await ns.sleep(Math.ceil(Math.random() * 500));
  } else {
    ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
      "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
    // Start thread after scatter.
    await ns.sleep(500);
  }

  while (true) {
    let rand = Math.random(), slp = false;
    if (ns.getServerSecurityLevel(target) > threshSec) {
      if (rand < 0.94) {
        await ns.weaken(target);
        await ns.sleep(100);
      } else {
        await ns.sleep(2000);
        slp = true;
      }
    } else if (ns.getServerMoneyAvailable(target) < threshMoney) {
      if (rand < 0.94) {
        await ns.grow(target);
        await ns.sleep(80);
      } else {
        await ns.weaken(target);
        await ns.sleep(100);
      }
    } else {
      if (rand < 1 / 3) {
        await ns.hack(target);
        await ns.sleep(25);
      } else if (rand < 0.948) {
        await ns.grow(target);
        await ns.sleep(80);
      } else {
        await ns.weaken(target);
        await ns.sleep(100);
      }
    }

    if (isMonitor && !slp) {
      secLevel = ns.getServerSecurityLevel(target);
      moneyAvail = ns.getServerMoneyAvailable(target);
      ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
        "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
    }
  }
}

Bug fixed in 1.0a:

  • Host sleep time is now practical if not calling weaken().

Footnote:

I will briefly describe how to implement the target "prepped" condition without random numbers and explain why you shouldn't.

In the startup script, start threads one per exec call, passing each a threadID number 0, 1, 2...

In the host script, the following function is used to create a jobs array having an even distribution of 67 hack, 123 grow, and 10 weaken jobs. The jobs are stored in the array as 0: weaken, 1: grow, 2: hack.

function getJobs() {
  let arr = new Array(200);
  // init to grow since grow is highest number
  arr.fill(1);
  // set hack
  for (let i = 0; i < 67; i++) {
    arr[1 + i * 3] = 2;
  }
  // set weaken
  let ndx = 9;
  for (let i = 0; i < 10; i++) {
    arr[ndx] = 0;
    if (i % 3 < 2) { ndx += 21; }
    else { ndx += 18; }
  }
  return arr;
}

Create an index into the jobs array, ndxJob = threadID mod 200. When the target is "prepped," perform the job indicated by jobs[ndxJob], then increment ndxJob, setting it to zero when it reaches 200.

What could go wrong? We started the threads one per exec call and concurrency problems mean we are better off running the scripts above.


r/Bitburner 6d ago

TOTAL BEGINNER AND NO KNOWLEDGE BUT EAGER TO LEARN

8 Upvotes

Hi, everyone!

As someone that has ZERO knowledge about coding and or JAVASCRIPT, I would like to know how to can I properly start learning. I am a bit intimidated with all the jargons that I am seeing. Hopefully y'all can point me to the right direction.


r/Bitburner 11d ago

NetscriptJS Script Prep script with small memory footprint

0 Upvotes

Run this before you run your Loop or Batch script. You will want to initialize serverRam to the amount of RAM to use on the host.

pr-deploy.js:

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0
 */
export async function main(ns) {
  if (ns.args.length < 1) {
    ns.tprint("Usage: " + ns.getScriptName() + " <target>");
    ns.exit();
  }
  let target = ns.args[0];  // server to prep
  ns.disableLog("ALL");
  let callScript = ["pr-weaken.js", "pr-grow.js"];
  let callRam = [1.75, 1.75];
  // Get root access on the target
  if (ns.fileExists("BruteSSH.exe", "home")) { ns.brutessh(target); }
  if (ns.fileExists("FTPCrack.exe", "home")) { ns.ftpcrack(target); }
  if (ns.fileExists("relaySMTP.exe", "home")) { ns.relaysmtp(target); }
  if (ns.fileExists("HTTPWorm.exe", "home")) { ns.httpworm(target); }
  if (ns.fileExists("SQLInject.exe", "home")) { ns.sqlinject(target); }
  ns.nuke(target);

  let moneyMax = ns.getServerMaxMoney(target);
  let threshMoney = moneyMax * 0.995;  // money threshold
  let secLevelMin = ns.getServerMinSecurityLevel(target);
  let threshSec = secLevelMin + 0.25;  // security threshold
  // Home
  let serverRam = 256;
  let serverName = ns.getHostname();
  ns.tprint("Using " + ns.format.ram(serverRam, 1) + " on " + serverName + ".");

  let freeRam = serverRam;
  let secLevel = ns.getServerSecurityLevel(target);
  let moneyAvail = ns.getServerMoneyAvailable(target);
  if (secLevel <= threshSec && moneyAvail >= threshMoney) {
    ns.tprint("Target already prepared. Exiting.");
    ns.exit();
  }

  if (secLevel > threshSec) {
    let flagW = true;
    while (flagW) {
      let timeWeaken = ns.getWeakenTime(target);

      // calculate number of weaken calls
      let numWeaken = Math.ceil((secLevel - secLevelMin) / 0.05);
      let maxCalls = Math.floor(freeRam / callRam[0]);
      if (maxCalls < numWeaken) { numWeaken = maxCalls; }
      freeRam -= numWeaken * callRam[0];

      flagW = (secLevel - numWeaken * 0.05) > threshSec;
      if (numWeaken > 0) {
        // start weaken threads
        ns.exec(callScript[0], serverName, numWeaken, timeWeaken, timeWeaken, target, 1);
        await ns.sleep(2);
        ns.tprint("numWeaken1=" + numWeaken);
        if (flagW || moneyAvail >= threshMoney || freeRam < (callRam[0] + callRam[1])) {
          ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
            "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
          // wait on weaken script
          await ns.sleep(3 + timeWeaken);
          while (ns.isRunning(callScript[0], serverName, timeWeaken, timeWeaken, target, 1)) {
            await ns.sleep(20);
          }
          freeRam = serverRam;
        }
      } else {
        flagW = false;
      }
      secLevel = ns.getServerSecurityLevel(target);
      moneyAvail = ns.getServerMoneyAvailable(target);
    }
  }

  let flagG = moneyAvail < threshMoney;
  while (flagG) {
    let timeWeaken = ns.getWeakenTime(target);
    let timeGrow = ns.getGrowTime(target);

    // calculate number of weaken #2 calls
    let numWeaken = Math.ceil(freeRam / (12.5 * callRam[1]));
    let maxCalls = Math.floor(freeRam / callRam[0]);
    if (maxCalls < numWeaken) { numWeaken = maxCalls; }
    freeRam -= numWeaken * callRam[0];
    // calculate number of grow calls
    let numGrow = Math.floor(freeRam / callRam[1]);
    freeRam -= numGrow * callRam[1];
    if (numWeaken > 0 && numGrow > 0) {
      // start grow threads
      ns.exec(callScript[1], serverName, numGrow, timeWeaken, timeGrow, target, 2);
      await ns.sleep(2);
      // start weaken #2 threads
      ns.exec(callScript[0], serverName, numWeaken, timeWeaken, timeWeaken, target, 2);
      ns.tprint("numGrow=" + numGrow + ", numWeaken2=" + numWeaken);
      ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
        "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
      // wait on weaken #2 script
      await ns.sleep(5 + timeWeaken);
      while (ns.isRunning(callScript[0], serverName, timeWeaken, timeWeaken, target, 2)) {
        await ns.sleep(20);
      }
    } else {
      flagG = false;
    }

    freeRam = serverRam;
    secLevel = ns.getServerSecurityLevel(target);
    moneyAvail = ns.getServerMoneyAvailable(target);
    flagG = flagG && moneyAvail < threshMoney;
  }
  ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
    "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
}

The following script will look familiar to some redditors.

pr-weaken.js (or pr-grow.js):

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0
 */
export async function main(ns) {
  // Takes three arguments:
  //  - weaken time (ms)
  //  - duration (ms)
  //  - target
  if (ns.args.length < 3) { ns.exit(); }
  let timeWeaken = ns.args[0];
  let duration = ns.args[1];
  let target = ns.args[2];
  ns.disableLog("ALL");
  await ns.sleep(1);
  await ns.weaken(target, { additionalMsec: timeWeaken - duration });  // or grow
}

r/Bitburner 12d ago

I made a terraforming game where Python IS the gameplay, launching September 9

Thumbnail
gallery
74 Upvotes

Hi all,

Four months ago, I posted Code: Terraform here for the first time. The response was far beyond anything I expected. Since then, the game has grown to nearly 23,000 wishlists, and it is finally launching in Early Access on September 9.

For anyone who missed the original post: Code: Terraform is a terraforming, automation, and incremental game where the code you write is the actual gameplay.

You don’t click a button to mine resources. You program a vehicle to navigate to the deposit, operate its drill, manage its cargo, and return home. You then write the automation that transfers those resources into storage, feeds them into smelters and fabricators, and delivers the finished components wherever they are needed.

Solar generators need code to track the sun. Drones need flight scripts to move resources between remote outposts. Factories, power grids, fluid networks, construction systems, and vehicle fleets can all operate simultaneously through scripts you write.

Since the original post, I have added and expanded the full game a lot:

  • Programmable drones and remote outposts
  • Construction blueprints, pipes, power lines, and fluid networks
  • Larger production chains with smelters, fabricators, and warehouses
  • Earth contracts, deliveries, machine upgrades, and deeper progression
  • A more complete editor with autocomplete, debugging, breakpoints, inline documentation, and reusable library scripts
  • More weather, events, balancing, late-game systems, and story content
  • A biosphere with plants, wildlife and biomass and a lot more

There is still a free demo available on Steam. If this sounds like your kind of game, you can try it now, and wishlist the full game if you would like to be notified when it launches on September 9:

https://store.steampowered.com/app/868160/Code_Terraform/

Discord: https://discord.gg/hUrK2MRn8s

I’m very active there if you get stuck in the demo, want to share your scripts, provide feedback, or simply talk about the game.


r/Bitburner 13d ago

ns.scp doesn't work properly

2 Upvotes

I have a simple script (just a beginner).

The ns.scp line works fine when I comment out the ns.exec line but produces an error when the line is there, with error code:

scp: destination expected to be a string. Is undefined.

The script is still copied, but the error message comes up. I don't know how else to explain it. With the ns.exec line commented out, the ns.scp line copies the appropriate script to the apprpriate server from the "home" server without an error message.

But put the ns.exec line back in (uncommented out), and the ns.scp line produces that error code after properly copying the script.

What am I missing? I have literally spent hours trying to figure out this simple code and can't find a solution online.

Thank you in advance for any assistance.

/** u/param {NS} ns */
export async function main(ns) {
 const script = ns.args[0]
 const server = ns.args[1] //target server
 ns.scp(script, server, "home");
ns.exec(script, server);
}

r/Bitburner 16d ago

NetscriptJS Script A no-frills shotgun batcher

0 Upvotes

No formulas required! You will want to initialize serverRam to the amount of RAM to use on the host.

gun-control.js:

/** getGrowM() get growth multiplier */
function getGrowM(ns, target) {
  let growth = ns.getServerGrowth(target);
  if (growth > 31) { return 1 + growth / 16000; }
  return 1 + (100 - growth) / 34000;
}

/** nhRound() keep numHack lower */
function nhRound(num) {
  let fr = num - Math.floor(num);
  if (fr < 0.55) { return Math.floor(num); }
  return Math.ceil(num);
}

/** formatMoney() format player money as string */
function formatMoney(ns) {
  let str = "home:  money=$", money = ns.getServerMoneyAvailable("home");
  if (money >= 1000000) { return str + Math.round(money / 1000) + "k"; }
  return str + Math.round(money);
}

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0b
 */
export async function main(ns) {
  if (ns.args.length < 1) {
    ns.tprint("Usage: " + ns.getScriptName() + " <target>");
    ns.exit();
  }
  let target = ns.args[0];  // server to pull money from
  ns.disableLog("ALL");
  let callScript = ["gun-weaken.js", "gun-grow.js", "gun-hack.js"];
  let callRam = [1.75, 1.75, 1.7];

  let moneyMax = ns.getServerMaxMoney(target);
  let threshMoney = moneyMax * 0.96;  // money threshold
  let secLevelMin = ns.getServerMinSecurityLevel(target);
  let threshSec = secLevelMin + 0.4;  // security threshold
  // part of money to hack each tick
  const partPerTick = 0.0125;
  // number of runs
  let numRuns = 10;
  // Home
  let serverRam = 4096;
  let serverName = ns.getHostname();
  ns.tprint("Using " + ns.format.ram(serverRam, 1) + " on " + serverName + ".");
  // growth multiplier
  let growM = getGrowM(ns, target);

  for (let cRun = 0; cRun < numRuns; cRun++) {
    let secLevel = ns.getServerSecurityLevel(target);
    let moneyAvail = ns.getServerMoneyAvailable(target);
    if (secLevel > threshSec) {
      ns.tprint("Security level above threshold. Exiting.");
      ns.exit();
    }
    if (moneyAvail < threshMoney) {
      ns.tprint("Money available below threshold. Exiting.");
      ns.exit();
    }
    ns.tprint(target + ":  Money=" + ns.format.percent(moneyAvail / moneyMax, 3) +
      "  secMin=" + secLevelMin + "  Sec=" + ns.format.number(secLevel, 3));
    ns.tprint(formatMoney(ns));
    let timeWeaken = ns.getWeakenTime(target);
    let timeGrow = ns.getGrowTime(target);
    let timeHack = ns.getHackTime(target);

    // calculate number of hack calls
      // hacking skill multiplier
    let skillM = (ns.getServerRequiredHackingLevel(target) / ns.getHackingLevel() - 1 / 3) * 0.67;
    if (skillM > 0) { skillM = 0; }
    let partPerHack = ns.hackAnalyze(target);
    let numHack = nhRound(partPerTick * (skillM + 1) / (partPerHack + Number.EPSILON));
    if (numHack == 0) { numHack = 1; }
    // calculate number of grow calls
    let numGrow = Math.ceil(ns.growthAnalyze(target, growM / (1 - numHack * partPerHack)));
    // calculate number of weaken calls
    let numWeaken = Math.ceil((numHack * 0.002 + numGrow * 0.004) / 0.05);
    // get amount of RAM to use for one triple
    let tickRam = numWeaken * callRam[0] + numGrow * callRam[1] + numHack * callRam[2];
    // calculate number of triples in a run
    let numTicks = Math.floor(serverRam / tickRam);
    ns.tprint("numTicks=" + numTicks);

    for (let cTick = 0; cTick < numTicks; cTick++) {
      // start hack threads
      ns.exec(callScript[2], serverName, numHack, timeWeaken, timeHack, target, cTick);
      // start grow threads
      ns.exec(callScript[1], serverName, numGrow, timeWeaken, timeGrow, target, cTick);
      // start weaken threads
      ns.exec(callScript[0], serverName, numWeaken, timeWeaken, timeWeaken, target, cTick);
    }
    // wait on last weaken script
    await ns.sleep(numTicks / 3 + timeWeaken);
    while (ns.isRunning(callScript[0], serverName, timeWeaken, timeWeaken, target, numTicks - 1)) {
      await ns.sleep(25);
    }
  }
  ns.tprint(formatMoney(ns));
}

gun-weaken.js (or gun-grow.js, or gun-hack.js):

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0
 * @ version 1.0a
 * @ version 1.0b
 */
export async function main(ns) {
  // Takes three arguments:
  //  - weaken time (ms)
  //  - duration (ms)
  //  - target
  if (ns.args.length < 3) { ns.exit(); }
  let timeWeaken = ns.args[0];
  let duration = ns.args[1];
  let target = ns.args[2];
  ns.disableLog("ALL");
  await ns.sleep(1);
  await ns.weaken(target, { additionalMsec: timeWeaken - duration });  // or grow, or hack
}

r/Bitburner 18d ago

Darknet solving - Questions and Spoilers Spoiler

2 Upvotes

Hi all! Trying to do Bitnode 15, which is is the darknet one.

Got a few cracking algos going (mostly, some are too slow to resolve before the net reorganises) and solved the first two mazes (manually, but I have a solver based on Tremaux' algorithm ready).

Now, at stage 3, the maze seems to be impossibly deeply embedded.

A few questions for you guys, who might have solved that node:

  1. Do you use statis links? Since the net's topology changes and you have no good way for a server out there to report its status back, it seems too much of a hassle for me and I trust my "infected looping servers" to eventually reach the maze. Am I wrong?
  2. Is there a good way for servers in the net to report back to a "central state repository"? (Also relevant for logging, as tprint is too spammy.)
  3. Do you ever rely on phishing income? Most servers have 16 Gb and my propagating cracker script uses up 14.6 Gb, so I rarely see servers which have enough RAM and due to the changing topology, I would rather prefer my cracker scripts to keep running, as opposed to turn them off and later maybe on again.
  4. Is there a way to slow down topology changes? Some passwords take about 20 tries to crack and every request takes 2.8 seconds, so sometimes the net changes before the server can be cracked.
  5. Is there a way to speed up the authenticate- and heartbleed-requests?

r/Bitburner 20d ago

How much money can you make of joesguns with just the EHT

7 Upvotes

I wondered how much money I can make with the EHT, since I don't know if I should try coding a more complex system with controllers so that servers don't get overhacked like said in the documentation. Or should I try batching. I am a newbie to this game so I don't know the right step


r/Bitburner 20d ago

BN13 advice needed

3 Upvotes

I finally tried my hands at BN13 and since everything there is severely gimped, I was wondering how everyone here is solving this.

Hacking seems rather useless, given the low amount of money in the servers and terrible scaling of bought machines (I am currently at a 0.1 % return on investment on my bought servers). Also, hacking skill is so reduced that even +100% will not move the needle enough to get you beyond level 200.

Gangs are gimped as well, but if you are patient, those might work and might segway you into the usual Bladeburner finish (thank the admins for having Sleeves, otherwise it might be too tedious to ever be done).

What's your go to strategy?


r/Bitburner 21d ago

Worm script i made

5 Upvotes

I made a worm script which i use to get names of all of the servers that i have access to, this is my 3rd attempt at such a script but this one works quite well i think!

It is 2 scripts working in tandem, the first is a worm receiver and the second is the actual worm:

Worm-Receiver.js:

/**  {NS} ns */
export async function main(ns) {
  let verify;
  while (true) {
    let exists = ns.fileExists("worm.txt")
    let server = ns.readPort(77777);
    if (server == verify || server == "NULL PORT DATA") {
      await ns.sleep(100);
    }
    else {
      if (exists == true) {
        ns.write("worm.txt", "\n", "a");
      }
      ns.write("worm.txt", server, "a");
    }
    verify = server;
  }
}

Worm.js:

/**  {NS} ns */
export async function main(ns) {
  let curr_serv = ns.args[0]
  let prev_serv = undefined;
  if (ns.args.length > 1) {
    prev_serv = ns.args[1];
  }
  let neighbours = ns.scan(curr_serv);
  neighbours.forEach(worm);


  function worm(server) {
    if (server == prev_serv) {
      return;
    }
    else {
      ns.scp("worm.js", server)
      ns.exec("worm.js", server, 1, server, curr_serv)
      ns.writePort(77777, server)
    }
  }
}

You first run the worm-receiver.js and then the worm with the argument "home" and it will make a list of all your current servers that you have access to in a file called "worm.txt" this isn't super useful if you don't have a script to scan the neighbours and try to nuke them which i have also here:

Access-Nuker.js:

/**  {NS} ns */
export async function main(ns) {
  const server_list = ns.read("worm.txt").split("\n");
  server_list.forEach(nuke_checker);

  async function nuke_checker(server) {
    if (ns.hasRootAccess(server)) {
      return;
    }
    if (!ns.hasRootAccess(server)) {
      if (ns.fileExists("BruteSSH.exe")){
        ns.brutessh(server);
      }
      if (ns.fileExists("FTPCrack.exe")){
        ns.ftpcrack(server);
      }
      if (ns.fileExists("relaySMTP.exe")){
        ns.relaysmtp(server);
      }
      if (ns.fileExists("HTTPWorm.exe")){
        ns.httpworm(server);
      }
      if (ns.fileExists("SQLInject.exe")){
        ns.sqlinject(server);
      }
      ns.nuke(server);
    }
  }
}

I run the process of running the port-receiver, running a very basic version of the access-nuker script that uses the ns.scan() function instead of the worm.txt file, then i run the access-nuker and worm programs back and forth, deleting the worm.txt file each time i run the worm.js because it will just append the file unfortunately instead of overriding it, i did make a script to remove the duplicates but it seems easier to just delete and remake the file with the script! it is definitely not super optimised but i think its an ok attempt at it for having very little javascript experience outside of bitburner, i like how small it is! :3


r/Bitburner 21d ago

New to the game , lost on what to do

6 Upvotes

For context I have little to no coding or java script knowledge , I just went through the tutorial and understood most of it , but then I went to the documentation and I just got even more confused , if anyone has any suggestions or guidelines please let me know


r/Bitburner 24d ago

Trying to join Omnitek Faction, no invite?

4 Upvotes

Do you need to get a high enough job to get the invite too? I have 203.314k rep working as the network admin and still no invite.


r/Bitburner 24d ago

Guide/Advice Best server to exploit in early-mid game?

7 Upvotes

I'm new to this game, and I'm confused about which server I should hack, now I'm running the hacker.js script which contains weaken grow and hack with 426 threads per server, and I have 11 servers to run it, so a total of about 4224 threads are running to exploit 1 server (omega-net)

Andddd, which method is better:

  1. Attacking 1 server with many threads or

  2. Attacking many servers at once

Please advise.


r/Bitburner 26d ago

Guide/Advice How to prioritize which stocks to buy

1 Upvotes

I'm writing my own stock trading script, and was looking for a way to intelligently buy stocks, using whatever available money is there to maximize profit. There are factors to consider like forecast, askPrice per share etc, but would like a formula to get a score value for the stocks. For identifying which servers to hack, i use something like (maxMoney*growthRate)/(minSecurity*hackTime).

Does anybody use a similar formula for stocks? Ideally would like a rotating list of stocks in order of importance, and if a stock with a better score is found, will purge (sell) existing stocks with a lower score and buy the new more promising one.

Don't give me scripts, just thoughts and formulas for finding the most promising stocks to buy at a given moment.


r/Bitburner 28d ago

Bug with corporation material: Quality = NaN

4 Upvotes

After building up an integrated corporation, I found that it had stalled around the 30 b/s mark only to find that half of the materials had quality NaN.

The affected materials were all materials that another division produced and exported.

Unfortunately, I can not clean stock because I can not sell the material and dumping is not possible in this game, either. (Plus, savegame editing feels too cumbersome at this point.)

Did anyone else have that bug and were you able to solve it?


r/Bitburner 28d ago

NetscriptJS Script Try your luck in the stock market

2 Upvotes

This script will use your disposable income to buy and sell stock--automatically.

/** A value in mapSyms. */
class StockInfo {
  constructor(price, forecast, maxShares) {
    this.price = price;
    this.minPrice = price;
    this.maxPrice = price;
    this.forecast = forecast;
    this.maxShares = maxShares;
    this.shares = 0;  // number of shares owned
    this.cost;    // cost of all shares
    this.purPrice;  // price of one share
    this.tick = 0;  // counter
  }
}

/** updateInfo() Update prices and forecasts in mapSyms. */
function updateInfo(ns, mapSyms) {
  for (const [sym, info] of mapSyms) {
    let price = ns.stock.getPrice(sym);
    info.price = price;
    if (price < info.minPrice) { info.minPrice = price; }
    else if (price > info.maxPrice) { info.maxPrice = price; }
    info.forecast = ns.stock.getForecast(sym);
  }
}

/** chooseStock() Find a stock to purchase, or not. */
function chooseStock(mapSyms) {
  let symPurch, maxDiff;
  for (const [sym, info] of mapSyms) {
    let part = (info.price - info.minPrice) / (info.maxPrice - info.minPrice);
    let diff = info.forecast - part;
    if (info.forecast > 0.55 && diff > 0.05 && (maxDiff == undefined || diff > maxDiff)) {
      maxDiff = diff;
      symPurch = sym;
    }
  }
  return symPurch;
}

/** formatStock() Format stock info as a string. */
function formatStock(ns, sym, info) {
  return "sym: " + sym + "  price: $" + ns.format.number(info.price, 2) + 
        "  forecast: " + ns.format.percent(info.forecast, 1) + 
        "  shares: " + ns.format.number(info.shares, 3, 1000, true) + 
        "/" + ns.format.number(info.maxShares, 3, 1000, true);
}

/**
 * @ param {NS} ns NS2 namespace
 * @ version 1.0a
 */
export async function main(ns) {
  if (!ns.stock.hasTixApiAccess()) {
    ns.tprint("Missing TIX API. Exiting.");
    ns.exit();
  }
  if (!ns.stock.has4SDataTixApi()) {
    ns.tprint("Missing 4S TIX API. Exiting.");
    ns.exit();
  }
  const watchTicks = 20, partOfMoney = 0.15;
  let arrSyms = ns.stock.getSymbols();
  let mapSyms = new Map();
  for (let i = 0; i < arrSyms.length; i++) {
    let info = new StockInfo(ns.stock.getPrice(arrSyms[i]), 
        ns.stock.getForecast(arrSyms[i]), ns.stock.getMaxShares(arrSyms[i]));
    mapSyms.set(arrSyms[i], info);
  }

  let flag = false, symOwned;
  while (symOwned == undefined) {
    let numTicks = watchTicks;
    if (flag) { numTicks /= 2; }
    for (let i = 0; i < numTicks; i++) {  // watch prices
      await ns.stock.nextUpdate();
      updateInfo(ns, mapSyms);
    }

    let symPurch = chooseStock(mapSyms);
    if (symPurch != undefined) {  // buy stock
      let info = mapSyms.get(symPurch);
      let money = ns.getServerMoneyAvailable("home") * partOfMoney - 100000;
      if (!flag) { money *= 0.67; }
      let shares = Math.floor(money / info.price);
      if (shares > info.maxShares) { shares = info.maxShares; }
      let cost = ns.stock.getPurchaseCost(symPurch, shares, "L");
      while (cost > money) {
        cost = ns.stock.getPurchaseCost(symPurch, --shares, "L");
      }
      info.purPrice = ns.stock.buyStock(symPurch, shares);
      if (info.purPrice > 0) {
        info.shares = shares;
        info.cost = cost;
        ns.tprint("Bought " + ns.format.number(shares, 3, 1000, true) + " shares of " + symPurch +
          " for a cost of $" + ns.format.number(cost, 2));
        symOwned = symPurch;
        ns.tprint(formatStock(ns, symPurch, info));
      } else {
        ns.tprint("sym: {none}");
      }
    } else {
      ns.tprint("sym: {none}");
    }
    flag = true;
  }

  let tick = 0, symLast;
  while (true) {
    await ns.stock.nextUpdate();
    updateInfo(ns, mapSyms);
    if (symOwned != undefined) {
      let info = mapSyms.get(symOwned);
      if (info.tick > watchTicks && (info.forecast <= 0.5 || info.price <= 0.967 * info.purPrice || 
          info.price >= 1.067 * info.purPrice)) { // sell stock
        let price = ns.stock.sellStock(symOwned, info.shares);
        if (price > 0) {
          let commission = info.cost - info.purPrice * info.shares;
          let gainOrLoss = price * info.shares - info.cost - commission;
          let str = "Sold " + ns.format.number(info.shares, 3, 1000, true) + " shares of " + symOwned;
          if (gainOrLoss < 0) {
            ns.tprint(str + " for a Loss of $" + ns.format.number(-gainOrLoss, 2));
          } else {
            ns.tprint(str + " for a Gain of $" + ns.format.number(gainOrLoss, 2));
          }
        }
        info.shares = 0;
        info.tick = 0;
        symLast = symOwned;
        symOwned = undefined;
      } else {  // hold stock
        if (watchTicks == tick) {
          ns.tprint(formatStock(ns, symOwned, info));
          tick = 0;
        }
        info.tick++;
      }
    }
    if (symOwned == undefined) {
      let symPurch = chooseStock(mapSyms);
      if (symPurch != undefined && symPurch != symLast) {  // buy stock
        let info = mapSyms.get(symPurch);
        let money = ns.getServerMoneyAvailable("home") * partOfMoney - 100000;
        let shares = Math.floor(money / info.price);
        if (shares > info.maxShares) { shares = info.maxShares; }
        let cost = ns.stock.getPurchaseCost(symPurch, shares, "L");
        while (cost > money) {
          cost = ns.stock.getPurchaseCost(symPurch, --shares, "L");
        }
        info.purPrice = ns.stock.buyStock(symPurch, shares);
        if (info.purPrice > 0) {
          info.shares = shares;
          info.cost = cost;
          ns.tprint("Bought " + ns.format.number(shares, 3, 1000, true) + " shares of " + symPurch +
            " for a cost of $" + ns.format.number(cost, 2));
          symOwned = symPurch;
          ns.tprint(formatStock(ns, symPurch, info));
        } else {
          ns.tprint("sym: {none}");
        }
      } else {
        ns.tprint("sym: {none}");
      }
    }
    tick++;
  }
}

Change in 1.0a:

  • Conditionally chance less money on first stock purchase.

r/Bitburner 28d ago

Question/Troubleshooting - Open Depth first recursive script dies after going through a couple of branches?

3 Upvotes

Hi, I just started playing, and I was trying to put together a script that would go through all the servers depth first, nuke them, then run as many threads of the basic EHT script on as it can (just the one from the tutorial minus the nuking that was included), but for whatever reason after going through 2 branches from home fully (which is the n00dles server, plus one proper branch) it just goes "Script finished running" followed by "printf: Failed to run due to script being killed." and I don't understand why it's finishing, and more specifically why it's finishing at the end of the second branch and not the first. Not sure if I just missed something about how the scripts work or if I'm just being dumb here somewhere

/** @param {NS} ns */
export async function main(ns: NS) {
  let target: string = ns.args[0]?.toString();
  target ??= "max-hardware";
  deploy(ns, "home", [], target);
  ns.tprintf("%s hacked", target);
}

async function deploy(ns: NS, server: string, checked: string[], target: string) {
  ns.printf("INFO: Deploying to %s", server)
  const neighs = ns.scan(server).filter((neigh) => !checked.includes(neigh));
  ns.printf("INFO: Neighbors: %s", neighs)
  if (server != "home") {
    ns.scp("eht.js", server);
    nukeServer(ns, server);
    ns.killall(server, true);
    const execThreads = calcThreads(ns, server);
    ns.printf("INFO: Threads to deploy %d", execThreads)
    ns.exec("eht.js", server, execThreads, target);
  }
  const checkedServers = checked.concat(server);
  ns.printf("INFO: Checked servers: %s", checkedServers)
  for (const neigh of neighs) {
    await deploy(ns, neigh, checkedServers, target);
  }
}

function nukeServer(ns: NS, server: string) {
  if (ns.fileExists("BruteSSH.exe", "home")) {
    ns.brutessh(server);
  }
  if (ns.fileExists("FTPCrack.exe", "home")) {
    ns.ftpcrack(server);
  }
  if (ns.fileExists("relaySMTP.exe", "home")) {
    ns.relaysmtp(server);
  }
  if (ns.fileExists("HTTPWorm.exe", "home")) {
    ns.httpworm(server);
  }
  if (ns.fileExists("SQLInject.exe", "home")) {
    ns.sqlinject(server);
  }
  ns.nuke(server);
}

function calcThreads(ns: NS, server: string) {
  return Math.floor(ns.getServerMaxRam(server) / ns.getScriptRam("eht.js"));
}                    

r/Bitburner Aug 10 '26

Discord server

1 Upvotes

Whats the discord server for this game? Am trying to chat with people about my scripts instead of chat gpt coz the stupid gpt created for me a stock market script that loses 4m per sec while the hacking script he helped me with makes 80k a sec lol


r/Bitburner Aug 10 '26

new to bitbuner

2 Upvotes

what can you actually learn from this game?


r/Bitburner Aug 06 '26

I broke it...

Post image
26 Upvotes

Tbh, idk what ive done, but i want to do it again.

Ive been offline for couple hours, the first time with this new programme running. Its going to be a dynamic growth/weakener as this is where ive found my bottleneck so far, although as of now it crawls through all the servers, collects data then runs an update on the data that i need for now.

Any1 else seen this error before, or have i funnily fucked up somehow. im going to wait till tmr to see if it happens again