bitburner-official / bitburner-src Goto Github PK
View Code? Open in Web Editor NEWBitburner source code.
License: Other
Bitburner source code.
License: Other
[Jakob002]
Bitburner v2.1.0 (8f4636c)
Browser
OS and browser set to German (locale de_DE)
Hi devs,
I noticed an inconsistency in the use of the thousands separator (and possibly the decimal separator).
Most of the game uses the notation used in English speaking countries (dot for decimal separator, comma for thousands separator, i.e. 1M=1,000,000 and pi=3.14159). However on the stats page the skill levels seem to use my local notation (dot for thousands separator, i.e. 1M=1.000.000, and possibly comma for decimal separator, i.e. pi=3,14159).
Here is a screenshot. On the left hand my Hacking level shows as "1.000". In the overview on the right my Hacking level shows as "1,000".
I'll also attach a savegame. If both levels show up as "1,000" on an English system, then it looks like the left number is locale dependent.
[vladtepesch]
According to documentation the run
command arguments -t
and --tail
have to be following directly to the script name. ( --> https://bitburner.readthedocs.io/en/latest/basicgameplay/terminal.html#run - at least -t
is mentioned there)
But the parser also interprets them as special arguments if they are later in the arg list. this prevents them to be passed to the executed script.
for example starting a runon
script (that is supposed to start a script on a remote server)
run runon.js pserv-5 somescript.js -t 500 --tail omnitek
where the script itself is supposed to process the -t
and --tail
parameter did not see them and itself gets executed with 500 threads
Comments From Original Issue
[mbrannen]
I believe this might be a misunderstanding of the command and intended usage.
From the docs
run [file name] [-t] [num threads] [args…]
Translating that to the command you wrote looks like this
run [file name = runon.js ] [-t] [num threads = 500] [args… = {'pserv-5', 'somescript.js', '--tail','omnitek'}]
I would suggest somescript.js having arguments that you can then pass when
exec()
is run from runon.js
Try taking out the-t 500
and using just500
instead.So in runon.js you might find something like this:
//exec(script, hostname[, numThreads=1[, args...]]) exec(scriptToRun, serverToRunOn, threads, serverToHack)
[vladtepesch]
I believe this might be a misunderstanding of the command and intended usage.
From the docs
run [file name] [-t] [num threads] [args…]
Translating that to the command you wrote looks like this
run [file name = runon.js ] [-t] [num threads = 500] [args… = {'pserv-5', 'somescript.js', '--tail','omnitek'}]
I would suggest somescript.js having arguments that you can then pass when
exec()
is run from runon.js Try taking out the-t 500
and using just500
instead.So in runon.js you might find something like this:
//exec(script, hostname[, numThreads=1[, args...]]) exec(scriptToRun, serverToRunOn, threads, serverToHack)
according to the docs the
-t
argument has to be passed right after the script name to be processed by the command line interpreter (I would expect the same for--tail
). This implies that if I pass-t
not as the second argument it should be visible within thens.args
array but that is not the case.I wanted my
runon.js
to parse for the optional-t number
parameter and pass its number to thens.exec
call.so at the end according to the docs the following should happen:
(this obviously works)> run script.js -t 1000 123 foo bar
should run the script
script.js
with 1000 threads and the arg array[123, 'foo', 'bar']
but this does not work as described:
> run script.js 123 foo bar -t 1000
should (according to the docs) run the script
script.js
with 1 threads and the arg array[123, 'foo', 'bar', '-t', 1000]
.
But instead it has the same result as the first command.
[tmajibon]
In part request, in part ask for guidance so I can possibly do it myself.
In the markdown can we put the endgame functions under a spoiler warning or such?
I went to edit it myself but a comment in the markdown says it's auto-generated, and I don't know the tool and how it's set up to run/correct it?
At the very least, we could put "Spoiler for Endgame" into the descriptions of the relevant parts?
Comments From Original Issue
[zeddrak]
I don't know the exact process (so not sure how/if spoiler is handled), but here's the documentation on contributing as a documentor. (I have used this information to make several successful documentation submissions myself, but none exactly like you are asking to do.)
contributing to documentation
[hydroflame]
null
Comments From Original Issue
[phyzical]
this one im not sure about.
is it just a matter of making this exportable https://github.com/danielyxie/bitburner/blob/dev/src/Electron.tsx#L35 exportableand calling it here? https://github.com/danielyxie/bitburner/blob/dev/src/db.tsx#L44
[HandyGold75]
share() function report to use 2.40 GiB but only uses 0.10 GiB when not running on home.
To reproduce:
while (true) { share() }
free
(This should be 1.70 GiB, where I suspect 1.60 GiB is of the base cost)Version: Bitburner v1.4.0 (49de4a28)
Comments From Original Issue
[HandyGold75]
The above also seems to be the case with this script (This script is run on bought servers).
while (true) { cacheFiles = ls("home", "/Automation/Cache/Hosts/"); for (i = cacheFiles.length - 1; i > 0; i--) { j = Math.floor(Math.random() * i); k = cacheFiles[i]; cacheFiles[i] = cacheFiles[j]; cacheFiles[j] = k } arrayRootedHosts = []; for (i = 0; i < cacheFiles.length; i++) { currentCacheFile = read(cacheFiles[i]).split(","); if (currentCacheFile[5] == "true") { arrayRootedHosts.push(currentCacheFile[1], currentCacheFile[13], currentCacheFile[15]) } } for (i = 0; i < arrayRootedHosts.length; i += 3) { hack(arrayRootedHosts[i]) } }
While this script is a bit more complicated than before it only uses the ls and hack functions that have a ram requirement, with the base cost it should only add up to 1.90 GiB per tread, but when run it requires 2.40 GiB per tread. it seems to be the same case as before but instead of a real lower requirement then meant it takes more than meant.
This is also the case with the script below (This script is run on non bought servers, except for n00dles and foodnstuff).
while (true) { hack("CSEC") }
Should require 1.70 GiB per tread but uses 2.00 GiB
[HandyGold75]
Here is an export of my save file (bitburnerSave_1647685808_BN5x0.json) as I can't upload the file directly I uploaded it to my g drive: https://drive.google.com/drive/folders/1Aa8MIhnIq2XtzT7GDnS6Rjk8L2FeerlM?usp=sharing
[k4zter]
wasn't able to access c:/ and had to use a script to remove all contents in the file to get rid of the folder even tho the game fully recognizes that there is a file there with c:/
Bitburner v1.4.0 (49de4a28)(steam)
Comments From Original Issue
[phyzical]
just to confirm (this is obviously windows right?)
or have you created a folder called c:/?
didn't relise we give bitburner access to the hardrive..
i assume we dont otherwise thats pretty scarey....
[k4zter]
yeah it was a folder i pushed from VSC and it took the file dir of my folder on my pc...
[phyzical]
hmm might be something to ask in the discord channel for VS code. (but we can try to repo it and see what happens) 👍
[k4zter]
Yeah I fixed it by changing the settings in vsc to not push my PC Dir but the people that I was asking help to fix this told me to issue it anyways
[phyzical]
@lordducky hey thought i would tag you on this one, any chance this can be added as part of your webserver updates :). tldr we just need to make sure that we cant save invalid directory names i.e
c:\
and/
as these cannot becd
into once they are copied across via the webserver
[macdjord]
I had a coding contract window open when a script I had running in the background called the exercise-at-gym singularity function. This caused the game to switch to the gym training screen and the contract window to vanish. When I went back to the terminal and tried to reopen the contract by running it again, I got an error message saying "There's already a Coding Contract in Progress". I had to reload the game to get the contract open again.
Version: Bitburner v1.3.0 (9fdc3ac5)
Comments From Original Issue
[SagePtr]
Also contract window disappears when you return your focus to faction job (hacking contracts for instance) when coding contract window is opened. You cannot programmatically solve contracts after this (the game thinks contract is running) until you reload the game.
[nulflux]
This also happens when triggering a DOM click() on a menu option like City as the contract window is open. The coding contract is forever in progress and there is no way to return to it. There are two potential solutions for this: 1) instead of an error the run command could default to cancel and re-open the contract or 2) make available a command to cancel the current contract. Solution 1 solves the problem universally; solution 2 allows the users to solve the problem themselves. Since there is no special mechanic preventing players pre-singularity from running a coding contract programmatically I don't believe it should be a singularity function but rather a function available by default.
[phyzical]
idk if this should be fixed, by changing focus is it not expected to close windows?
or is it more of a the window should be there when you go back to the terminal?
[macdjord]
@phyzical The problem isn't that the window closes. The problem is you can't reopen it because the game thinks its still open.
[BrianLDev]
This bug happened to me today too in the way @SagePtr described.
If you have a contract open and change focus to Faction work, the coding contract UI disappears but the game incorrectly thinks that it's still open. Doesn't look like there's a way to get the UI to pop back up again, and trying to run the contract again gives an error message.
There's already a Coding Contract in Progress
. The only way to fix it is to close and reopen the game.
[BrianLDev]
So I'm guessing the fix would be in the code that handles focus. It should check for any open coding contracts and simply close them before changing focus.
[macdjord]
@BrianLDev That seems like treating the symptom rather than the problem to me. A better solution would be to change the 'is a coding contract in progress' check so it actually checks whether there is a contract window open - as in, examine the DOM - rather than depend on finding every possible way that the contract window could get closed and ensuring each one marks the window as closed first.
[holgero]
Why is there a guard against opening the contract again, anyway? Perhaps just delete that?
[rayanth]
@holgero it was likely intended in order to prevent two different coding contracts from being opened at the same time. I agree with @macdjord that the better fix would be in the check for a coding contract in progress, but rather than simply check if a window is open, check if a different contract's window is open. If the same coding contract's window is thought to be open, just display it again.
[YoshiRulz]
Just hit this on 2.0.2 via Steam.
[hydroflame]
Every file in the game should match [a-zA-Z0-9\-_](/[a-zA-Z0-9\-_])*\.(js|script|txt)
. Note the lack is leading slash in ALL files. Foldered or not.
Make a function to sanitize filename (convert // to /, remove leading slash, etc, take a look at electron.tsx)
Make another function that validates a filename (to catch weird extension and other invalid characters like spaces)
Write a save file migration that sanitizes all txt and scripts.
Make the txt and scripts array on server private
, will narrow down everything that uses them.
Write a function called like BaseServer.prototype.findFile
so that nothing needs read access to the private arrays
Comments From Original Issue
[daanflore]
Do not know if my issue is related to my "problem" in the game:
Bug reports that I was making:
Seems like when you ns.exec command contains a script in a sub folder when you do not start it with / the system does not detect that it is already running and start the script as a new process
Save file:
githubIssue-bitburnerSave_1642281820_BN1x0.txt](https://github.com/danielyxie/bitburner/files/7875918/githubIssue-bitburnerSave_1642281820_BN1x0.txt)Steps to reproduce:
run the script startup.js multiple times and you will see that home server runs same server multiple timesVersion of the game, e.g. Bitburner v1.3.0 (216bf616):
Bitburner v1.3.0 (bab67866)Would the new match logic prevent the problem with ns.exec I notices?
Or are they not related.
[phyzical]
@daanflore yeah it basically is 👍
also danielyxie/bitburner#1935 may be related
[davidpa9708]
Last section of danielyxie/bitburner#2783
Hacking server with low amounts of money results in no money stolen
test with server: 'foodnstuff', no extra security and around 3000 hack skill
to hack some money, at least 1$
0
money on the server. (foodnstuff)grow
from terminalhack
from terminal Bitburner v1.4.0 (a3c599e6)
[home ~/]> connect foodnstuff
Connected to foodnstuff
[foodnstuff ~/]> analyze
Analyzing system...
[||||||||||||||||||||||||||||||||||||||||||||||||||]
foodnstuff:
Organization name: FoodNStuff
Root Access: YES
Can run scripts on this host: YES
Backdoor: YES
Required hacking skill for hack() and backdoor: 1
Server security level: 3.000
Chance to hack: 100.00%
Time to hack: 0.333 seconds
Total money available on server: $0.000
Required number of open ports for NUKE: 0
SSH port: Open
FTP port: Closed
SMTP port: Closed
HTTP port: Closed
SQL port: Closed
[foodnstuff ~/]> grow
[||||||||||||||||||||||||||||||||||||||||||||||||||]
Available money on 'foodnstuff' grown by NaN%. Gained 19.916 hacking exp.
Security increased on 'foodnstuff' from 3.000 to 3.100
[foodnstuff ~/]> analyze
Analyzing system...
[||||||||||||||||||||||||||||||||||||||||||||||||||]
foodnstuff:
Organization name: FoodNStuff
Root Access: YES
Can run scripts on this host: YES
Backdoor: YES
Required hacking skill for hack() and backdoor: 1
Server security level: 3.100
Chance to hack: 100.00%
Time to hack: 0.333 seconds
Total money available on server: $25.470
Required number of open ports for NUKE: 0
SSH port: Open
FTP port: Closed
SMTP port: Closed
HTTP port: Closed
SQL port: Closed
[foodnstuff ~/]> hack
[||||||||||||||||||||||||||||||||||||||||||||||||||]
Hack successful on 'foodnstuff'! Gained $0.000 and 19.916 hacking exp
Security increased on 'foodnstuff' from 3.100 to 3.102
[foodnstuff ~/]> analyze
Analyzing system...
[||||||||||||||||||||||||||||||||||||||||||||||||||]
foodnstuff:
Organization name: FoodNStuff
Root Access: YES
Can run scripts on this host: YES
Backdoor: YES
Required hacking skill for hack() and backdoor: 1
Server security level: 3.102
Chance to hack: 100.00%
Time to hack: 0.333 seconds
Total money available on server: $25.470
Required number of open ports for NUKE: 0
SSH port: Open
FTP port: Closed
SMTP port: Closed
HTTP port: Closed
SQL port: Closed
Comments From Original Issue
[davidpa9708]
we could show a message like not enough money on server to gain money
[zeddrak]
Since hack is a percentage of remaining money, it is entirely possible you can hacking $0.000001 per hack, and it's only a display issue... '_'
[davidpa9708]
it is entirely possible you can hacking $0.000001 per hack
@zeddrak I would expect that to happen, but I think we are currently
floor
ing the money stolen when hacking
[phyzical]
to be fair though do we reaaaaaaaally want to se that we hack 0.0000001 $ it would have such little effect that someone else would complain that they dont get their fraction of a cent in the total because it probably does something similar for display
imo its not worth it
[BinarySpike]
Using bitburner v1.4.0 (steam edition?)
You cannot write arrays to ports with tryWritePort
using a .script
file, but you can with a .js
file.
// portsTest.script
var i = 0;
clearPort(1);
var values = ["SOMETHING REALLY LONG", "SOMETHINGE ELSE REALLY LONG TOO"];
while (tryWritePort(1, values)) {
i++;
var input = readPort(1);
print('portsLength ' + i + " peek: " + input[0] + " " + input[1]);
}
tprint('portLength ' + i);
fails by printing portsLength xxx peek: undefined undefined
// portsTest.js
/** @param {NS} ns **/
export async function main(ns) {
var i = 0;
ns.clearPort(1);
var values = ["SOMETHING REALLY LONG", "SOMETHINGE ELSE REALLY LONG TOO"];
while (await ns.tryWritePort(1, values)) {
i++;
var input = await ns.readPort(1);
await ns.print('portsLength ' + i + " peek: " + input[0] + " " + input[1]);
await ns.sleep(0);
}
await ns.tprint('portLength ' + i);
}
Works successfully with portsLength 1145 peek: SOMETHING REALLY LONG SOMETHINGE ELSE REALLY LONG TOO
Comments From Original Issue
[zeddrak]
because your script version isn't waiting for the port read maybe?
var input = readPort(1); //<-- no await... so is the readPort returning a promise?
print('portsLength ' + i + " peek: " + input[0] + " " + input[1]);
[zeddrak]
It's been so long since I used ns1 scripts I don't even remember if it can be waited for?
[BinarySpike]
await
is a syntax error in ns1 scripts:Error processing Imports in test.script: SyntaxError: Unexpected token (1:17)
It's an issue with ns1. I'm not sure how it gets translated, but the type definition is
String | Number
and the implementation isany
. AFAIK ns2 uses the implementation directly, so it's not an issue.
[phyzical]
is ns1 still supported? i thought i remember reading somewhere it is not
[sjauld]
According to the contract instructions,
NOTE: Numbers in the expression cannot have leading 0's. In other words, "1+01" is not a valid expression
However, for the question ["51655173017", -55], the following term was accepted in the solution.
"51-6551-7+3017"
It seems like the "no leading zeros" rule has not been implemented.
Comments From Original Issue
[Phlarx]
(as the formatting seems to have gone awry, here is the actual formula from the above report)
51-6*5*5*1-7+3*017
[heap-underflow]
I haven't tried adding random wrong answers to my answer arrays, but it seems like a few of the solution validators would have this issue, since the logic turns into
correct := expectedAnswerSet is-subset-of playerAnswerSet
. I guess that you'd really want to ensure the symmetric difference was empty.
[Darren-Gannon]
This is a MINOR issue. I have a work around for it, its just not clean.
Dynamic RAM usage calculations fail to account for barrel files. In my /lib/index.js
I want to roll up all the modules in my lib
folder, but in order to avoid the dynamic ram error I need call the imported variable.
v1.4.0(49de4a28)
/lib/get-all-hosts.js
(1.8GB)
/** @param {NS} ns **/
export async function main(ns) {
ns.tprint(getAllHosts(ns));
}
/**
* @param {NS} ns
**/
export function getAllHosts(ns) {
const hosts = ns.scan();
for(const host of hosts) {
const newHosts = ns.scan(host)
const additionalHosts = newHosts.filter(newHost => !hosts.includes(newHost))
hosts.push(...additionalHosts);
}
return hosts;
}
/lib/index.js
(1.6GB)
export { getAllHosts } from '/lib/get-all-hosts.js'
test.js
(1.6GB)
import { getAllHosts } from '/lib/index.js'
/** @param {NS} ns **/
export async function main(ns) {
ns.tprint(getAllHosts(ns))
}
In the barrel file (/lib/index.js
) read the imported VARIABLE
import { getAllHosts } from '/lib/get-all-hosts.js';
getAllHosts;
export { getAllHosts }
[hydroflame]
Which does stuff like make sure your programs are in order.
Comments From Original Issue
[phyzical]
need more info to infer this one 😄
[Master-Guy]
What would be the difference between the "base" reset, and the reset while killing all scripts?
(Novice in the game, hope I'm not asking stupid questions)
[alainbryden]
https://github.com/danielyxie/bitburner/blob/176ddd4f0b30a9d69dda35b2dfabc972ac069d3e/src/Server/BaseServer.ts#L201
In the implementation of rm
(a.k.a. BaseServer.RemoveFile
) we remove a script by slicing it out of our array - but before we do so we should go:
URL.revokeObjectURL(this.scripts[i].url);
So that the blob associated with this script can be garbage collected.
[macdjord]
There are several issues with the current bladeburner UI for synthoid population and community counts:
I propose that the UI be changed to display synthoid population and community counts as a chart like so:
City | Est. Synth. Pop. | Pop. Error | Est. Communities | Coms. Error |
---|---|---|---|---|
Sector-12 | 1.2b | +20% / -8% | 123 | +2 / -4 |
Aevum | 1.8b | +1% / -12% | 87 | +5 / -4 |
Volhaven | 123m | +30% / -30% | 17 | +1 / -0 |
Version: a3c599e
Comments From Original Issue
[zeddrak]
We're given a number of actions that we're told will improve the accuracy of these estimates, and a skill which will make these actions more effective. However, we're given no feedback for how accurate these estimates are to start with, or how much our actions are improving them.
Every time the player completes an action which improves their estimates, the error boundaries are reduced and the estimates are updated
Isn't that what the range of the error tells you? If the error is +10 / -12, then your estimate isn't very good. Increasing the accuracy should reduce the range of the error, to something more like +5 / -6 (this is an estimate that's "twice" as accurate as the previous one, for example). So completing those actions means the "estimate" is now more closely bounded to the error range (ie, your estimate is more accurate and the range of error is reduced.).
We are given occasional intelligence updates hinting at changes to populations - migrations and such - but these don't update our estimated populations, nor is there any good way to track them over time.
When the player gets an intelligence update about a migration, the estimates do not change, but the error bars do, and in the appropriate direction (e.g. if the player is notified about a migration from Sector-12 to Aevum, then the negative error boundary of Sector-12 and the positive error boundary of Aevum increase)
I'm assuming this is because we don't know how many actually migrated (ie we have an unconfirmed report, so we know what we started with - our unchanged estimations - and we know how many were reported as having moved - our updated error bars - but we haven't confirmed how many actually arrived, nor how many gave up and went back, etc, so our estimates have become less accurate.)
Essentially, migrations make estimates less accurate over time (as more migrations occur), while the actions we take make them more accurate - this is the dance (basically, if you do nothing, then the migrations will eventually make the estimates near useless)...
[macdjord]
Isn't that what the range of the error tells you? If the error is +10 / -12, then your estimate isn't very good.
That's the problem - right now, we don't get to see the error range. It isn't displayed anywhere.
[phyzical]
related danielyxie/bitburner#2861
[Knyffen]
My current hacking setup works in three layers:
ns.hackServer
/ns.growServer
/ns.weakenServer
commands.I have noticed that whenever a layer 3. processes finish (by reaching the end of the function), the layer 2. process that started it has an increase in earnings and experience. However, when the layer 2 process ends (either via ns.exit
, return
, or when another process kills it with ns.kill
), the layer 1 process remains at zero earnings and zero experience.
This behavior prevents me from having any substantial offline earnings.
I am currently using the steam version on windows, but it should be platform-agnostic.
I don't know if it is a bug, as it might very well just be that there is an undocumented requirement for when earnings and experience is inherited between processes. My request is therefore for that requirement to be documented. If it turns out to be a bug, tell me, and I will prepare a MWE script.
Thank you for your time. :-)
Comments From Original Issue
[phyzical]
is this not valid? layer 1 doesnt do any actions and thus earns nothing
unless we expect these sort of stats to trickle up?
higher powers question
[Knyffen]
The layer 2 process doesn't do any actions either, yet when the layer 3 process finishes the layer 2 process inherits its earnings/hour number.
Just to be clear: I don't know how its supposed to work (which is the entire point of the ticket), but I have just noticed the inconsistency in that the layer 2 process inherits the earnings of the layer 3 process (once it finishes), yet the layer 1 process doesn't inherit the earnings of the layer 2 process.
Personally, I think it makes sense to have the stats trickle up, since it allows the player to write more modular (often cleaner) scripts without being punished by having practically no offline earnings.
[phyzical]
ah yep the fact it trickles up one layer, i agree it should probably bubble up all the way and is probably a bug, thanks or the reply.
[phyzical]
@Knyffen quick one where is the "total earnings per script actually found" having a hard time finding the right place to workout how it works
[Snarling]
It looks like this was fixed during one of the major edits to launching scripts. Here is a test script and test output I used to verify:
//testLayers.js /** @param {NS} ns */ export async function main(ns) { const layer = ns.args[0] || 1; const lastLayer = layer === 5; ns.tprintf(`${" ".repeat(layer - 1)}Started layer ${layer}.`) if (!lastLayer) ns.run("testLayers.js", 1, layer + 1); // Hack n00dles until it is successful, but only for the last layer. if (lastLayer) while (!await ns.hack("n00dles")); // Wait until this script has some profit. Then print this script's income and exit. let profit; while (!profit) await ns.asleep(1000).then(() => profit = ns.getRunningScript().onlineMoneyMade); // Print script profit, then exit after 1s. ns.tprintf(`${" ".repeat(layer - 1)}Layer ${layer} detected profit of \$${profit}`); await ns.asleep(1000); }[03:57:32] [foodnstuff ~/]> run testLayers.js [03:57:32] Running script with 1 thread(s), pid 66 and args: []. [03:57:32] Started layer 1. [03:57:32] Started layer 2. [03:57:32] Started layer 3. [03:57:32] Started layer 4. [03:57:32] Started layer 5. [03:59:11] Layer 5 detected profit of $287 [03:59:12] Layer 4 detected profit of $287 [03:59:14] Layer 3 detected profit of $287 [03:59:16] Layer 2 detected profit of $287 [03:59:18] Layer 1 detected profit of $287
Note that if a layer 2 process is killed before the layer 3 process, then the layer 3 process will still not transfer its earnings to the level 1 process. Script income transfers up 1 layer and it happens when a script dies, so the only time you transfer income from layer 2 to 1 is when the layer 2 process dies.
[macdjord]
home
:
test_run.js
:/** @param {NS} ns **/
export async function main(ns) {
const deploy_from_servers = [
"n00dles",
"foodnstuff",
"sigma-cosmetics",
"joesguns",
"hong-fang-tea",
"harakiri-sushi",
"iron-gym",
];
const host_server = "home";
const test_script = "/test_sleep.js";
for (const deploy_from_server of deploy_from_servers) {
ns.connect(deploy_from_server);
ns.exec(test_script, host_server);
ns.connect("home");
}
}
test_sleep.js
:/** @param {NS} ns **/
export async function main(ns) {
await ns.sleep(60 * 1000);
}
test_run.js
from the terminal (Singularity functions required)test_sleep.js
all running on home
, all with the same arguments (i.e. none)Version: a3c599e
Comments From Original Issue
[phyzical]
i think the fact you can run multiple scripts with the same args is valid.
But the log bug is probably a bug related to scripts getting confused or rather not being unique enough.
[macdjord]
@phyzical No, by design you cannot run multiple copies of the same script with the same arguments on the same server; if you try the game will refuse to run it and tell you that the script is already running.
[phyzical]
welll... this has either changed or its now a bug. last time i launched my batchers i remember seeing plenty of the same scripts.
ill have a look at my scripts and give it a try, maybe i was taking on multiple arguments.
[hydroflame]
Nah this is weird a.f.
[hydroflame]
null
Comments From Original Issue
[phyzical]
is this one implemented? i had a look around for bitnode multipliers and gyms but had no luck seeing anything anymore
[MartinFournier]
I recommend you add the missing tags for version updates in the repository. I stopped listing revisions around 2 years ago.
git tag v0.43.1 9137c2427415c4dc344876a3c30ee445d92ebe4f
git tag v0.44.0 f1e43a86db09fa2dbc1e334c5ab6a907fef50c18
git tag v0.44.1 f2b4ae86926bb1a7977a36bd4a002ef16da74ebc
git tag v0.45.1 29c5c9b99d397cab675166439417a41e48dbf17e
git tag v0.46.1 2e9b028174623b6ddde3a47ced94dc66fcfd16ea
git tag v0.46.2 7417fb6ef8f3b62b4c5f4263da771a5195425039
git tag v0.46.3 bcb198220d9a2745e71d2389ef2a1355b9c6c58b
git tag v0.47.0 15a324a9466d360cc6f7be844076c799fe33889b
git tag v0.47.1 433b399de9397b805181dc89c8e1a024e6490dbe
git tag v0.47.2 59cf1d5baf78ccca32dfefe80717cbb1d284c23a
git tag v0.47.3 e9dfe3c3896329a135f96302e372c46926ff5101
git tag v0.48.0 56441b8e34b595d31e0f90354f47ab84ec72fac8
git tag v0.49.0 123628ec0b81383516e727f5a88c7262c99c84cd
git tag v0.49.1 a00c253dcb2768dd7ecb90f555be5e94ac2e8429
git tag v0.49.3 31e9f65f0622a4dec8f8133420b3fe8c44b59ae3
git tag v0.50.2 69124e7146003aad1acfc245bce9e62073750865
git tag v0.51.0 e572c6dad8793ba5a9ca6c1e76041c6eedd324f9
git tag v0.51.1 db2bf79e3b9e2fae7835a95597d1513ab1849662
git tag v0.51.2 925e96345da94b9f994f0be97c953cbcbad3793c
git tag v0.51.3 4e5ebcfe6f6bf08f7b040ff68383e7ac57821b4d
git tag v0.51.4 135df8703c651e17e0a1eae5a534c6f08ad215c1
git tag v0.51.5 b2aafea656bf1cbe4c143b62c35eba607af2d7d0
git tag v0.51.6 52a80ad23612562be51a8b7f9dd2c82b6553e39a
git tag v0.51.7 c9b5aaa2f74daa7323ae4ceb84ab63bf3b2c31ef
git tag v0.51.8 d96ad9fa6e8f94beb992c558b72e4a45352979dc
git tag v0.51.9 b28f60705697041be4bdf8213a4a91d089f1a290
git tag v0.52.1 8c9f78394b70d94dbba0b4e610eea88cb9eab190
git tag v0.52.2 67e5e413e4d98fb45caeb55f1427ea1bae8cb00a
git tag v0.52.3 e4b2a6853d713551cc31ec057e617da2a976abdf
git tag v0.52.4 1a1a43c1cea63f892c7946223d31157b8030403c
git tag v0.52.5 df457a0c6e07d847d22232ea28fc1d771832419a
git tag v0.52.6 474befa0919542b46656c29d9264c0447db3b74a
git tag v0.52.7 a564957092320bfb6c4df1175afb48733c26a953
git tag v0.52.8 6d2b8b4f6fb41ed74525653eea654922155eca2f
git tag v0.52.9 42704d86957482386f2197b27429490909b4ff22
git tag v0.53.0 cb31954b082fea47f8fe74632100c9fbf3c4e8ed
git tag v0.54.0 74906cc9e6498d728f93193096885214b172d16f
git tag v0.55.0 50cf362b3bd93255325bfa741a2911dedd33cedd
git tag v0.56.0 87c63cde59299c15de252e00acb6e29e69c420a7
git tag v0.57.0 c96c7e3d2e8bace9b983cff7b308c3031bf3c636
git tag v1.0.0 c87e9bdf843a05322e081d3527185483ca26e824
git tag v1.0.1 f3fa2a7c791a9166aa6a3b457776a4c47b4b4b58
git tag v1.1.0 3c27893aa30158fdd04ef2dc93f8cba1f13d6ece
git tag v1.2.0 02605090df38914ee5a288aedcc711d611d3e2fa
git tag v1.3.0 faf8389befec1b74133c6da6f892a6a7f951acdc
git tag v1.4.0 05cbc25a8fed73b9982925526940d65e55a842a1
git push --tags
v0.43.1 9137c24
v0.44.0 f1e43a8
v0.44.1 f2b4ae8
v0.45.1 29c5c9b
v0.46.1 2e9b028
v0.46.2 7417fb6
v0.46.3 bcb1982
v0.47.0 15a324a
v0.47.1 433b399
v0.47.2 59cf1d5
v0.47.3 e9dfe3c
v0.48.0 56441b8
v0.49.0 123628e
v0.49.1 a00c253
v0.49.3 31e9f65
v0.50.2 69124e7
v0.51.0 e572c6d
v0.51.1 db2bf79
v0.51.2 925e963
v0.51.3 4e5ebcf
v0.51.4 135df87
v0.51.5 b2aafea
v0.51.6 52a80ad
v0.51.7 c9b5aaa
v0.51.8 d96ad9f
v0.51.9 b28f607
v0.52.1 8c9f783
v0.52.2 67e5e41
v0.52.3 e4b2a68
v0.52.4 1a1a43c
v0.52.5 df457a0
v0.52.6 474befa
v0.52.7 a564957
v0.52.8 6d2b8b4
v0.52.9 42704d8
v0.53.0 cb31954
v0.54.0 74906cc
v0.55.0 50cf362
v0.56.0 87c63cd
v0.57.0 c96c7e3
v1.0.0 c87e9bd
v1.0.1 f3fa2a7
v1.1.0 3c27893
v1.2.0 0260509
v1.3.0 faf8389
v1.4.0 05cbc25
Comments From Original Issue
[phyzical]
seems responsible for debugging what things looked like at certain tags (shortcuts)
[Boraz]
Display size 4k: 3840 x 2160
Looking at Active Scripts
Expand a server
Pagination elements are pushed off screen when scripts have long details
Comments From Original Issue
[Boraz]
Looked into this further and built off dev branch. Page width is being pushed out by the script name/details. They are not wrapping on the current size of their container. It pushed everything out and might be wrapping on the max window size. I can now scroll left and right with long names.
I may attempt a fix. 🤞
[LuisAmorimDev]
My keyboard when im write have caracters wrong, the keys are not like the leanguage of my keyboard and i cant change that in the game.
Comments From Original Issue
[phyzical]
workaround would be to ask users to use some sort of keyboard software to being english?
actual solutions would be a kin to adding other multi language support i.e translations
[Master-Guy]
Weird thought, but could it be that the Keyboard layout in the Windows settings of @raskilo are set incorrectly?
Using US-international myself as that is the most commonly used layout in the Netherlands, so I cannot reproduce this.
[MatthewTh0]
So, I found a weird interaction, this is almost undoubtedly a bug, but I did find a workaround so this is low-priority. If one tries to re-export a function (using export * from "fileWithFunctionExports";
) then it won't calculate RAM costs properly if you import from that file (using import {functionFromFileWithFunctionExports} from "reExportFile";
). Interestingly enough, if one imports directly from the file with function exports using a name (like import * as fooBar from "fileWithFunctionExports";
), it then calculates correctly, even if you don't use this name or change anything else.
Example:
libFunction.js
export function testFunc(ns) {
let x =ns.getServer();
}
importTest.js
import {testFunc} from "reExport";
/** @param {NS} ns **/
export async function main(ns {
testFunc(ns);
}
reExport.js (Bad version)
export * from "libFunction"; // won't calculate ram correctly when imported
reExport.js (Good version, somehow)
export * from "libFunction";
import * as FooBar from "libFunction"; // never used, but allows correct ram calculation
Exact Error:
RUNTIME ERROR
/scripts/hacking/foreverLoop.js@home
Dynamic RAM usage calculated to be greater than initial RAM usage on fn: getServer.
This is probably because you somehow circumvented the static RAM calculation.
Threads: 1
Dynamic RAM Usage: 3.60GB
Static RAM Usage: 1.60GB
One of these could be the reason:
* Using eval() to get a reference to a ns function
const myScan = eval('ns.scan');
* Using map access to do the same
const myScan = ns['scan'];
Sorry :(
Comments From Original Issue
[MatthewTh0]
So, I guess this doesn't fix it, but just gives the RAM cost of importing everything even if you don't use it.
[phyzical]
the way the ram usage works is it just parses your code for keywords that line up with functions that require ram nothing too special. there is probably code trying to stop you from trying to circumvent it, but
Interestingly enough, if one imports directly from the file with function exports using a name (like import * as fooBar from "fileWithFunctionExports";), it then calculates correctly,
this probably just isnt in whatever logic is trying to stop you if i was to guess
[MatthewTh0]
Now, from what I've tested, if you import from a file that has classes, it will give the RAM cost as if using ALL functions in the class even if you don't export the class or anything related to it (for example, importing a constant from a file with a class that isn't exported, and therefore has no way to be imported, will still cost you as if you used every function in the class).
[phyzical]
yes this is correct as if the current implementations.
the issue is (AFAIK) there are many ways to exploit the system ill leave those up to you to find ;) (part of the game in its current state) but tbh when i first started playing i wanted it to work like you have done,
just wanted more readable/reusable code 😆 one workaround would be to have a bunch of files instead of say one helper file. even though that would be painful. and in many cases result in duplicate code
[jacktose]
Maybe this is a separate issue, but you can cause the same problem/hack by using default export import.
// find.js export default function find(ns, target, seen=[ns.getHostname()]) { const here = seen.slice(-1)[0]; if (here == target) { return seen; } for (const neighbor of ns.scan(here).filter(n => !seen.includes(n))) { const path = find(ns, target, seen.concat(neighbor)); if (path) { return path; } } return null; }// auto_connect.js import { default as find } from '/find.js'; // <- causes error //`import { find } from '/find.js';` // <- works fine function auto_connect(ns, server) { find(ns, server).forEach(ns.connect); const endpoint = ns.getCurrentServer(); return endpoint; } export async function main(ns) { return auto_connect(ns, ns.args[0]); }By “the problem,” I mean that the in-game editor's RAM button doesn't show the RAM from the import, and I get the runtime error as quoted above.
[macdjord]
There is no out-of-game (and almost no in-game) documentation for how gangs are supposed to work. I managed to get through BN2 using this two-year-old guide on Reddit, plus occasionally reading the source code. Now I'm on another BN, and I can't even figure out how to start a gang - I've joined the Slum Snakes faction, but the 'Form gang' button isn't showing up. The guide suggests that you need different amounts of negative karma to form a gang on different bitnodes, but we have (supposedly) complete documentation for the bitnode multipliers and 'karma required for gang' is not among them.
Version: a3c599e
Comments From Original Issue
[zeddrak]
As far as I know, you need approximately -54k karma to start a gang, This has been the same for all BN's I've played in.
It's not documented anywhere that I could find either, nor explained well. I just used the API to constantly try to create a gang every few seconds.
[macdjord]
Note that the question of 'Why can't I start a gang?' is only one part of what needs to be documented. The whole process and mechanics of gangs needs to be explained.
[phyzical]
yeah part of the issue with this one is i thiiink its meant to be a motivation for the user to find out how/why in the source code, motivate them to learn about opensource
(encouraging users to understand why things don't work how they expect)
there is probably a consideration on spoilers also
[Sleaker]
For control scripts that actively launch multiple other scripts in quick succession it becomes impossible to navigate the list once the last page has been reached as the footer UI which controls rows per page and back continually pops up and down as scripts are destroyed/started up.
This can make finding a specific script on servers with many active scripts difficult to find in the active scripts page.
UI elements that control navigation should be locked in place elements so they don't bounce around:
Fix 1) move the navigation elements to the header,
Fix 2) Fill in empty rows until 'rows per page' has been reached.
Side feature: make the search box filter out any scripts that don't have the name, not just the servers with them running.
Comments From Original Issue
[phyzical]
if this hasn't been addressed i think it would be a good idea. i know i've had a hard time clicking the right script sometimes.
[ballardrog]
Steps to reproduce:
/** @param {NS} ns **/
export async function main(ns) {
delayedPrint(ns);
await ns.asleep(10_000);
}
async function delayedPrint(ns) {
await ns.asleep(5_000);
ns.tprint("Foo");
}
Would it be possible to mark the environment of a killed process, so that the error only shows up for scripts that exited normally instead of also showing up for scripts that were killed?
Note that there is a workaround:
/** @param {NS} ns **/
export async function main(ns) {
delayedPrint(ns).then(() => { }, () => { });
await ns.asleep(10_000);
}
async function delayedPrint(ns) {
await ns.asleep(5_000);
ns.tprint("Foo");
}
Comments From Original Issue
[heap-underflow]
IMO, the bug is in the fact that your delayedPrint (an async function) doesn't always throw the uncaught promise error when it's not awaited (or otherwise resolved) like you have, not that it only sometimes does (when killed).
You get the same error, with a slightly different
delayedPrint
function, even without killing the process./** @param {NS} ns **/ export async function main(ns) { delayedPrint(ns) ns.asleep(10_000) } async function delayedPrint(ns) { ns.tprint(0) await ns.asleep(1_000) ns.tprint(1) await ns.asleep(1_000) ns.tprint(2) }So, I don't think the issue is in how it's behaving when scripts are killed, I think the real issue (in a loose sense) is that you don't always get the error when you're not resolving promises.
An alternative to your
/then
then might beawait Promise.all([delayedPrint(ns), ns.asleep(10_000)])
[ballardrog]
The modified version you gave is only throwing an error because the asleep in main isn't being awaited. The error happens when code in a promise tries to access ns after the script dies, which can happen either because main exits normally or the process is killed. There are valid usecases for not awaiting an asleep-based function; I don't think that should always be an error. (And I don't think there's a clean way to make it be, anyway.)
[phyzical]
not sure if this helps or is even possible but can you use the workerscripts's
.env.stopFlag
?
[hydroflame]
null
Comments From Original Issue
[phyzical]
This miight be closable given the new keyboard code changes
[macdjord]
I'm currently working on an automated contract-solving suite, but it's slow going, mostly because I cannot create my interfaces or test my solutions without an actual contract of a given type.
I propose two new functions be added, to allow players to practice contract and test solvers without needing to wait for real contracts of the appropriate type:
ns.codingcontract.listContractTypes()
: Returns a list of all the types of coding contract in the game. 0GB RAM cost.ns.codingcontract.generateSampleContract(contractType, host?, name?)
: Causes a contract of the given type to be immediately spawned. Such a contract will always have a reward of $0. If possible, such contracts will give the player unlimited attempts. Returns the name of the generated contract, or the empty string on failure.
host
: Server on which to create the contract; default to the server the script is running onname
: Filename to give the contract; must end in '.cct'; defaults to a random filename of the form contract-######-test.cct
Comments From Original Issue
[phyzical]
cool idea 👍
i would argue that it should cost ram though, forces the user to be sparing with ram as with anything in the game.
[macdjord]
@phyzical Yes, of course.
listContractTypes()
should be 0-cost, like all static game info functions, butgenerateSampleContract()
would cost some RAM. Not sure how much; that sort of balance question is up to the devs.
[MaWo2]
I really like this idea. It would help me, too.
It would also push this game even more into the educational direction.However, I am not sure, whether RAM cost really is an issue here. In most use-cases, people would spawn the test contract only once, most likely from the terminal or a separate script. Accordingly, the RAM-cost is neglectible (as long as it is not extremely high).
Therefore, I was wondering, whether this function might be something you could buy from the darknet, for instance, or develop at a certain level.
A completely different approach: Make it a degree at the University.
[hydroflame]
null
[hydroflame]
null
Comments From Original Issue
[Master-Guy]
Do you want this to be a yes/no prompt in the UI, or a textual yes/no question in the terminal?
The first is easy to implement, the latter might be very non-trivial
[Undeemiss]
bump. I can do this if given clear direction (I was planning to write a script to do this for my personal save, but can just write it as a feature instead if you want)
[macdjord]
The gameplay mechanic whereby you can work for a company & get promoted is almost entirely undocumented and has a non-discoverable, unclear GUI:
Comments From Original Issue
[Kebap]
Small improvements for point 1 and 2 maybe change button from "Apply for X" to "Promote in X" if you already hold that title and there is a promotion available (no matter if you fulfill the criteria yet) so players actually are shown a difference and can find more info with mouse-over.
[devnuhl]
Related to hovering and having information with a mouse-over, I just encountered the mouse-over information being irrelevant to my current position / next promotion. I know my current position because it's at the top.
The hover shows the basic position info, which it has not shown for the last several promotions, but the correct values. Attempting the promotion, though, says I'm ineligible because I lack the stats/rep I need. I'm guessing the tooltips may have been copy/pasted, and this one missed getting updated to the appropriate numbers?
[macdjord]
My expectations, based on this:
Instead, working for Volhaven I observed the following:
94.076 (8.111 / sec) reputation for this faction
42.158 (3.634 / sec) hacking exp
15.792 (1.361 / sec) strength exp
15.792 (1.361 / sec) defense exp
15.792 (1.361 / sec) dexterity exp
15.792 (1.361 / sec) agility exp
13.160 (1.135 / sec) charisma exp
97.625 (8.876 / sec) reputation for this faction
19.989 (1.817 / sec) hacking exp
22.463 (2.042 / sec) strength exp
22.463 (2.042 / sec) defense exp
22.463 (2.042 / sec) dexterity exp
22.463 (2.042 / sec) agility exp
I.e. security work is giving me more faction rep than field, and also giving me Hack exp when it shouldn't be. Also, while its giving more combat exp, its giving less Hack exp than field.
Comments From Original Issue
[Undeemiss]
I don't understand what the problem is here, beyond that security work should be listed as giving a little bit of hacking exp. It never made any claims about the scaling of these actions; my understanding is that field work intentionally scales worse than security work because it's easier to gain stats in general than specifically to gain physical stats.
[quyteriyaki]
Description: Unhandled promise reject with return value other than string results in a "Script runtime error. This is a bug please contact game developer"
Steps to reproduce:
import { NS } from '@ns'
export async function main(ns: NS): Promise<void> {
await new Promise<string>((resolve, reject) => {
reject(400)
})
}
Expected: The game notifies the location of the exception, something like ("You've written something that causes an exception, did you remember to handle it?") or the game outputs the message of the exception.
Actual: The game shows the the bug error with no meaningful response and the script hangs.
Suggested solution:
Comments From Original Issue
[phyzical]
i couldn't run the provided script verbaitum, if i run the following it get told an unexpected error occurs. (presumably because resolve is never called), if i add a resolve instead of reject things work.
export async function main(ns) { await new Promise((resolve, reject) => { reject(400) }) }
so the question is,
- is promises in user code supported?
- if so why doesn't it work.
[hydroflame]
null
Comments From Original Issue
[phyzical]
i think this one is closable too (unless we dont zip given certain conditions?)
[phyzical]
(unless we are referring to export in settings?)
[Master-Guy]
Just a basic ZIP reduces used storage by about 50%. In my case from ~160 MB to ~80 MB.
In a game that is all about optimization, this seems to be a basic thing to do :)
[Xynrati]
Should be standard support and handled the same everywhere
Comments From Original Issue
[rabirabirara]
To be specific, in the documentation (https://bitburner.readthedocs.io/en/latest/basicgameplay/terminal.html?highlight=backdoor#netscript), it is noted that files not in the root directory need to be referred to by absolute path. This is a limitation that is documented as part of the game; it is not a bug per se.
However, the documentation does not mention that you cannot refer to files in the root directory by absolute path in arguments passed to functions like
fileExists()
orexec()
. This is probably the main problem (besides the inherent inconsistency of NetScript's filepath behavior) and why a few people comment on the forward-slash in file paths.So for future users with this problem, you can do the following to standardize file paths so that they are correctly treated. This is a NetScript 2 function.
function standardize(path) { // remove all slashes at the start of the string let s = path.replace(/^\/*/g, ""); if (s.includes("/")) { // the file is not in the root directory; prepend a single slash return "/" + s; } else { // the file is in the root directory (no slashes in the filename that aren't in front); prepend no slashes return s; } }
[Xynrati]
Not exactly. If you do this using wget for files in the root folder, you'll cause problems.
[rabirabirara]
I see. Since your original post is quite bare, I had thought you were referring to a different problem. Could you elaborate what your issue actually is? After all, your choice of the word "oddness" leaves a lot to the imagination.
EDIT: I see; you're a contributor, which means this issue is probably something you're referring to yourself. My bad! I was thinking that this was along the lines of #1634, which was closed without comment. I was thinking I could be helpful to people with that problem, but I suppose I missed the mark on your issue.
[BrianLDev]
This came up in a broader discussion on the Discord dev channel about moving away from "magic strings" in general.
To start, hydroflame recommended converting Toasts, and then later we can look into enums for Gang names, crimes, universities, courses, etc.
Comments From Original Issue
[waffleattack]
Could I have an example for what the magic strings are in toasts?
[BrianLDev]
@waffleattack since hydroflame was the source of this request, they're the best one to ask for more details.
But if I had to guess, I'd say that the toast variants should be converted from magic strings into const objects/enums. Screenshot below:
[waffleattack]
ah so instead of inputting
ns.toast("Alert!", "warning", 10000)you would instead be able to do
ns.toast("Alert!", TOASTS.WARNING, 10000)if I understand it correctly?
[BrianLDev]
@waffleattack Yup, that's exactly how I'd do it. But you might want to check with hydroflame to see if they had anything else in mind.
[phyzical]
nah thats correct 👍
[hydroflame]
Yeah it's not that easy
How do you feedTOASTS
to the scripts?
[waffleattack]
could we do it similar to ns.args? so instead of using
TOASTS.WARNING
you would usens.TOASTS.WARNING
?
[hydroflame]
https://github.com/danielyxie/bitburner/blob/dev/src/ScriptEditor/NetscriptDefinitions.d.ts#L6426
If someone can uncomment this line and make it compile ...
[swofle]
Bitburner v1.4.0 (49de4a28)
The actual sell price of product is different from the price displayed in UI when player uses the 'MP' variable.
The displayed sell price is computed based on the estimated market price, but the sell price of the transaction uses the actual market price. This means that the displayed sell price is much lower than the actual value, resulting in confusion.
Setting the sell price: MP*70600
Setting the sell price: 650000000
You can see from the above example that although the 2nd sell price is ten times of the 1st one, the product is actually selling. While in the 1st instance, the product is not selling (net increase of 15.530/s).
It is stated in the description that 'MP' variable corresponds to the Product's estimated market price. So use that instead of the actual market price. Specifically change this line:
https://github.com/danielyxie/bitburner/blob/07fe3c1906b569799652cd1f7a36de2abe306802/src/Corporation/Industry.ts#L1178
to
sCost = sCostString.replace(/MP/g, product.pCost + "");
[bmartin1234]
Steps to reproduce:
It looks like shares owned by the player are not counted in the divisor for share price, so in this scenario target share price = valuation.
See /src/Corporation/Corporation.tsx line 189
Comments From Original Issue
[phyzical]
good spot, now whether this should be adjusted not sure (i would say probably? as corps are too op)
leaving to higher powers
[Xenosplitter]
When exiting an infiltration, open script (file.script and file.js) logs remain how they were set up before beginning the infiltration
Exiting an infiltration via running out of HP, completing the infiltration, canceling mid infiltration, and canceling before starting the infiltration cause all open script logs to reappear in the middle of the screen, how they appear when first opened. This resets log window sizes, positions, and minimized status.
Comments From Original Issue
[akuma6099]
I just wanted to tack onto this because I was about to open an issue on it. You can reproduce this problem by simpling navigating to any company, selecting infiltration, then cancel. I've yet to reach a level of XP to bring down the difficulty so I kept checking then cancelling and I observed this same behavior. My organized log windows stacked in the lower right corner all resized and opened in the middle as if I just launched the scripts with --tail.
[Xenosplitter]
Without doing any investigative work, a blind guess on why this might happen is that opening the infiltration screen tries to hide open logs. This might be done by noting which logs were open, closing them, then reopening the logs once more. This would explain why all windows reset (because they are in this theory). Perhaps a better way to hide the log windows would be to set their element display styles to
display: none;
temporarily, resetting back todisplay: flex;
once finished.
[hydroflame]
null
Comments From Original Issue
[phyzical]
to confirm i think this is the bug?
/** @param {NS} ns **/ export async function main(ns) { await ns.wget("https://gist.githubusercontent.com/ramzs/35fa68c0e4c83e4b66d2137d8364dbd6/raw/281998608078700ed213bad1cc019b31a5b2cccd/PaymentNotificator.gs", "/file.txt", "home") }
it works if i use
file.txt
if i use/file.txt
it saves it as a directory called / that you cannot cd into and cannot ls
[phyzical]
on a side note should we even allow this anymore given the vscode integration?
[phyzical]
related danielyxie/bitburner#2991
[Master-Guy]
Version: Steam - Bitburner v1.5.0 (3aabbb7)
Script:
export async function main(ns) {
ns.disableLog("ALL");
ns.purchaseServer("hostname", ns.getPurchasedServerMaxRam());
}
Reproduce: New save game (so you don't have enough money) and run the script.
Issue:
ns.purchaseServer()
and ns.deleteServer()
don't log errors after ns.disableLog("ALL")
even though the documentation tells us that it should. It might be a wider issue.
https://github.com/danielyxie/bitburner/blob/dev/markdown/bitburner.ns.disablelog.md
Note that this does not completely remove all logging functionality. This only stops a function from logging when the function is successful. If the function fails, it will still log the reason for failure.
Comments From Original Issue
[Master-Guy]
Needs a comment from @hydroflame on how to solve:
Either remove this part of the documentation (see the quote), or go through all functions and check if this has been implemented correctly.i.e.:
disableLog("ALL") currently works by adding all possible log options, so you can re-enable them one by one if you want to:if (fn === "ALL") { for (fn of Object.keys(possibleLogs)) { workerScript.disableLogs[fn] = true; }
However, the checks in PlayerObjectGeneralMethods.tsx are checking for "ALL" (an old way of doing it):
if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) {
The WorkerScript log doesn't differentiate between success and failure:
getPurchasedServerCost: function (ram: any): any { updateDynamicRam("getPurchasedServerCost", getRamCost(Player, "getPurchasedServerCost")); const cost = getPurchaseServerCost(ram); if (cost === Infinity) { workerScript.log("getPurchasedServerCost", () => `Invalid argument: ram='${ram}'`); return Infinity; }
log(func: string, txt: () => string): void { if (this.shouldLog(func)) {
shouldLog(fn: string): boolean { return this.disableLogs[fn] == null; }
[hydroflame]
null
Comments From Original Issue
[phyzical]
i assume this is about taking the users setting of locale/ adding a new number specific one and supporting https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
[Master-Guy]
If this is about using the regional settings, then I'm against this.
It would create a lot of weird situations where scripts at one time should use dots and at other times commas in decimal fields.
[BrianLDev]
This was talked about in depth on the Bitburner discord today (Feb 24, 2022), but to summarize:
There are a lot of Singularity API functions that require "magic strings" like University name, course name, Crime name, Faction name, etc. "Magic strings" are generally considered to be no bueno when it comes to good programming habits, so it would be great if we could add some simple constant objects that contain the names of related items.
note: these are usually called enums, but vanilla JS doesn't have enums, so they're implemented in JS as constant objects
Here's an example of all the crimes in a constant object (aka an enum):
export const Crimes = {
shoplift: "shoplift",
rob: "rob store",
mug: "mug someone",
larceny: "larceny",
dealDrugs: "deal drugs",
bondForgery: "bond forgery",
traffickIllegalArms: "traffick illegal arms",
homicide: "homicide",
grandTheftAuto: "grand theft auto",
kidnap: "kidnap",
assassination: "assassination",
heist: "heist",
none: "none"
};
Generally, enums allow for autocomplete which is one of the big benefits to avoid typos, misspellings, future changes to strings, etc. The autocomplete in Bitburner doesn't always seem to correctly look up object properties, so we would have to also make sure that functionality works as well.
Since autocomplete might create some spoilers, I highly recommend that these const objects (aka enums) get added to the Singularity API and marked as FREE (no RAM cost). When players have reached the Singularity API, they won't be spoiled by having a full list of University names, Crime names, etc. The other benefit of having these in the Singularity API is that players will probably run into problems with magic strings along the way, and experiencing that pain will show the value of using enums/const objects.
One nice thing about this change is that it would be "backwards compatible", meaning that the const enums will just provide a better way to input strings to function args, and all previously created functions and scripts will be unaffected.
Since this would be a moderate sized change, Hydroflame suggested that we start by converting the Toasts over to enums, so there's a separate issue created for that specific one (3032). Once the Toasts issue is resolved, we can move on to this one.
SUGGESTIONS FOR CONST OBJECTS/ENUMS:
No big spoiler concerns:
Possible spoiler concerns (will have to discuss before implementing)
Comments From Original Issue
[BrianLDev]
For the possible spoiler concern items: one way to minimize that is to keep the full enum hidden (e.g. Augmentation names), and create a separate object that contains only the items that the player has accessed so far.
That will prevent the player from seeing any spoilers, and new items can be added added every time a player accesses something new (e.g. joins a new faction with a list of augmentations not seen before)
[storm6436]
Minimal scripts to reproduce the issue: breakout.js (Included in save)
Steps to reproduce:
(Inconsistent reproduction, but frequent enough I'm finally filling this out)
run the following
'reset all'
'cm'
'run overseer.js'
'autopop'
'run breakout.js 5' <- # is largely irrelevant, any valid can trigger (valid: 0-5)
Then attempt to open the script editor, either by the navigation pane or via terminal with nano.
Notes: Have checked file integrity, etc. several times.
(Just whack the fake file extension. It's a bit odd to ask for a save file that's less than a MB and autoreject it based on extension.)
RECOVERY_BITBURNER_1643078738.json.notreallya.zip
Comments From Original Issue
[phyzical]
@storm6436 is this still an issue?
[storm6436]
Not sure? I'll have to check what patch supposedly fixed it and do some
testing once I get in a place that won't poleaxe my BN13 progress. Just
started the node yesterday and... it's slow.
On Sun, Mar 13, 2022, 08:13 Jack @.***> wrote:
@storm6436 https://github.com/storm6436 is this still an issue?
—
Reply to this email directly, view it on GitHub
danielyxie/bitburner#2799 (comment),
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ASAWRUBSROQFUZFSXRSH5J3U7XSWXANCNFSM5MXBPKOA
.
Triage notifications on the go with GitHub Mobile for iOS
https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675
or Android
https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.You are receiving this because you were mentioned.Message ID:
@.***>
[storm6436]
Yeah, got another crash just now. Not sure if you guys need me to upload that recovery file or not.
[phyzical]
@storm6436 all good, just wanted to confirm before trying to replicate ill let you know where i get
[borisflagell]
Still a valid issue as of 1.7.0
[hydroflame]
null
Comments From Original Issue
[phyzical]
Is this one just a matter of providing "reset" buttons for all actions, we would add it to the sell action also.
also adding api actions for this "cancel"
[HeinousTugboat]
Per hydro, adding an issue for this: we should add a proper pipeline so we can have both a beta and prod release, allowing us to release features to a limited set of users before more broadly pushing them out to the full userbase. Additionally, we should use envvars to track the deployed sha so we can avoid the chicken-and-egg issue of not knowing the current sha of the deployed code.
Comments From Original Issue
[marcjmiller]
This is up my alley, what does the current process look like? I don't see any CI/CD at present, so am I to assume it's a 100% manual job right now? I'm not familiar with building electron apps, but walk me through the steps and I'll at least get it started. I normally work in gitlab, so transitioning to GitHub actions might take a bit, but I'll give it a go.
[phyzical]
we are working on this, if you checkout the .github/workflows there is some. the main issue we currently have is lack of full access to handle secrets ect. soon we will be moving to an org to gain this control.
TLDR; i wouldn't worry about it at this time
[hydroflame]
https://github.com/HeinousTugboat/bitburner/blob/htugboat/deploy-wip/.github/workflows/deploy-pages.yml i
^ relevant
[Unkn0wnNPC]
Just run the script below and it'll always result in Infinite on various servers
export async function main(ns) { let destinations = ns.read("/hackV2/servers-sorted.txt"); destinations = JSON.parse(destinations); let test = ns.hackAnalyzeThreads("foodnstuff", 1) ns.print(test) }
bitburnerSave_1642201801_BN1x0.json.txt
Comments From Original Issue
[nickinitro]
can confirm!
[geiloschefos]
same...
[zeddrak]
Are you in a bitnode with a BitNodeMultipliers.ScriptHackMoney == 0?
If so, this would be the correct response (no amount of threads will allow you to steal any money)#2454
One recent correction that I know was made was to include the BitNodeMultipliers.ScriptHackMoney, but that shouldn't create this behavior where it wasn't before, as the 0 case would be the same either way.Similarly having a server security of 100+ should result in infinity, because of:
const difficultyMult = (100 - server.hackDifficulty) / 100;
As would a server.moneyAvailable == 0.
Basically, anything that makes this denominator 0 should return infinity:
return hackAmount / Math.floor(server.moneyAvailable * percentHacked);
hackAnalyzeThreads: function (hostname: any, hackAmount: any): any { updateDynamicRam("hackAnalyzeThreads", getRamCost(Player, "hackAnalyzeThreads")); // Check argument validity const server = safeGetServer(hostname, "hackAnalyzeThreads"); if (!(server instanceof Server)) { workerScript.log("hackAnalyzeThreads", () => "Cannot be executed on this server."); return -1; } if (isNaN(hackAmount)) { throw makeRuntimeErrorMsg( "hackAnalyzeThreads", `Invalid growth argument passed into hackAnalyzeThreads: ${hackAmount}. Must be numeric.`, ); } if (hackAmount < 0 || hackAmount > server.moneyAvailable) { return -1; } else if (hackAmount === 0) { return 0; } const percentHacked = calculatePercentMoneyHacked(server, Player); return hackAmount / Math.floor(server.moneyAvailable * percentHacked); }
/** * Returns the percentage of money that will be stolen from a server if * it is successfully hacked (returns the decimal form, not the actual percent value) */ export function calculatePercentMoneyHacked(server: Server, player: IPlayer): number { // Adjust if needed for balancing. This is the divisor for the final calculation const balanceFactor = 240; const difficultyMult = (100 - server.hackDifficulty) / 100; const skillMult = (player.hacking - (server.requiredHackingSkill - 1)) / player.hacking; const percentMoneyHacked = (difficultyMult * skillMult * player.hacking_money_mult * BitNodeMultipliers.ScriptHackMoney) / balanceFactor; if (percentMoneyHacked < 0) { return 0; } if (percentMoneyHacked > 1) { return 1; } return percentMoneyHacked; }
[zeddrak]
Hmm...
I guess that if BitNodeMultipliers.ScriptHackMoney could be < 0, then moving it before the check could result in a different behavior, but that'd still be really weird, as the previous version would've ended up in negative threads being needed.
[zeddrak]
Update, I am working on a fix for this in my scripts. Once I've completed and tested there, I will check with Hydroflame if he wants them imported into the source game. It is a complicated problem though (since the amount grown is now partially based on the threads used, making getting the threads needed a self-referential nightmare akin to determining how much rocket fuel you need to get into orbit...)
[zeddrak]
My Discord discussion in developement
Ok, concerning the growAnalyze, I have a couple of options to deal with the infinity issues:
danielyxie/bitburner#2635
danielyxie/bitburner#2628Option 1) Just retun Math.min(growAnalyze normal value, server.moneyMax) --- this basically assumes a minimum of $1 server and ignores the extra power added to grow ($1/thread) and so will return larger values than actually needed (potentially MANY times larger in some case. Theoretical example: if it takes 100 threads to double - grow x2 - a certain server with moneyMax of $200, then 100 threads is all that would be needed to grow it to max from $0, but this naïve solution is returning 200)
Option 2) Is basically to use a first order differential equation - ie, how many threads it takes is dependent on how many threads you need... I'll look up one of the approximation techniques for that kind of first order differential equation and use that (most approach very quickly, and we only need to get to an error <1 since integer threads anyways). This has the added advantage of taking into consideration the extra grow power for non-full grows as well.
Opinions?
(Follow-up: If we go with option 1, should I also change the previously discussed functions to behave accordingly - eliminating the infinity thing entirely? Basically, this would change the mechanic for growing <$1 servers to assume $1, instead of $1/thread, consistently.)
[phyzical]
i'm personally not a fan of having an equation
Mostly because a complicated algorithm to stop this issue will break one day, not if just when 😆The other way to look at this would be to fix the issue on the other side, anywhere the result could be
Infinity
make it invalid.
though i dont like this one because Infinity will eventually be a valid result due to the cap on number in JS land
So we would have to consider to use a number system similar to other idle games where they use letters for additional categorizing of large numbers. but we just have no reason for numbers to get bigger than the js cap at this timeimho, just make the minimum 0.00000000001 (or 1).
But its a question for higher powers
[DJ-Laser]
Ngl im kinda salty about this. I made a HACKING gang so I wouldn't have to worry about clashing, so when I lost all my territory on accident and it cut my production massively (~50m/sec to ~1m/sec) I was kinda mad. Now I'm trying to train all my members of a HACKING gang in COMBAT, so I can get territory to be able to make enough money to actually get enough neuroflux to get 15k skill and beat the BN, but it is so slow -_-
This is my 2nd BN so I only have gangs to work with, so I am stuck and it is kinda demoralizing to me to have all my hard work lost and I might need to flume and reset. Pls fix this.
Steps:
Version: Bitburner v1.6.1 (d949907)
Save:
bitburnerSave_1648836646_BN2x0.txt
Comments From Original Issue
[phyzical]
what do you mean by "accidentally lost territory"? i would just flume and do it again if you messed up
[hydroflame]
That won't fix this users issue but we'll make hacking gangs participate in territory warfare with their hacking skills.
[macdjord]
Closing a script by clicking the 'X' button on its tab at the top of the screen will sometimes ask if you want to save changes, even though the tab was not showing the 'unsaved changes' asterisk.
Note: Every time this has happened, it has been a file I thought I had already saved, so I believe the problem is that the editor is asking to save changes when there are none, but it's possible the files had changed and I'd forgotten, in which case the actual bug is 'editor not displaying unsaved-changes asterisk'.
Version: a3c599e
Comments From Original Issue
[phyzical]
@macdjord mind giving exact repo steps please?
[macdjord]
@phyzical Don't have them; that's why I said 'sometimes'.
[phyzical]
im sorry but there is only so much time one can dedicate to a plethora of bug reports, without enough information bugs get closed to reduce the load of trying to fix more important bugs.
[OriginalRobotWizard]
This is super easy 100% reproducible:
- nano test.txt
- Close and save
- Start over at 1 (popup to be asked to save will be displayed every time for .txt files)
[phyzical]
thx is it only txt files by chance?
[OriginalRobotWizard]
Yes, it only happens with .txt files. Not with .js, .script, or .ns files.
[hydroflame]
null
Comments From Original Issue
[phyzical]
is this one
- just a matter of replaces the
with pre tags- just removing them and tweeking the text until they are all readable?
- just removing the
entirely?
[borisflagell]
Still a relevant issue as of 1.7.0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.