Merge pull request #252 from danielyxie/dev

v0.37.1
This commit is contained in:
danielyxie 2018-05-22 19:16:06 -05:00 committed by GitHub
commit 25be246a57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 18392 additions and 17208 deletions

15992
dist/engine.bundle.js vendored

File diff suppressed because it is too large Load Diff

15992
dist/tests.bundle.js vendored

File diff suppressed because it is too large Load Diff

BIN
doc/build/doctrees/changelog.doctree vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,725 @@
.. _changelog:
Changelog
=========
v0.37.1
-------
* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based
on the difficulty of the contract.
* Completing Field Analysis in Bladeburner now grants 0.1 rank
* The maximum RAM you can get on a purchased server is now 1,048,576 GB (2^20)
* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS
* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS
* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to
* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.
* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms
v0.37.0 - 5/20/2018
-------------------
* NetscriptJS (Netscript 2.0) released (Documentation here: http://bitburner.readthedocs.io/en/latest/netscriptjs.html)
* Running the game with the '?noScripts' query will start the game without loading any of your scripts. This should be used if you accidentally write a script that crashes your game
v0.36.1 - 5/11/2018
-------------------
* Bladeburner Changes:
* Bug Fix: You can no longer get Bladeburner faction reputation through Infiltration
* Initial difficulty of Tracking contracts reduced
* Datamancer skill effect increased from 4% per level to 5%
* Slightly decreased the base stamina cost of contracts/operations
* Slightly increased the effects of the Tracer, Digital Observer, Short Circuit, Cloak, and Blade's Intuition skills
* Overclock skill capped at level 95, rather than 99
* Training gives significantly more exp/s
* Crime, Infiltration, and Hacking are now slightly more profitable in BN-6
* Gyms are now more expensive, but give slightly more exp
* Added getScriptName() and getHacknetMultipliers() Netscript functions (added by Github user hydroflame)
* getScriptRam() Netscript function now has default value for the second argument, which is hostname/ip (implemented by Github user hydroflame)
* There is now a soft-cap on stock price, which means it's no longer possible for the price of a stock to reach insanely-high values
* The ctrl+b hotkey in the text editor should now also be triggered by command+b on OSX (I don't have OSX so I can't confirm if this works)
* Many servers now have additional RAM
* Added an option to disable hotkeys/keyboard shortcuts
* Refactored 'Active Scripts' UI page to optimize its performance
* Added a new .fconf Terminal setting: ENABLE_TIMESTAMP
* 'Netscript Execution Time', which can be found in the Options, now has a minimum value of 15ms rather than 25ms
* Bug Fix: Fixed a typo in the Fulcrum Technologies company name (Technolgies -> Technologies)
* Bug Fix: hacknetnodes keyword should no longer incur RAM cost if its in a comment
* Bug Fix: disableLog() now works for the commitCrime() Netscript function (fixed by Github user hydroflame)
v0.36.0 - 5/2/2018
------------------
* Added BN-6: Bladeburners
* Rebalanced many combat Augmentations so that they are slightly less powerful
* Bug Fix: When faction invites are suppressed, an invitation will no longer load the Faction page
v0.35.2 - 3/26/2018
-------------------
* Corporation Changes:
* Fixed an issue with Warehouse upgrade cost. Should now be significantly cheaper than before.
* Scientific Research now has a slightly more significant effect on Product quality
* The Energy and Water Utilities industries are now slightly more profitable
* The Robotics and Computer Hardware industries are now less profitable
* The Software industry is slightly less profitable
* When selling Materials and Products, the 'PROD' qualifier can now be used to set dynamic sell amounts based on your production
* Exporting MAX should now work properly
* You can no longer export past storage limits
* Scientific Research production reduced
* Effects of AdVert. Inc upgrade were reduced, but the effect that popularity and awareness have on sales was increased to compensate (popularity/awareness numbers were getting too big with Advert. Inc)
* Bug Fix: Products from Computer Hardware division should now properly have ratings
* Improved Augmentation UI/UX. Now contains collapsible headers and sort buttons
* Improved Faction Augmentations display UI/UX. Now contains sort buttons. There is also an option to disable confirmation when purchasing Augmentations
v0.35.1 - 3/12/2018
-------------------
* You can now easily download all of your scripts/text files as zip folders. Use the 'help download' Terminal command for details
* Scripts are now downloaded with the .script.js extension at the end of their filename
* Corporation Management Changes:
* Implemented Smart Supply unlock
* Changed the way a division's Production Multiplier is calculated. It is now the sum of the individual Production Multiplier for every city. Therefore, it is now beneficial to open offices in different cities
* Several small UI/UX improvements
* Numerous balance changes. The significant ones are listed below.
* Product descriptions will now display their estimated market price
* The sale price of Products can no longer be marked up as high as before
* Scientific Research now affects the rating of Products
* In general, the maximum amount of product you are able to sell is reduced
* Sale bonus from advertising (popularity/awareness) now has diminishing returns rather than scaling linearly
* Experience gained during Infiltration now scales linearly based on the clearance level you reach. Compared to before, the experience gained will be much less at lower clearance levels, but much more at higher clearance levels
* The editor can now be used to edit both scripts and text files
* New Terminal config file that can be edited using the command 'nano .fconf'. Right now there is only one option, but there will be more in the future.
* You can now enable Bash-style Terminal hotkeys using the .fconf file referenced above
* Bug Fix: Fixed an issue with the UI elements of Gang Management persisting across different instances of BitNode-2
v0.35.0 - 3/3/2018
------------------
* Minor rebalancing of BitNodes due to the fact that Corporations provide a (relatively) new method of progressing
* Corporation Management Changes:
* Once your Corporation gets big/powerful enough, you can now bribe Factions for reputation using company funds an/or stock shares
* You can now only create one Division for every Industry type
* Added several new UI/UX elements
* Wilson Analytics multiplier was significantly reduced to 1% per level (additive).
* Reduced the effect of Advert Inc upgrade. Advert Inc. upgrade price increases faster
* Materials can now be marked up at higher prices
* Added Javascript's built-in Number object to Netscript
* Added getCharacterInformation(), getCompanyFavor(), and getFactionFavor() Netscript Singularity functions
* Rebalanced Singularity Function RAM Costs. They now cost x8 as much when outside of BN-4 (rather than x10). Also, many of the functions now use significantly less RAM
* Refactored Netscript Ports. You can now get a handle for a Netscript port using the getPortHandle() Netscript function. This allows you to access a port's underlying queue (which is just an array) and also makes several new functions available such as tryWrite(), full(), and empty().
* Number of Netscript Ports increased from 10 to 20
* Netscript assignments should now return proper values. i.e. i = 5 should return 5.
* Added throw statements to Netscript. It's not super useful since 'catch' isn't implemented, but it can be used to generate custom runtime error messages.
* Added import declaration to Netscript. With this, you are able to import functions (and only functions) from other files. Using export declarations is not necessary
* Most Netscript Runtime errors (the ones that cause your script to crash) should now include the line number where the error occured
* When working for a company, your current company reputation is now displayed
* Whenever you get a Faction Invite it will be immediately appended to your 'invited factions' list. Therefore the checkFactionInvitations() Singularity Function should now be properly useable since you no longer need to decline a Faction Invitation before it shows up in the result.
* Bug Fix: When purchasing servers, whitespace should now automatically be removed from the hostname
* Bug Fix: Can no longer have whitespace in the filename of text files created using write()
* Bug Fix: In Netscript, you can no longer assign a Hacknet Node handle (hacknetnodes[i]) to another value
* Bug Fix: If you are in the Factions tab when you accept an invitation from a Faction, the page will now properly 'refresh'
* Bug Fix: Scripts that run recursive functions should now be killed properly
v0.34.5 - 2/24/2018
-------------------
* Corporation Management Changes:
* Market Research unlocks are now cheaper
* New 'VeChain' upgrade: displays useful statistics about Corporation
* Corporation cycles are processed 25% faster
* Corporation valuation was lowered by ~10% (this affects stock price and investments)
* Rebalanced the effects of advertising. Should now be more effective for every Industry
* Fixed several bugs/exploits involving selling and buying back stock shares
* You will now receive a Corporation Handbook (.lit file) when starting out BitNode-3. It contains a brief guide to help you get started. This same handbook can be viewed from the Corporation management screen
* Slightly decreased the amount by which a Product's sell price can be marked up
* Employees can now be assigned to a 'Training' task, during which they will slowly increase several of their stats
* Hopefully fixed an exploit with Array.forEach(). If there are any issues with using forEach, let me know
* Arguments passed into a script are now passed by value. This means modifying the 'args' array in a script should no longer cause issues
* Scripts executed programatically (via run(), exec(), etc.) will now fail if null/undefined is passed in as an argument
* Added peek() Netscript function
* killall() Netscript function now returns true if any scripts were killed, and false otherwise.
* hack() Netscript function now returns the amount of money gained for successful hacks, and 0 for failed hacks
* scp Terminal command and Netscript function now work for txt files
* Changes courtesy of Wraithan:
* Text files are now displayed using 'pre' rather than 'p' elements when using the 'cat' Terminal command. This means tabs are retained and lines don't automatically wrap
* ls() Netscript function now returns text files as well
* Removed round() Netscript function, since you can just use Math.round() instead
* Added disableLog() and enableLog() Netscript functions
* Removed the 'log' argument from sleep(), since you can now use the new disableLog function
* 'Netscript Documentation' button on script editor now points to new readthedocs documentation rather than wiki
* When working for a faction, your current faction reputation is now displayed
* Bug Fix: Hacking Missions should no longer break when dragging an existing connection to another Node
* Bug Fix: Fixed RAM usage of getNextHacknetNodeCost() (is not 1.5GB instead of 4GB)
v0.34.4 - 2/14/2018
-------------------
* Added several new features to Gang UI to make it easier to manage your Gang.
* Changed the Gang Member upgrade mechanic. Now, rather than only being able to have one weapon/armor/vehicle/etc., you can purchase all the upgrades for each Gang member and their multipliers will stack. To balance this out, the effects (AKA multipliers) of each Gang member upgrade were reduced.
* Added a new script editor option: Max Error Count. This affects how many approximate lines the script editor will process (JSHint) for common errors. Increasing this option can affect negatively affect performance
* Game theme colors (set using 'theme' Terminal command) are now saved when re-opening the game
* 'download' Terminal command now works on scripts
* Added stopAction() Singularity function and the spawn() Netscript function
* The 'Purchase Augmentations' UI screen will now tell you if you need a certain prerequisite for Augmentations.
* Augmentations with prerequisites can now be purchased as long as their prerequisites are puchased (before, you had to actually install the prerequisites before being able to purchase)
v0.34.3 - 1/31/2018
-------------------
* Minor balance changes to Corporations:
* Upgrades are generally cheaper and/or have more powerful effects.
* You will receive more funding while your are a private company.
* Product demand decreases at a slower rate.
* Production multiplier for Industries (receives for owning real estate/hardware/robots/etc.) is slightly higher
* Accessing the hacknetnodes array in Netscript now costs 4.0GB of RAM (only counts against RAM usage once)
* Bug Fix: Corporation oustanding shares should now be numeric rather than a string
* Bug Fix: Corporation production now properly calculated for industries that dont produce materials.
* Bug Fix: Gangs should now properly reset when switching BitNodes
* Bug Fix: Corporation UI should now properly reset when you go public
v0.34.2 - 1/27/2018
-------------------
* Corporation Management Changes:
* Added advertising mechanics
* Added Industry-specific purchases
* Re-designed employee management UI
* Rebalancing: Made many upgrades/purchases cheaper. Receive more money from investors in early stage. Company valuation is higher after going public
* Multiple bug fixes
* Added rm() Netscript function
* Updated the way script RAM usage is calculated. Now, a function only increases RAM usage the first time it is called. i.e. even if you call hack() multiple times in a script, it only counts against RAM usage once. The same change applies for while/for loops and if conditionals.
* The RAM cost of the following were increased:
* If statements: increased by 0.05GB
* run() and exec(): increased by 0.2GB
* scp(): increased by 0.1GB
* purchaseServer(): increased by 0.25GB
* Note: You may need to re-save all of your scripts in order to re-calculate their RAM usages. Otherwise, it should automatically be re-calculated when you reset/prestige
* The cost to upgrade your home computer's RAM has been increased (both the base cost and the exponential upgrade multiplier)
* The cost of purchasing a server was increased by 10% (it is now $55k per RAM)
* Bug fix: (Hopefully) removed an exploit where you could avoid RAM usage for Netscript function calls by assigning functions to a variable (foo = hack(); foo('helios');)
* Bug fix: (Hopefully) removed an exploit where you could run arbitrary Javascript code using the constructor() method
* Thanks to Github user mateon1 and Reddit users havoc_mayhem and spaceglace for notifying me of the above exploits
* The fileExists() Netscript function now works on text files (.txt). Thanks to Github user devoidfury for this
v0.34.1 - 1/19/2018
-------------------
* Updates to Corporation Management:
* Added a number of upgrades to various aspects of your Corporation
* Rebalanced the properties of Materials and the formula for determining the valuation of the Corporation
* Fixed a number of bugs
* 'Stats' page now shows information about current BitNode
* You should now be able to create Corporations in other BitNodes if you have Source-File 3
* Added a new create-able program called b1t_flum3.exe. This program can be used to reset and switch BitNodes
* Added an option to adjust autosave interval
* Line feeds, newlines, and tabs will now work with the tprint() Netscript function
* Bug fix: 'check' Terminal command was broken
* Bug fix: 'theme' Terminal command was broken when manually specifying hex codes
* Bug fix: Incorrect promotion requirement for 'Business'-type jobs
* Bug fix: Settings input bars were incorrectly formatted when loading game
v0.34.0 - 12/6/2017
-------------------
* Added clear() and exit() Netscript functions
* When starting out or prestiging, you will now receive a 'Hacking Starter Guide'. It provides tips/pointers for new players
* Doubled the amount of RAM on low-level servers (up to required hacking level 150)
* Slightly increased experience gain from Infiltration
* buyStock(), sellStock(), shortStock(), and sellShort() Netscript function now return the stock price at which the transaction occurred, rather than a boolean. If the function fails for some reason, 0 will be returned.
* Hacking Mission Changes:
* You can now select multiple Nodes of the same type by double clicking. This allows you to set the action of all of selected nodes at once (e.g. set all Transfer Nodes to Fortify). Creating connections does not work with this multi-select functionality yet
* Shield and Firewall Nodes can now fortify
* The effects of Fortifying are now ~5% lower
* Conquering a Spam Node now increases your time limit by 25 seconds instead of 15
* Damage dealt by Attacking was slightly reduced
* The effect of Scanning was slightly reduced
* Enemy CPU Core Nodes start with slightly more attack. Misc Nodes start with slightly less defense
* Corporation Management changes:
* Added several upgrades that unlock new features
* Implemented Exporting mechanic
* Fixed many bugs
v0.33.0 - 12/1/2017
-------------------
* Added BitNode-3: Corporatocracy. In this BitNode you can start and manage your own corporation. This feature is incomplete. Much more will be added to it in the near future
* Minor bug fixes
v0.32.1 - 11/2/2017
-------------------
* Updated Netscript's 'interpreter/engine' to use the Bluebird promise library instead of native promises. It should now be faster and more memory-efficient. If this has broken any Netscript features please report it through Github or the subreddit (reddit.com/r/bitburner)
* Rebalanced stock market (adjusted parameters such as the volatility/trends/starting price of certain stocks)
* Added prompt() Netscript function
* Added 'Buy Max' and 'Sell All' functions to Stock Market UI
* Added 'Portfolio' Mode to Stock Market UI so you can only view stocks you have a position/order in
* Added a button to kill a script from its log display box
v0.32.0 - 10/25/2017
--------------------
* Added BitNode-8: Ghost of Wall Street
* Re-designed Stock Market UI
* Minor bug fixes
v0.31.0 - 10/15/2017
--------------------
* Game now saves to IndexedDb (if your browser supports it). This means you should no longer have trouble saving the game when your save file gets too big (from running too many scripts). The game will still be saved to localStorage as well
* New file type: text files (.txt). You can read or write to text files using the read()/write() Netscript commands. You can view text files in Terminal using 'cat'. Eventually I will make it so you can edit them in the editor but that's not available yet. You can also download files to your real computer using the 'download' Terminal command
* Added a new Crime: Bond Forgery. This crime takes 5 minutes to attempt and gives $4,500,000 if successful. It is meant for mid game.
* Added commitCrime(), getCrimeChance(), isBusy(), and getStats() Singularity Functions.
* Removed getIntelligence() Netscript function
* Added sprintf and vsprintf to Netscript. See [https://github.com/alexei/sprintf.js this Github page for details]
* Increased the amount of money gained from Infiltration by 20%, and the amount of faction reputation by 12%
* Rebalanced BitNode-2 so that Crime and Infiltration are more profitable but hacking is less profitable. Infiltration also gives more faction rep
* Rebalanced BitNode-4 so that hacking is slightly less profitable
* Rebalanced BitNode-5 so that Infiltration is more profitable and gives more faction rep
* Rebalanced BitNode-11 so that Crime and Infiltration are more profitable. Infiltration also gives more faction rep.
* Fixed an annoying issue in Hacking Missions where sometimes you would click a Node but it wouldnt actually get selected
* Made the Hacking Mission gameplay a bit slower by lowering the effect of Scan and reducing Attack damage
* Slightly increased the base reputation gain rate for factions when doing Field Work and Security Work
v0.30.0 - 10/9/2017
-------------------
* Added getAugmentations() and getAugmentationsFromFaction() Netscript Singularity Functions
* Increased the rate of Intelligence exp gain
* Added a new upgrade for home computers: CPU Cores. Each CPU core on the home computer grants an additional starting Core Node in Hacking Missions. I may add in other benefits later. Like RAM upgrades, upgrading the CPU Core on your home computer persists until you enter a new BitNode.
* Added lscpu Terminal command to check number of CPU Cores
* Changed the effect of Source-File 11 and made BitNode-11 a little bit harder
* Fixed a bug with Netscript functions (the ones you create yourself)
* Hacking Missions officially released (they give reputation now). Notable changes in the last few updates:
* Misc Nodes slowly gain hp/defense over time
* Conquering a Misc Node will increase the defense of all remaining Misc Nodes that are not being targeted by a certain percentage
* Reputation reward for winning a Mission is now affected by faction favor and Player's faction rep multiplier
* Whenever a Node is conquered, its stats are reduced
v0.29.3 - 10/3/2017
-------------------
* Fixed bug for killing scripts and showing error messages when there are errors in a player-defined function
* Added function name autocompletion in Script Editor. Press Ctrl+space on a prefix to show autocompletion options.
* Minor rebalancing and bug fixes for Infiltration and Hacking Missions
v0.29.2 - 10/1/2017
-------------------
* installAugmentations() Singularity Function now takes a callback script as an argument. This is a script that gets ran automatically after Augmentations are installed. The script is run with no arguments and only a single thread, and must be found on your home computer.
* Added the ability to create your own functions in Netscript. See [[Netscript Functions|this link]] for details
* Added :q, :x, and :wq Vim Ex Commands when using the Vim script editor keybindings. :w, :x, and :wq will all save the script and return to Terminal. :q will quit (return to Terminal) WITHOUT saving. If anyone thinks theres an issue with this please let me know, I don't use Vim
* Added a new Augmentation: ADR-V2 Pheromone Gene
* In Hacking Missions, enemy nodes will now automatically target Nodes and perform actions.
* Re-balanced Hacking Missions through minor tweaking of many numbers
* The faction reputation reward for Hacking Missions was slightly increased
v0.29.1 - 9/27/2017
-------------------
* New gameplay feature that is currently in BETA: Hacking Missions. Hacking Missions is an active gameplay mechanic (its a minigame) that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation for the time being, since the feature likely has many bugs, balance problems, and other issues. If you have any feedback regarding the new feature, feel free to let me know
* CHANGED THE RETURN VALUE OF getScriptIncome() WHEN RAN WITH NO ARGUMENTS. It will now return an array of two values rather than a single value. This may break your scripts, so make sure to update them!
* Added continue statement for for/while loops
* Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions
* Netscript scp() function can now take an array as the first argument, and will try to copy every file specified in the array (it will just call scp() normally for every element in the array). If an array is passed in, then the scp() function returns true if at least one element from the array is successfully copied
* Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's static methods will work (now(), UTC(), parse(), etc.).
* Failing a crime now gives half the experience it did before
* The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup)
* fileExists() function now works on literature files
v0.29.0 - 9/19/2017
-------------------
* Added BitNode-5: Artificial Intelligence
* Added getIp(), getIntelligence(), getHackingMultipliers(), and getBitNodeMultipliers() Netscript functions (requires Source-File 5)
* Updated scan() Netscript function so that you can choose to have it print IPs rather than hostnames
* Refactored scp() Netscript function so that it takes an optional 'source server' argument
* For Infiltration, decreased the percentage by which the security level increases by about 10% for every location
* Using :w in the script editor's Vim keybinding mode should now save and quit to Terminal
* Some minor optimizations that should reduce the size of the save file
* scan-analyze Terminal command will no longer show your purchased servers, unless you pass a '-a' flag into the command
* After installing the Red Pill augmentation from Daedalus, the message telling you to find 'The-Cave' will now repeatedly pop up regardless of whether or not you have messages suppressed
* Various bugfixes
v0.28.6 - 9/15/2017
-------------------
* Time required to create programs now scales better with hacking level, and should generally be much faster
* Added serverExists(hostname/ip) and getScriptExpGain(scriptname, ip, args...) Netscript functions
* Short circuiting && and || logical operators should now work
* Assigning to multidimensional arrays should now work
* Scripts will no longer wait for hack/grow/weaken functions to finish if they are killed. They will die immediately
* The script loop that checks whether any scripts need to be started/stopped now runs every 6 seconds rather than 10 (resulting in less delays when stopping/starting scripts)
* Fixed several bugs/exploits
* Added some description for BitNode-5 (not implemented yet, should be soon though)
v0.28.5 - 9/13/2017
-------------------
* The fl1ght.exe program that is received from jump3r is now sent very early on in the game, rather than at hacking level 1000
* Hostname is now displayed in Terminal
* Syntax highlighting now works for all Netscript functions
* Export should now work on Edge/IE
v0.28.4 - 9/11/2017
-------------------
* Added getScriptIncome() Netscript function
* Added Javascript's math module to Netscript. See [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math this link for details]
* Added several member variables for the Hacknet Node API that allow you to access info about their income
* All valid Netscript functions are now syntax highlighted as keywords in the editor. This means they will a different color than invalid netscript functions. The color will depend on your theme. Note that right now, this only applies for normal Netscript functions, not functions in the TIX API, Hacknet Node API, or Singularity Functions.
* Comments and operators no longer count towards RAM usage in scripts.
* Variety of bug fixes and updates to informational text in the game
v0.28.3 - 9/7/2017
------------------
* Added ls() Netscript function
* Increased company wages by about ~10% across the board
* The scp() Netsction function and Terminal command now works for .lit files
* Increased the amount of RAM on many lower level servers (up to level 200 hacking level required).
v0.28.2 - 9/4/2017
------------------
* Added several configuration options for script editor (key bindings, themes, etc.)
* Certain menu options will now be hidden until their relevant gameplay is unlocked. This includes the Factions, Augmentations, Create Program, Travel, and Job tabs. This will only affect newer players.
* Most unrecognize or un-implemented syntax errors in Netscript will now include the line number in the error message
v0.28.1 - 9/1/2017
------------------
* The script editor now uses the open-source Ace editor, which provides a much better experience when coding!
* Added tprint() Netscript function
v0.28.0 - 8/30/2017
-------------------
* Added BitNode-4: The Singularity
* Added BitNode-11: The Big Crash
* Migrated the codebase to use webpack (doesn't affect any in game content, except maybe some slight performance improvements and there may be bugs that result from dependency errors
v0.27.3 - 8/19/2017
-------------------
* You can now purchase upgrades for Gang Members (BitNode 2 only)
* Decreased Gang respect gains and slightly increased wanted gains (BitNode 2 only)
* Other gangs will increase in power faster (BitNode 2 only)
* Added getHackTime(), getGrowTime(), and getWeakenTime() Netscript functions
v0.27.2 - 8/18/2017
-------------------
* Added getServerGrowth() Netscript function
* Added getNextHacknetNodeCost() Netscript function
* Added new 'literature' files (.lit extension) that are used to build lore for the game. These .lit files can be found in certain servers throughout the game. They can be viewed with the 'cat' Terminal command and copied over to other servers using the 'scp' command. These .lit files won't be found until you reset by installing Augmentations
* Fixed some bugs with Gang Territory(BitNode 2 only)
v0.27.1 - 8/15/2017
-------------------
* Changed the way Gang power was calculated to make it scale better late game (BitNode 2 only)
* Lowered the respect gain rate in Gangs (Bitnode 2 only)
* Added '| grep pattern' option for ls Terminal command. This allows you to only list files that contain a certain pattern
* Added break statement in Netscript
* Display for some numerical values is now done in shorthand (e.g 1.000m instead of 1,000,000)
v0.27.0 - 8/13/2017
-------------------
* Added secondary 'prestige' system - featuring Source Files and BitNodes
* MILD SPOILERS HERE: Installing 'The Red Pill' Augmentation from Daedalus will unlock a special server called w0r1d_d43m0n. Finding and manually hacking this server through Terminal will destroy the Player's current BitNode, and allow the player to enter a new one. When destroying a BitNode, the player loses everything except the scripts on his/her home computer. The player will then gain a powerful second-tier persistent upgrade called a Source File. The player can then enter a new BitNode to start the game over. Each BitNode has different characteristics, and many will have new content/mechanics as well. Right now there are only 2 BitNodes. Each BitNode grants its own unique Source File. Restarting and destroying a BitNode you already have a Source File for will upgrade your Source File up to a maximum level of 3.
* Reputation gain with factions and companies is no longer a linear conversion, but an exponential one. It will be much easier to gain faction favor at first, but much harder later on.
* Significantly increased Infiltration exp gains
* Fixed a bug with company job requirement tooltips
* Added scriptRunning(), scriptKill(), and getScriptRam() Netscript functions. See documentation for details
* Fixed a bug with deleteServer() Netscript function
v0.26.4 - 8/1/2017
------------------
* All of the 'low-level servers' in early game that have a required hacking level now have 8GB of RAM instead of 4GB
* Increased the amount of experience given at university
* Slightly increased the production of Hacknet Nodes and made them cheaper to upgrade
* Infiltration now gives slightly more EXP and faction reputation
* Added two new crimes. These crimes are viable to attempt early on in the game and are relatively passive (each take 60+ seconds to complete)
* Crimes give more exp and more money
* Max money available on a server decreased from 50x the server's starting money to 25x
* Significantly increased wages for all jobs
v0.26.3
-------
* Added support for large numbers using Decimal.js. Right now it only applies for the player's money
* Purchasing servers with the Netscript function purchaseServer() is no longer 2x as expensive as doing manually it now costs the same
* Early game servers have more starting money
v0.26.2
-------
* Major rebalancing and randomization of the amount of money that servers start with
* Significantly lowered hacking exp gain from hacking servers. The exp gain for higher-level servers was lowered more than that of low level servers. (~16% for lower level servers, up to ~25% for higher-level servers)
* Added deleteServer() Netscript function
* You can now purchase a maximum of 25 servers each run (Deleting a server will allow you to purchase a new one)
* Added autocompletion for './' Terminal command
* Darkweb prices now displayed properly using toLocaleString()
* Added NOT operator (!) and negation operator(-) in Netscript, so negative numbers should be functional now
* Rejected faction invitations will now show up as 'Outstanding Faction Invites' in the Factions page. These can be accepted at any point in the future
* Added a few more configurable game settings for suppressing messages and faction invitations
* Added tooltips for company job requirements
v0.26.1
-------
* Added autocompletion for aliases
* Added getServerRam() Netscript function()
* Added getLevelUpgradeCost(n), getRamUpgradeCost(), getCoreUpgradeCost() functions for Netscript Hacknet Node API
* Added some configurable settings (See Game Options menu)
v0.26.0
-------
* Game now has a real ending, although it's not very interesting/satisfying right now. It sets up the framework for the secondary prestige system in the future
* Forgot to mention that since last update, comments now work in Netscript. Use // for single line comments or /* and */ for multiline comments just like in Javascript
* Added ports to Netscript. These ports are essentially serialized queues. You can use the write() Netscript function to write a value to a queue, and then you can use the read() Netscript function to read the value from the queue. Once you read a value from the queue it will be removed. There are only 10 queues (1-10), and each has a maximum capacity of 50 entries. If you try to write to a queue that is full, the the first value is removed. See wiki/Netscript documentation for more details
* You can now use the 'help' Terminal command for specific commands
* You can now use './' to run a script/program (./NUKE.exe). However, tab completion currently doesn't work for it (I'm working on it)
* Decreased the base growth rate of servers by ~25%
* Both the effect of weaken() and its time to execute were halved. In other words, calling weaken() on a server only lowers its security by 0.05 (was 0.1 before) but the time to execute the function is half of what it was before. Therefore, the effective rate of weaken() should be about the same
* Increased all Infiltration rewards by ~10%, and increased infiltration rep gains by an additional 20% (~32% total for rep gains)
* The rate at which the security level of a facility increases during Infiltration was decreased significantly (~33%)
* Getting treated at the Hospital is now 33% more expensive
* Slightly increased the amount of time it takes to hack a server
* Slightly decreased the amount of money gained when hacking a server (~6%)
* Slightly decreased the base cost for RAM on home computer, but increased the cost multiplier. This means that upgrading RAM on the home computer should be slightly cheaper at the start, but slightly more expensive later on
* Increased the required hacking level for many late game servers
* The sleep() Netscript function now takes an optional 'log' argument that specifies whether or not the 'Sleeping for N milliseconds' will be logged for the script
* Added clearLog() Netscript function
* Deleted a few stocks. Didn't see a reason for having so many, and it just affects performance. Won't take effect until you reset by installing Augmentations
* There was a typo with Zeus Medical's server hostname. It is now 'zeus-med' rather than 'zeud-med'
* Added keyboard shortcuts to quickly navigate between different menus. See wiki link (http://bitburner.wikia.com/wiki/Shortcuts)
* Changed the Navigation Menu UI
v0.25.0
-------
* Refactored Netscript to use the open-source Acorns Parser. This re-implementation was done by [https://github.com/MrNuggelz Github user MrNuggelz]. This has resulted in several changes in the Netscript language. Some scripts might break because of these changes. Changes listed below: 
* Arrays are now fully functional Javascript arrays. You no longer need to use the 'Array' keyword to declare them. 
* The length(), clear/clear(), insert(), and remove() functions no longer work for arrays. 
* All Javascript array methods are available (splice(), push(), pop(), join(), shift(), indexOf(), etc. See documentation)
* Variables assigned to arrays are now passed by value rather than reference
* Incrementing/Decrementing are now available (i++, ++i)
* You no longer need semicolons at the end of block statements
* Elif is no longer valid. Use 'else if' instead
* Netscript's Hacknet Node API functions no longer log anything
* Stock prices now update every ~6 seconds when the game is active (was 10 seconds before)
* Added a new mechanic that affects how stock prices change
* Script editor now has dynamic indicators for RAM Usage and Line number
* Augmentation Rebalancing - Many late game augmentations are now slightly more expensive. Several early game augmentations had their effects slightly decreased
* Increased the amount of rewards (both money and rep) you get from infiltration
* Purchasing servers is now slightly more expensive
* Calling the Netscript function getServerMoneyAvailable('home') now return's the player's money
* Added round(n) Netscript function - Rounds a number
* Added purchaseServer(hostname, ram) Netscript function
* Added the TIX API. This must be purchased in the WSE. It persists through resets. Access to the TIX API allows you to write scripts that perform automated algorithmic trading. See Netscript documentation
* Minor rebalancing in a lot of different areas
* Changed the format of IP Addresses so that they are smaller (will consist mostly of single digit numbers now). This will reduce the size of the game's save file.
v0.24.1
-------
* Adjusted cost of upgrading home computer RAM. Should be a little cheaper for the first few upgrades (up to ~64GB), and then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.
* Slightly lowered the starting money available on most mid-game and end-game servers (servers with required hacking level greater than 200) by about 10-15%
* Rebalanced company/company position reputation gains and requirements
* Studying at a university now gives slightly more EXP and early jobs give slightly less EXP
* Studying at a university is now considerably more expensive
* Rebalanced stock market
* Significantly increased cost multiplier for purchasing additional Hacknet Nodes
* The rate at which facility security level increases during infiltration for each clearance level was lowered slightly for all companies
* Updated Faction descriptions
* Changed the way alias works. Normal aliases now only work at the start of a Terminal command (they will only replace the first word in the Terminal command). You can also create global aliases that work on any part of the command, like before. Declare global aliases by entering the optional -g flag: alias -g name="value" - [https://github.com/MrNuggelz Courtesy of Github user MrNuggelz]
* 'top' Terminal command implemented courtesy of [https://github.com/LTCNugget Github user LTCNugget]. Currently, the formatting gets screwed up if your script names are really long.
v0.24.0
-------
* Players now have HP, which is displayed in the top right. To regain HP, visit the hospital. Currently the only way to lose HP is through infiltration
* Infiltration - Attempt to infiltrate a company and steal their classified secrets. See 'Companies' documentation for more details
* Stock Market - Added the World Stock Exchange (WSE), a brokerage that lets you buy/sell stocks. To begin trading you must first purchase an account. A WSE account will persist even after resetting by installing Augmentations. How the stock market works should hopefully be self explanatory. There is no documentation about it currently, I will add some later. NOTE: Stock prices only change when the game is open. The Stock Market is reset when installing Augmentations, which means you will lose all your stocks
* Decreased money gained from hacking by ~12%
* Increased reputation required for all Augmentations by ~40%
* Cost increase when purchasing multiple augmentations increased from 75% to 90%
* Added basic variable runtime to Netscript operations. Basic commands run in 100ms. Any function incurs another 100ms in runtime (200ms total). Any function that starts with getServer incurs another 100ms runtime (300ms total). exec() and scp() require 400ms total. 
* Slightly reduced the amount of experience gained from hacking
v0.23.1
-------
* scan() Netscript function now takes a single argument representing the server from which to scan. 
v0.23.0
-------
* You can now purchase multiple Augmentations in a run. When you purchase an Augmentation you will lose money equal to the price and then the cost of purchasing another Augmentation during this run will be increased by 75%. You do not gain the benefits of your purchased Augmentations until you install them. This installation can be done through the 'Augmentation' tab. When you install your Augmentations, your game will reset like before. 
* Reputation needed to gain a favor from faction decreased from 7500 to 6500
* Reputation needed to gain a favor from company increased from 5000 to 6000
* Reputation cost of all Augmentations increased by 16%
* Higher positions at companies now grant slightly more reputation for working
* Added getServerMaxMoney() Netscript function
* Added scan() Netscript function
* Added getServerNumPortsRequired() Netscript function
* There is now no additional RAM cost incurred when multithreading a script
v0.22.1
-------
* You no longer lose progress on creating programs when cancelling your work. Your progress will be saved and you will pick up where you left off when you start working on it again
* Added two new programs: AutoLink.exe and ServerProfiler.exe
* Fixed bug with Faction Field work reputation gain
v0.22.0 - Major rebalancing, optimization, and favor system
-----------------------------------------------------------
* Significantly nerfed most augmentations
* Almost every server with a required hacking level of 200 or more now has slightly randomized server parameters. This means that after every Augmentation purchase, the required hacking level, base security level, and growth factor of these servers will all be slightly different
* The hacking speed multiplier now increases rather than decreases. The hacking time is now divided by your hacking speed multiplier rather than multiplied. In other words, a higher hacking speed multiplier is better
* Servers now have a minimum server security, which is approximately one third of their starting ('base') server security
* If you do not steal any money from a server, then you gain hacking experience equal to the amount you would have gained had you failed the hack
* The effects of grow() were increased by 50%
* grow() and weaken() now give hacking experience based on the server's base security level, rather than a flat exp amount
* Slightly reduced amount of exp gained from hack(), weaken(), and grow()
* Rebalanced formulas that determine crime success
* Reduced RAM cost for multithreading a script. The RAM multiplier for each thread was reduced from 1.02 to 1.005
* Optimized Script objects so they take less space in the save file
* Added getServerBaseSecurityLevel() Netscript function
* New favor system for companies and factions. Earning reputation at a company/faction will give you favor for that entity when you reset after installing an Augmentation. This favor persists through the rest of the game. The more favor you have, the faster you will earn reputation with that faction/company
* You can no longer donate to a faction for reputation until you have 150 favor with that faction
* Added unalias Terminal command
* Changed requirements for endgame Factions
v0.21.1
-------
* IF YOUR GAME BREAKS, DO THE FOLLOWING: Options -> Soft Reset -> Save Game -> Reload Page. Sorry about that! 
* Autocompletion for aliases - courtesy of [https://github.com/LTCNugget Github user LTCNugget]
v0.21.0
-------
* Added dynamic arrays. See Netscript documentation
* Added ability to pass arguments into scripts. See documentation
* The implementation/function signature of functions that deal with scripts have changed. Therefore, some old scripts might not work anymore. Some of these functions include run(), exec(), isRunning(), kill(), and some others I may have forgot about. Please check the updated Netscript documentation if you run into issues.-Note that scripts are now uniquely identified by the script name and their arguments. For example, you can run a script using::
run foodnstuff.script 1
and you can also run the same script with a different argument::
run foodnstuff.script 2
These will be considered two different scripts. To kill the first script you must run::
kill foodnstuff.script 1
and to kill the second you must run::
kill foodnstuff.script 2
Similar concepts apply for Terminal Commands such as tail, and Netscript commands such as run(), exec(), kill(), isRunning(), etc.
* Added basic theme functionality using the 'theme' Terminal command - All credit goes to /u/0x726564646974 who implemented the awesome feature
* Optimized Script objects, which were causing save errors when the player had too many scripts
* Formula for determining exp gained from hacking was changed
* Fixed bug where you could purchase Darkweb items without TOR router
* Slightly increased cost multiplier for Home Computer RAM
* Fixed bug where you could hack too much money from a server (and bring its money available below zero)
* Changed tail command so that it brings up a display box with dynamic log contents. To get old functionality where the logs are printed to the Terminal, use the new 'check' command
* As a result of the change above, you can no longer call tail/check on scripts that are not running
* Added autocompletion for buying Programs in Darkweb
v0.20.2
-------
* Fixed several small bugs
* Added basic array functionality to Netscript
* Added ability to run scripts with multiple threads. Running a script with n threads will multiply the effects of all hack(), grow(), and weaken() commands by n. However, running a script with multiple threads has drawbacks in terms of RAM usage. A script's ram usage when it is 'multithreaded' is calculated as: base cost * numThreads * (1.02 ^ numThreads). A script can be run multithreaded using the 'run [script] -t n' Terminal command or by passing in an argument to the run() and exec() Netscript commands. See documentation.
* RAM is slightly (~10%) more expensive (affects purchasing server and upgrading RAM on home computer)
* NeuroFlux Governor augmentation cost multiplier decreased
* Netscript default operation runtime lowered to 200ms (was 500ms previously)
v0.20.1
-------
* Fixed bug where sometimes scripts would crash without showing the error
* Added Deepscan programs to Dark Web
* Declining a faction invite will stop you from receiving invitations from that faction for the rest of the run
* (BETA) Added functionality to export/import saves. WARNING This is only lightly tested. You cannot choose where to save your file it just goes to the default save location. Also I have no idea what will happen if you try to import a file that is not a valid save. I will address these in later updates
v0.20.0
-------
* Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, now each one should only take ~500 milliseconds). 
* Percentage money stolen when hacking lowered to compensate for faster script speeds
* Hacking experience granted by grow() halved
* Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5 
* Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() and weaken() all cost slightly less RAM than before 
* Added getServerRequiredHackingLevel(server) Netscript command. 
* Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a specified server
* Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
* Added killall Terminal command. Kills all running scripts on the current machine
* Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
* Re-designed 'Active Scripts' tab
* Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
* Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
* NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that server's security level by 0.004. For reference, if a server has a security level of 10 it will have approximately the same growth rate as before. 
* Server growth no longer happens naturally
* Servers now have a maximum limit to their money. This limit is 50 times it's starting money
* Hacking now grants 10% less hacking experience
* You can now edit scripts that are running
* Augmentations cost ~11% more money and 25% more faction reputation
v0.19.7
-------
* Added changelog to Options menu
* Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs
v0.19.6
-------
* Script editor now saves its state even when you change tabs 
* scp() command in Terminal/script will now overwrite files at the destination 
* Terminal commands are no longer case-sensitive (only the commands themselves such as 'run' or 'nano'. Filenames are still case sensitive
* Tab automcompletion will now work on commands
v0.19.0
-------
* Hacknet Nodes have slightly higher base production, and slightly increased RAM multiplier. But they are also a bit more expensive at higher levels
* Calling grow() and weaken() in a script will now work offline, at slower rates than while online (The script now keeps track of the rate at which grow() and weaken() are called when the game is open. These calculated rates are used to determine how many times the calls would be made while the game is offline)
* Augmentations now cost 20% more reputation and 50% more money
* Changed the mechanic for getting invited to the hacking factions (CyberSec, NiteSec, The Black Hand, BitRunners) Now when you get to the required level to join these factions you will get a message giving you instructions on what to do in order to get invited.
* Added a bit of backstory/plot into the game. It's not fully fleshed out yet but it will be used in the future
* Made the effects of many Augmentations slightly more powerful
* Slightly increased company job wages across the board (~5-10% for each position)
* Gyms and classes are now significantly more expensive
* Doubled the amount by which a server's security increases when it is hacked. Now, it will increase by 0.002. Calling weaken() on a server will lower the security by 0.1.
v0.18.0
-------
* Major rebalancing (sorry didn't record specifics. But in general hacking gives more money and hacknet nodes give less)
* Server growth rate (both natural and manual using grow()) doubled
* Added option to Soft Reset
* Cancelling a full time job early now only results in halved gains for reputation. Exp and money earnings are gained in full
* Added exec() Netscript command, used to run scripts on other servers. 
* NEW HACKING MECHANICS: Whenever a server is hacked, its 'security level' is increased by a very small amount. The security level is denoted by a number between 1-100. A higher security level makes it harder to hack a server and also decreases the amount of money you steal from it. Two Netscript functions, weaken() and getServerSecurityLevel() level, were added. The weaken(server) function lowers a server's security level. See the Netscript documentation for more details
* When donating to factions, the base rate is now $1,000,000 for 1 reputation point. Before, it was $1,000 for 1 reputation point.
* Monetary costs for all Augmentations increased. They are now about ~3.3 - 3.75 times more expensive than before
v0.17.1
-------
* Fixed issue with purchasing Augmentations that are 'upgrades' and require previous Augmentations to be installed
* Increased the percentage of money stolen from servers when hacking
v0.17.0
-------
* Greatly increased amount of money gained for crimes (by about 400% for most crimes)
* Criminal factions require slightly less negative karma to get invited to
* Increased the percentage of money stolen from servers when hacking
* Increased the starting amount of money available on beginning servers (servers with <50 required hacking))
* Increased the growth rate of servers (both naturally and manually when using the grow() command in a script)
* Added getHostname() command in Netscript that returns the hostname of the server a script is running on
* jQuery preventDefault() called when pressing ctrl+b in script editor
* The Neuroflux Governor augmentation (the one that can be repeatedly leveled up) now increases ALL multipliers by 1%. To balance it out, it's price multiplier when it levels up was increased
* Hacknet Node base production decreased from $1.75/s to $1.65/s
* Fixed issue with nested for loops in Netscript (stupid Javascript references)
* Added 'scp' command to Terminal and Netscript
* Slightly nerfed Hacknet Node Kernel DNI and Hacknet Node Core DNI Augmentations
* Increased TOR Router cost to $200k
v0.16.0
-------
* New Script Editor interface 
* Rebalanced hacknet node - Increased base production but halved the multiplier from additional cores. This should boost its early-game production but nerf its late-game production
* Player now starts with 8GB of RAM on home computer
* 'scan-analyze' terminal command displays RAM on servers
* Slightly buffed the amount of money the player steals when hacking servers (by about ~8%)
* Time to execute grow() now depends on hacking skill and server security, rather than taking a flat 2 minutes.
* Clicking outside of a pop-up dialog box will now close it
* BruteSSH.exe takes 33% less time to create
* 'iron-gym' and 'max-hardware' servers now have 2GB of RAM
* Buffed job salaries across the board
* Updated Tutorial
* Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work 
v0.15.0
-------
* Slightly reduced production multiplier for Hacknet Node RAM
* Faction pages now scroll
* Slightly increased amount of money gained from hacking
* Added 'alias' command
* Added 'scan-analyze' terminal command - used to get basic hacking info about all immediate network connections
* Fixed bugs with upgradeHacknetNode() and purchaseHacknetNode() commands
* Added getNumHacknetNodes() and hasRootAccess(hostname/ip) commands to Netscript
* Increased Cost of university classes/gym
* You can now see what an Augmentation does and its price even while its locked

@ -22,6 +22,7 @@ secrets that you've been searching for.
Netscript <netscript>
Terminal <terminal>
Keyboard Shortcuts <shortcuts>
Changelog <changelog>
Indices and tables

@ -648,7 +648,7 @@ purchaseServer
.. js:function:: purchaseServer(hostname, ram)
:param string hostname: Hostname of the purchased server
:param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.)
:param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)
Purchased a server with the specified hostname and amount of RAM.

1078
doc/build/html/changelog.html vendored Normal file

File diff suppressed because it is too large Load Diff

@ -453,6 +453,7 @@
<li class="toctree-l1"><a class="reference internal" href="netscript.html"> Netscript</a></li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

@ -267,6 +267,67 @@ secrets that you've been searching for.</p>
<li class="toctree-l2"><a class="reference internal" href="shortcuts.html#misc-shortcuts">Misc Shortcuts</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a><ul>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-1">v0.37.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-0-5-20-2018">v0.37.0 - 5/20/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-36-1-5-11-2018">v0.36.1 - 5/11/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-36-0-5-2-2018">v0.36.0 - 5/2/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-35-2-3-26-2018">v0.35.2 - 3/26/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-35-1-3-12-2018">v0.35.1 - 3/12/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-35-0-3-3-2018">v0.35.0 - 3/3/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-5-2-24-2018">v0.34.5 - 2/24/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-4-2-14-2018">v0.34.4 - 2/14/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-3-1-31-2018">v0.34.3 - 1/31/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-2-1-27-2018">v0.34.2 - 1/27/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-1-1-19-2018">v0.34.1 - 1/19/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-34-0-12-6-2017">v0.34.0 - 12/6/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-33-0-12-1-2017">v0.33.0 - 12/1/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-32-1-11-2-2017">v0.32.1 - 11/2/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-32-0-10-25-2017">v0.32.0 - 10/25/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-31-0-10-15-2017">v0.31.0 - 10/15/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-30-0-10-9-2017">v0.30.0 - 10/9/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-29-3-10-3-2017">v0.29.3 - 10/3/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-29-2-10-1-2017">v0.29.2 - 10/1/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-29-1-9-27-2017">v0.29.1 - 9/27/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-29-0-9-19-2017">v0.29.0 - 9/19/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-6-9-15-2017">v0.28.6 - 9/15/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-5-9-13-2017">v0.28.5 - 9/13/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-4-9-11-2017">v0.28.4 - 9/11/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-3-9-7-2017">v0.28.3 - 9/7/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-2-9-4-2017">v0.28.2 - 9/4/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-1-9-1-2017">v0.28.1 - 9/1/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-28-0-8-30-2017">v0.28.0 - 8/30/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-27-3-8-19-2017">v0.27.3 - 8/19/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-27-2-8-18-2017">v0.27.2 - 8/18/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-27-1-8-15-2017">v0.27.1 - 8/15/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-27-0-8-13-2017">v0.27.0 - 8/13/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-26-4-8-1-2017">v0.26.4 - 8/1/2017</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-26-3">v0.26.3</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-26-2">v0.26.2</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-26-1">v0.26.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-26-0">v0.26.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-25-0">v0.25.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-24-1">v0.24.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-24-0">v0.24.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-23-1">v0.23.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-23-0">v0.23.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-22-1">v0.22.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-22-0-major-rebalancing-optimization-and-favor-system">v0.22.0 - Major rebalancing, optimization, and favor system</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-21-1">v0.21.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-21-0">v0.21.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-20-2">v0.20.2</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-20-1">v0.20.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-20-0">v0.20.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-19-7">v0.19.7</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-19-6">v0.19.6</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-19-0">v0.19.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-18-0">v0.18.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-17-1">v0.17.1</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-17-0">v0.17.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-16-0">v0.16.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-15-0">v0.15.0</a></li>
</ul>
</li>
</ul>
</div>
</div>
@ -292,6 +353,7 @@ secrets that you've been searching for.</p>
<li class="toctree-l1"><a class="reference internal" href="netscript.html"> Netscript</a></li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

@ -1089,7 +1089,7 @@ to purchase a new Hacknet Node then the function will return false.</p>
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Arguments:</th><td class="field-body"><ul class="first last simple">
<li><strong>hostname</strong> (<em>string</em>) -- Hostname of the purchased server</li>
<li><strong>ram</strong> (<em>number</em>) -- Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.)</li>
<li><strong>ram</strong> (<em>number</em>) -- Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)</li>
</ul>
</td>
</tr>
@ -1618,6 +1618,7 @@ you create in functions such as <a class="reference external" href="https://deve
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="netscript.html"> Netscript</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html"> NetscriptJS (Netscript 2.0)</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptoperators.html"> Operators</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptloopsandconditionals.html"> Loops and Conditionals</a></li>

Binary file not shown.

@ -88,6 +88,7 @@
<li class="toctree-l1"><a class="reference internal" href="netscript.html"> Netscript</a></li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">

File diff suppressed because one or more lines are too long

725
doc/source/changelog.rst Normal file

@ -0,0 +1,725 @@
.. _changelog:
Changelog
=========
v0.37.1
-------
* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based
on the difficulty of the contract.
* Completing Field Analysis in Bladeburner now grants 0.1 rank
* The maximum RAM you can get on a purchased server is now 1,048,576 GB (2^20)
* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS
* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS
* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to
* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.
* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms
v0.37.0 - 5/20/2018
-------------------
* NetscriptJS (Netscript 2.0) released (Documentation here: http://bitburner.readthedocs.io/en/latest/netscriptjs.html)
* Running the game with the '?noScripts' query will start the game without loading any of your scripts. This should be used if you accidentally write a script that crashes your game
v0.36.1 - 5/11/2018
-------------------
* Bladeburner Changes:
* Bug Fix: You can no longer get Bladeburner faction reputation through Infiltration
* Initial difficulty of Tracking contracts reduced
* Datamancer skill effect increased from 4% per level to 5%
* Slightly decreased the base stamina cost of contracts/operations
* Slightly increased the effects of the Tracer, Digital Observer, Short Circuit, Cloak, and Blade's Intuition skills
* Overclock skill capped at level 95, rather than 99
* Training gives significantly more exp/s
* Crime, Infiltration, and Hacking are now slightly more profitable in BN-6
* Gyms are now more expensive, but give slightly more exp
* Added getScriptName() and getHacknetMultipliers() Netscript functions (added by Github user hydroflame)
* getScriptRam() Netscript function now has default value for the second argument, which is hostname/ip (implemented by Github user hydroflame)
* There is now a soft-cap on stock price, which means it's no longer possible for the price of a stock to reach insanely-high values
* The ctrl+b hotkey in the text editor should now also be triggered by command+b on OSX (I don't have OSX so I can't confirm if this works)
* Many servers now have additional RAM
* Added an option to disable hotkeys/keyboard shortcuts
* Refactored 'Active Scripts' UI page to optimize its performance
* Added a new .fconf Terminal setting: ENABLE_TIMESTAMP
* 'Netscript Execution Time', which can be found in the Options, now has a minimum value of 15ms rather than 25ms
* Bug Fix: Fixed a typo in the Fulcrum Technologies company name (Technolgies -> Technologies)
* Bug Fix: hacknetnodes keyword should no longer incur RAM cost if its in a comment
* Bug Fix: disableLog() now works for the commitCrime() Netscript function (fixed by Github user hydroflame)
v0.36.0 - 5/2/2018
------------------
* Added BN-6: Bladeburners
* Rebalanced many combat Augmentations so that they are slightly less powerful
* Bug Fix: When faction invites are suppressed, an invitation will no longer load the Faction page
v0.35.2 - 3/26/2018
-------------------
* Corporation Changes:
* Fixed an issue with Warehouse upgrade cost. Should now be significantly cheaper than before.
* Scientific Research now has a slightly more significant effect on Product quality
* The Energy and Water Utilities industries are now slightly more profitable
* The Robotics and Computer Hardware industries are now less profitable
* The Software industry is slightly less profitable
* When selling Materials and Products, the 'PROD' qualifier can now be used to set dynamic sell amounts based on your production
* Exporting MAX should now work properly
* You can no longer export past storage limits
* Scientific Research production reduced
* Effects of AdVert. Inc upgrade were reduced, but the effect that popularity and awareness have on sales was increased to compensate (popularity/awareness numbers were getting too big with Advert. Inc)
* Bug Fix: Products from Computer Hardware division should now properly have ratings
* Improved Augmentation UI/UX. Now contains collapsible headers and sort buttons
* Improved Faction Augmentations display UI/UX. Now contains sort buttons. There is also an option to disable confirmation when purchasing Augmentations
v0.35.1 - 3/12/2018
-------------------
* You can now easily download all of your scripts/text files as zip folders. Use the 'help download' Terminal command for details
* Scripts are now downloaded with the .script.js extension at the end of their filename
* Corporation Management Changes:
* Implemented Smart Supply unlock
* Changed the way a division's Production Multiplier is calculated. It is now the sum of the individual Production Multiplier for every city. Therefore, it is now beneficial to open offices in different cities
* Several small UI/UX improvements
* Numerous balance changes. The significant ones are listed below.
* Product descriptions will now display their estimated market price
* The sale price of Products can no longer be marked up as high as before
* Scientific Research now affects the rating of Products
* In general, the maximum amount of product you are able to sell is reduced
* Sale bonus from advertising (popularity/awareness) now has diminishing returns rather than scaling linearly
* Experience gained during Infiltration now scales linearly based on the clearance level you reach. Compared to before, the experience gained will be much less at lower clearance levels, but much more at higher clearance levels
* The editor can now be used to edit both scripts and text files
* New Terminal config file that can be edited using the command 'nano .fconf'. Right now there is only one option, but there will be more in the future.
* You can now enable Bash-style Terminal hotkeys using the .fconf file referenced above
* Bug Fix: Fixed an issue with the UI elements of Gang Management persisting across different instances of BitNode-2
v0.35.0 - 3/3/2018
------------------
* Minor rebalancing of BitNodes due to the fact that Corporations provide a (relatively) new method of progressing
* Corporation Management Changes:
* Once your Corporation gets big/powerful enough, you can now bribe Factions for reputation using company funds an/or stock shares
* You can now only create one Division for every Industry type
* Added several new UI/UX elements
* Wilson Analytics multiplier was significantly reduced to 1% per level (additive).
* Reduced the effect of Advert Inc upgrade. Advert Inc. upgrade price increases faster
* Materials can now be marked up at higher prices
* Added Javascript's built-in Number object to Netscript
* Added getCharacterInformation(), getCompanyFavor(), and getFactionFavor() Netscript Singularity functions
* Rebalanced Singularity Function RAM Costs. They now cost x8 as much when outside of BN-4 (rather than x10). Also, many of the functions now use significantly less RAM
* Refactored Netscript Ports. You can now get a handle for a Netscript port using the getPortHandle() Netscript function. This allows you to access a port's underlying queue (which is just an array) and also makes several new functions available such as tryWrite(), full(), and empty().
* Number of Netscript Ports increased from 10 to 20
* Netscript assignments should now return proper values. i.e. i = 5 should return 5.
* Added throw statements to Netscript. It's not super useful since 'catch' isn't implemented, but it can be used to generate custom runtime error messages.
* Added import declaration to Netscript. With this, you are able to import functions (and only functions) from other files. Using export declarations is not necessary
* Most Netscript Runtime errors (the ones that cause your script to crash) should now include the line number where the error occured
* When working for a company, your current company reputation is now displayed
* Whenever you get a Faction Invite it will be immediately appended to your 'invited factions' list. Therefore the checkFactionInvitations() Singularity Function should now be properly useable since you no longer need to decline a Faction Invitation before it shows up in the result.
* Bug Fix: When purchasing servers, whitespace should now automatically be removed from the hostname
* Bug Fix: Can no longer have whitespace in the filename of text files created using write()
* Bug Fix: In Netscript, you can no longer assign a Hacknet Node handle (hacknetnodes[i]) to another value
* Bug Fix: If you are in the Factions tab when you accept an invitation from a Faction, the page will now properly 'refresh'
* Bug Fix: Scripts that run recursive functions should now be killed properly
v0.34.5 - 2/24/2018
-------------------
* Corporation Management Changes:
* Market Research unlocks are now cheaper
* New 'VeChain' upgrade: displays useful statistics about Corporation
* Corporation cycles are processed 25% faster
* Corporation valuation was lowered by ~10% (this affects stock price and investments)
* Rebalanced the effects of advertising. Should now be more effective for every Industry
* Fixed several bugs/exploits involving selling and buying back stock shares
* You will now receive a Corporation Handbook (.lit file) when starting out BitNode-3. It contains a brief guide to help you get started. This same handbook can be viewed from the Corporation management screen
* Slightly decreased the amount by which a Product's sell price can be marked up
* Employees can now be assigned to a 'Training' task, during which they will slowly increase several of their stats
* Hopefully fixed an exploit with Array.forEach(). If there are any issues with using forEach, let me know
* Arguments passed into a script are now passed by value. This means modifying the 'args' array in a script should no longer cause issues
* Scripts executed programatically (via run(), exec(), etc.) will now fail if null/undefined is passed in as an argument
* Added peek() Netscript function
* killall() Netscript function now returns true if any scripts were killed, and false otherwise.
* hack() Netscript function now returns the amount of money gained for successful hacks, and 0 for failed hacks
* scp Terminal command and Netscript function now work for txt files
* Changes courtesy of Wraithan:
* Text files are now displayed using 'pre' rather than 'p' elements when using the 'cat' Terminal command. This means tabs are retained and lines don't automatically wrap
* ls() Netscript function now returns text files as well
* Removed round() Netscript function, since you can just use Math.round() instead
* Added disableLog() and enableLog() Netscript functions
* Removed the 'log' argument from sleep(), since you can now use the new disableLog function
* 'Netscript Documentation' button on script editor now points to new readthedocs documentation rather than wiki
* When working for a faction, your current faction reputation is now displayed
* Bug Fix: Hacking Missions should no longer break when dragging an existing connection to another Node
* Bug Fix: Fixed RAM usage of getNextHacknetNodeCost() (is not 1.5GB instead of 4GB)
v0.34.4 - 2/14/2018
-------------------
* Added several new features to Gang UI to make it easier to manage your Gang.
* Changed the Gang Member upgrade mechanic. Now, rather than only being able to have one weapon/armor/vehicle/etc., you can purchase all the upgrades for each Gang member and their multipliers will stack. To balance this out, the effects (AKA multipliers) of each Gang member upgrade were reduced.
* Added a new script editor option: Max Error Count. This affects how many approximate lines the script editor will process (JSHint) for common errors. Increasing this option can affect negatively affect performance
* Game theme colors (set using 'theme' Terminal command) are now saved when re-opening the game
* 'download' Terminal command now works on scripts
* Added stopAction() Singularity function and the spawn() Netscript function
* The 'Purchase Augmentations' UI screen will now tell you if you need a certain prerequisite for Augmentations.
* Augmentations with prerequisites can now be purchased as long as their prerequisites are puchased (before, you had to actually install the prerequisites before being able to purchase)
v0.34.3 - 1/31/2018
-------------------
* Minor balance changes to Corporations:
* Upgrades are generally cheaper and/or have more powerful effects.
* You will receive more funding while your are a private company.
* Product demand decreases at a slower rate.
* Production multiplier for Industries (receives for owning real estate/hardware/robots/etc.) is slightly higher
* Accessing the hacknetnodes array in Netscript now costs 4.0GB of RAM (only counts against RAM usage once)
* Bug Fix: Corporation oustanding shares should now be numeric rather than a string
* Bug Fix: Corporation production now properly calculated for industries that dont produce materials.
* Bug Fix: Gangs should now properly reset when switching BitNodes
* Bug Fix: Corporation UI should now properly reset when you go public
v0.34.2 - 1/27/2018
-------------------
* Corporation Management Changes:
* Added advertising mechanics
* Added Industry-specific purchases
* Re-designed employee management UI
* Rebalancing: Made many upgrades/purchases cheaper. Receive more money from investors in early stage. Company valuation is higher after going public
* Multiple bug fixes
* Added rm() Netscript function
* Updated the way script RAM usage is calculated. Now, a function only increases RAM usage the first time it is called. i.e. even if you call hack() multiple times in a script, it only counts against RAM usage once. The same change applies for while/for loops and if conditionals.
* The RAM cost of the following were increased:
* If statements: increased by 0.05GB
* run() and exec(): increased by 0.2GB
* scp(): increased by 0.1GB
* purchaseServer(): increased by 0.25GB
* Note: You may need to re-save all of your scripts in order to re-calculate their RAM usages. Otherwise, it should automatically be re-calculated when you reset/prestige
* The cost to upgrade your home computer's RAM has been increased (both the base cost and the exponential upgrade multiplier)
* The cost of purchasing a server was increased by 10% (it is now $55k per RAM)
* Bug fix: (Hopefully) removed an exploit where you could avoid RAM usage for Netscript function calls by assigning functions to a variable (foo = hack(); foo('helios');)
* Bug fix: (Hopefully) removed an exploit where you could run arbitrary Javascript code using the constructor() method
* Thanks to Github user mateon1 and Reddit users havoc_mayhem and spaceglace for notifying me of the above exploits
* The fileExists() Netscript function now works on text files (.txt). Thanks to Github user devoidfury for this
v0.34.1 - 1/19/2018
-------------------
* Updates to Corporation Management:
* Added a number of upgrades to various aspects of your Corporation
* Rebalanced the properties of Materials and the formula for determining the valuation of the Corporation
* Fixed a number of bugs
* 'Stats' page now shows information about current BitNode
* You should now be able to create Corporations in other BitNodes if you have Source-File 3
* Added a new create-able program called b1t_flum3.exe. This program can be used to reset and switch BitNodes
* Added an option to adjust autosave interval
* Line feeds, newlines, and tabs will now work with the tprint() Netscript function
* Bug fix: 'check' Terminal command was broken
* Bug fix: 'theme' Terminal command was broken when manually specifying hex codes
* Bug fix: Incorrect promotion requirement for 'Business'-type jobs
* Bug fix: Settings input bars were incorrectly formatted when loading game
v0.34.0 - 12/6/2017
-------------------
* Added clear() and exit() Netscript functions
* When starting out or prestiging, you will now receive a 'Hacking Starter Guide'. It provides tips/pointers for new players
* Doubled the amount of RAM on low-level servers (up to required hacking level 150)
* Slightly increased experience gain from Infiltration
* buyStock(), sellStock(), shortStock(), and sellShort() Netscript function now return the stock price at which the transaction occurred, rather than a boolean. If the function fails for some reason, 0 will be returned.
* Hacking Mission Changes:
* You can now select multiple Nodes of the same type by double clicking. This allows you to set the action of all of selected nodes at once (e.g. set all Transfer Nodes to Fortify). Creating connections does not work with this multi-select functionality yet
* Shield and Firewall Nodes can now fortify
* The effects of Fortifying are now ~5% lower
* Conquering a Spam Node now increases your time limit by 25 seconds instead of 15
* Damage dealt by Attacking was slightly reduced
* The effect of Scanning was slightly reduced
* Enemy CPU Core Nodes start with slightly more attack. Misc Nodes start with slightly less defense
* Corporation Management changes:
* Added several upgrades that unlock new features
* Implemented Exporting mechanic
* Fixed many bugs
v0.33.0 - 12/1/2017
-------------------
* Added BitNode-3: Corporatocracy. In this BitNode you can start and manage your own corporation. This feature is incomplete. Much more will be added to it in the near future
* Minor bug fixes
v0.32.1 - 11/2/2017
-------------------
* Updated Netscript's 'interpreter/engine' to use the Bluebird promise library instead of native promises. It should now be faster and more memory-efficient. If this has broken any Netscript features please report it through Github or the subreddit (reddit.com/r/bitburner)
* Rebalanced stock market (adjusted parameters such as the volatility/trends/starting price of certain stocks)
* Added prompt() Netscript function
* Added 'Buy Max' and 'Sell All' functions to Stock Market UI
* Added 'Portfolio' Mode to Stock Market UI so you can only view stocks you have a position/order in
* Added a button to kill a script from its log display box
v0.32.0 - 10/25/2017
--------------------
* Added BitNode-8: Ghost of Wall Street
* Re-designed Stock Market UI
* Minor bug fixes
v0.31.0 - 10/15/2017
--------------------
* Game now saves to IndexedDb (if your browser supports it). This means you should no longer have trouble saving the game when your save file gets too big (from running too many scripts). The game will still be saved to localStorage as well
* New file type: text files (.txt). You can read or write to text files using the read()/write() Netscript commands. You can view text files in Terminal using 'cat'. Eventually I will make it so you can edit them in the editor but that's not available yet. You can also download files to your real computer using the 'download' Terminal command
* Added a new Crime: Bond Forgery. This crime takes 5 minutes to attempt and gives $4,500,000 if successful. It is meant for mid game.
* Added commitCrime(), getCrimeChance(), isBusy(), and getStats() Singularity Functions.
* Removed getIntelligence() Netscript function
* Added sprintf and vsprintf to Netscript. See [https://github.com/alexei/sprintf.js this Github page for details]
* Increased the amount of money gained from Infiltration by 20%, and the amount of faction reputation by 12%
* Rebalanced BitNode-2 so that Crime and Infiltration are more profitable but hacking is less profitable. Infiltration also gives more faction rep
* Rebalanced BitNode-4 so that hacking is slightly less profitable
* Rebalanced BitNode-5 so that Infiltration is more profitable and gives more faction rep
* Rebalanced BitNode-11 so that Crime and Infiltration are more profitable. Infiltration also gives more faction rep.
* Fixed an annoying issue in Hacking Missions where sometimes you would click a Node but it wouldnt actually get selected
* Made the Hacking Mission gameplay a bit slower by lowering the effect of Scan and reducing Attack damage
* Slightly increased the base reputation gain rate for factions when doing Field Work and Security Work
v0.30.0 - 10/9/2017
-------------------
* Added getAugmentations() and getAugmentationsFromFaction() Netscript Singularity Functions
* Increased the rate of Intelligence exp gain
* Added a new upgrade for home computers: CPU Cores. Each CPU core on the home computer grants an additional starting Core Node in Hacking Missions. I may add in other benefits later. Like RAM upgrades, upgrading the CPU Core on your home computer persists until you enter a new BitNode.
* Added lscpu Terminal command to check number of CPU Cores
* Changed the effect of Source-File 11 and made BitNode-11 a little bit harder
* Fixed a bug with Netscript functions (the ones you create yourself)
* Hacking Missions officially released (they give reputation now). Notable changes in the last few updates:
* Misc Nodes slowly gain hp/defense over time
* Conquering a Misc Node will increase the defense of all remaining Misc Nodes that are not being targeted by a certain percentage
* Reputation reward for winning a Mission is now affected by faction favor and Player's faction rep multiplier
* Whenever a Node is conquered, its stats are reduced
v0.29.3 - 10/3/2017
-------------------
* Fixed bug for killing scripts and showing error messages when there are errors in a player-defined function
* Added function name autocompletion in Script Editor. Press Ctrl+space on a prefix to show autocompletion options.
* Minor rebalancing and bug fixes for Infiltration and Hacking Missions
v0.29.2 - 10/1/2017
-------------------
* installAugmentations() Singularity Function now takes a callback script as an argument. This is a script that gets ran automatically after Augmentations are installed. The script is run with no arguments and only a single thread, and must be found on your home computer.
* Added the ability to create your own functions in Netscript. See [[Netscript Functions|this link]] for details
* Added :q, :x, and :wq Vim Ex Commands when using the Vim script editor keybindings. :w, :x, and :wq will all save the script and return to Terminal. :q will quit (return to Terminal) WITHOUT saving. If anyone thinks theres an issue with this please let me know, I don't use Vim
* Added a new Augmentation: ADR-V2 Pheromone Gene
* In Hacking Missions, enemy nodes will now automatically target Nodes and perform actions.
* Re-balanced Hacking Missions through minor tweaking of many numbers
* The faction reputation reward for Hacking Missions was slightly increased
v0.29.1 - 9/27/2017
-------------------
* New gameplay feature that is currently in BETA: Hacking Missions. Hacking Missions is an active gameplay mechanic (its a minigame) that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation for the time being, since the feature likely has many bugs, balance problems, and other issues. If you have any feedback regarding the new feature, feel free to let me know
* CHANGED THE RETURN VALUE OF getScriptIncome() WHEN RAN WITH NO ARGUMENTS. It will now return an array of two values rather than a single value. This may break your scripts, so make sure to update them!
* Added continue statement for for/while loops
* Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions
* Netscript scp() function can now take an array as the first argument, and will try to copy every file specified in the array (it will just call scp() normally for every element in the array). If an array is passed in, then the scp() function returns true if at least one element from the array is successfully copied
* Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's static methods will work (now(), UTC(), parse(), etc.).
* Failing a crime now gives half the experience it did before
* The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup)
* fileExists() function now works on literature files
v0.29.0 - 9/19/2017
-------------------
* Added BitNode-5: Artificial Intelligence
* Added getIp(), getIntelligence(), getHackingMultipliers(), and getBitNodeMultipliers() Netscript functions (requires Source-File 5)
* Updated scan() Netscript function so that you can choose to have it print IPs rather than hostnames
* Refactored scp() Netscript function so that it takes an optional 'source server' argument
* For Infiltration, decreased the percentage by which the security level increases by about 10% for every location
* Using :w in the script editor's Vim keybinding mode should now save and quit to Terminal
* Some minor optimizations that should reduce the size of the save file
* scan-analyze Terminal command will no longer show your purchased servers, unless you pass a '-a' flag into the command
* After installing the Red Pill augmentation from Daedalus, the message telling you to find 'The-Cave' will now repeatedly pop up regardless of whether or not you have messages suppressed
* Various bugfixes
v0.28.6 - 9/15/2017
-------------------
* Time required to create programs now scales better with hacking level, and should generally be much faster
* Added serverExists(hostname/ip) and getScriptExpGain(scriptname, ip, args...) Netscript functions
* Short circuiting && and || logical operators should now work
* Assigning to multidimensional arrays should now work
* Scripts will no longer wait for hack/grow/weaken functions to finish if they are killed. They will die immediately
* The script loop that checks whether any scripts need to be started/stopped now runs every 6 seconds rather than 10 (resulting in less delays when stopping/starting scripts)
* Fixed several bugs/exploits
* Added some description for BitNode-5 (not implemented yet, should be soon though)
v0.28.5 - 9/13/2017
-------------------
* The fl1ght.exe program that is received from jump3r is now sent very early on in the game, rather than at hacking level 1000
* Hostname is now displayed in Terminal
* Syntax highlighting now works for all Netscript functions
* Export should now work on Edge/IE
v0.28.4 - 9/11/2017
-------------------
* Added getScriptIncome() Netscript function
* Added Javascript's math module to Netscript. See [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math this link for details]
* Added several member variables for the Hacknet Node API that allow you to access info about their income
* All valid Netscript functions are now syntax highlighted as keywords in the editor. This means they will a different color than invalid netscript functions. The color will depend on your theme. Note that right now, this only applies for normal Netscript functions, not functions in the TIX API, Hacknet Node API, or Singularity Functions.
* Comments and operators no longer count towards RAM usage in scripts.
* Variety of bug fixes and updates to informational text in the game
v0.28.3 - 9/7/2017
------------------
* Added ls() Netscript function
* Increased company wages by about ~10% across the board
* The scp() Netsction function and Terminal command now works for .lit files
* Increased the amount of RAM on many lower level servers (up to level 200 hacking level required).
v0.28.2 - 9/4/2017
------------------
* Added several configuration options for script editor (key bindings, themes, etc.)
* Certain menu options will now be hidden until their relevant gameplay is unlocked. This includes the Factions, Augmentations, Create Program, Travel, and Job tabs. This will only affect newer players.
* Most unrecognize or un-implemented syntax errors in Netscript will now include the line number in the error message
v0.28.1 - 9/1/2017
------------------
* The script editor now uses the open-source Ace editor, which provides a much better experience when coding!
* Added tprint() Netscript function
v0.28.0 - 8/30/2017
-------------------
* Added BitNode-4: The Singularity
* Added BitNode-11: The Big Crash
* Migrated the codebase to use webpack (doesn't affect any in game content, except maybe some slight performance improvements and there may be bugs that result from dependency errors
v0.27.3 - 8/19/2017
-------------------
* You can now purchase upgrades for Gang Members (BitNode 2 only)
* Decreased Gang respect gains and slightly increased wanted gains (BitNode 2 only)
* Other gangs will increase in power faster (BitNode 2 only)
* Added getHackTime(), getGrowTime(), and getWeakenTime() Netscript functions
v0.27.2 - 8/18/2017
-------------------
* Added getServerGrowth() Netscript function
* Added getNextHacknetNodeCost() Netscript function
* Added new 'literature' files (.lit extension) that are used to build lore for the game. These .lit files can be found in certain servers throughout the game. They can be viewed with the 'cat' Terminal command and copied over to other servers using the 'scp' command. These .lit files won't be found until you reset by installing Augmentations
* Fixed some bugs with Gang Territory(BitNode 2 only)
v0.27.1 - 8/15/2017
-------------------
* Changed the way Gang power was calculated to make it scale better late game (BitNode 2 only)
* Lowered the respect gain rate in Gangs (Bitnode 2 only)
* Added '| grep pattern' option for ls Terminal command. This allows you to only list files that contain a certain pattern
* Added break statement in Netscript
* Display for some numerical values is now done in shorthand (e.g 1.000m instead of 1,000,000)
v0.27.0 - 8/13/2017
-------------------
* Added secondary 'prestige' system - featuring Source Files and BitNodes
* MILD SPOILERS HERE: Installing 'The Red Pill' Augmentation from Daedalus will unlock a special server called w0r1d_d43m0n. Finding and manually hacking this server through Terminal will destroy the Player's current BitNode, and allow the player to enter a new one. When destroying a BitNode, the player loses everything except the scripts on his/her home computer. The player will then gain a powerful second-tier persistent upgrade called a Source File. The player can then enter a new BitNode to start the game over. Each BitNode has different characteristics, and many will have new content/mechanics as well. Right now there are only 2 BitNodes. Each BitNode grants its own unique Source File. Restarting and destroying a BitNode you already have a Source File for will upgrade your Source File up to a maximum level of 3.
* Reputation gain with factions and companies is no longer a linear conversion, but an exponential one. It will be much easier to gain faction favor at first, but much harder later on.
* Significantly increased Infiltration exp gains
* Fixed a bug with company job requirement tooltips
* Added scriptRunning(), scriptKill(), and getScriptRam() Netscript functions. See documentation for details
* Fixed a bug with deleteServer() Netscript function
v0.26.4 - 8/1/2017
------------------
* All of the 'low-level servers' in early game that have a required hacking level now have 8GB of RAM instead of 4GB
* Increased the amount of experience given at university
* Slightly increased the production of Hacknet Nodes and made them cheaper to upgrade
* Infiltration now gives slightly more EXP and faction reputation
* Added two new crimes. These crimes are viable to attempt early on in the game and are relatively passive (each take 60+ seconds to complete)
* Crimes give more exp and more money
* Max money available on a server decreased from 50x the server's starting money to 25x
* Significantly increased wages for all jobs
v0.26.3
-------
* Added support for large numbers using Decimal.js. Right now it only applies for the player's money
* Purchasing servers with the Netscript function purchaseServer() is no longer 2x as expensive as doing manually it now costs the same
* Early game servers have more starting money
v0.26.2
-------
* Major rebalancing and randomization of the amount of money that servers start with
* Significantly lowered hacking exp gain from hacking servers. The exp gain for higher-level servers was lowered more than that of low level servers. (~16% for lower level servers, up to ~25% for higher-level servers)
* Added deleteServer() Netscript function
* You can now purchase a maximum of 25 servers each run (Deleting a server will allow you to purchase a new one)
* Added autocompletion for './' Terminal command
* Darkweb prices now displayed properly using toLocaleString()
* Added NOT operator (!) and negation operator(-) in Netscript, so negative numbers should be functional now
* Rejected faction invitations will now show up as 'Outstanding Faction Invites' in the Factions page. These can be accepted at any point in the future
* Added a few more configurable game settings for suppressing messages and faction invitations
* Added tooltips for company job requirements
v0.26.1
-------
* Added autocompletion for aliases
* Added getServerRam() Netscript function()
* Added getLevelUpgradeCost(n), getRamUpgradeCost(), getCoreUpgradeCost() functions for Netscript Hacknet Node API
* Added some configurable settings (See Game Options menu)
v0.26.0
-------
* Game now has a real ending, although it's not very interesting/satisfying right now. It sets up the framework for the secondary prestige system in the future
* Forgot to mention that since last update, comments now work in Netscript. Use // for single line comments or /* and */ for multiline comments just like in Javascript
* Added ports to Netscript. These ports are essentially serialized queues. You can use the write() Netscript function to write a value to a queue, and then you can use the read() Netscript function to read the value from the queue. Once you read a value from the queue it will be removed. There are only 10 queues (1-10), and each has a maximum capacity of 50 entries. If you try to write to a queue that is full, the the first value is removed. See wiki/Netscript documentation for more details
* You can now use the 'help' Terminal command for specific commands
* You can now use './' to run a script/program (./NUKE.exe). However, tab completion currently doesn't work for it (I'm working on it)
* Decreased the base growth rate of servers by ~25%
* Both the effect of weaken() and its time to execute were halved. In other words, calling weaken() on a server only lowers its security by 0.05 (was 0.1 before) but the time to execute the function is half of what it was before. Therefore, the effective rate of weaken() should be about the same
* Increased all Infiltration rewards by ~10%, and increased infiltration rep gains by an additional 20% (~32% total for rep gains)
* The rate at which the security level of a facility increases during Infiltration was decreased significantly (~33%)
* Getting treated at the Hospital is now 33% more expensive
* Slightly increased the amount of time it takes to hack a server
* Slightly decreased the amount of money gained when hacking a server (~6%)
* Slightly decreased the base cost for RAM on home computer, but increased the cost multiplier. This means that upgrading RAM on the home computer should be slightly cheaper at the start, but slightly more expensive later on
* Increased the required hacking level for many late game servers
* The sleep() Netscript function now takes an optional 'log' argument that specifies whether or not the 'Sleeping for N milliseconds' will be logged for the script
* Added clearLog() Netscript function
* Deleted a few stocks. Didn't see a reason for having so many, and it just affects performance. Won't take effect until you reset by installing Augmentations
* There was a typo with Zeus Medical's server hostname. It is now 'zeus-med' rather than 'zeud-med'
* Added keyboard shortcuts to quickly navigate between different menus. See wiki link (http://bitburner.wikia.com/wiki/Shortcuts)
* Changed the Navigation Menu UI
v0.25.0
-------
* Refactored Netscript to use the open-source Acorns Parser. This re-implementation was done by [https://github.com/MrNuggelz Github user MrNuggelz]. This has resulted in several changes in the Netscript language. Some scripts might break because of these changes. Changes listed below: 
* Arrays are now fully functional Javascript arrays. You no longer need to use the 'Array' keyword to declare them. 
* The length(), clear/clear(), insert(), and remove() functions no longer work for arrays. 
* All Javascript array methods are available (splice(), push(), pop(), join(), shift(), indexOf(), etc. See documentation)
* Variables assigned to arrays are now passed by value rather than reference
* Incrementing/Decrementing are now available (i++, ++i)
* You no longer need semicolons at the end of block statements
* Elif is no longer valid. Use 'else if' instead
* Netscript's Hacknet Node API functions no longer log anything
* Stock prices now update every ~6 seconds when the game is active (was 10 seconds before)
* Added a new mechanic that affects how stock prices change
* Script editor now has dynamic indicators for RAM Usage and Line number
* Augmentation Rebalancing - Many late game augmentations are now slightly more expensive. Several early game augmentations had their effects slightly decreased
* Increased the amount of rewards (both money and rep) you get from infiltration
* Purchasing servers is now slightly more expensive
* Calling the Netscript function getServerMoneyAvailable('home') now return's the player's money
* Added round(n) Netscript function - Rounds a number
* Added purchaseServer(hostname, ram) Netscript function
* Added the TIX API. This must be purchased in the WSE. It persists through resets. Access to the TIX API allows you to write scripts that perform automated algorithmic trading. See Netscript documentation
* Minor rebalancing in a lot of different areas
* Changed the format of IP Addresses so that they are smaller (will consist mostly of single digit numbers now). This will reduce the size of the game's save file.
v0.24.1
-------
* Adjusted cost of upgrading home computer RAM. Should be a little cheaper for the first few upgrades (up to ~64GB), and then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.
* Slightly lowered the starting money available on most mid-game and end-game servers (servers with required hacking level greater than 200) by about 10-15%
* Rebalanced company/company position reputation gains and requirements
* Studying at a university now gives slightly more EXP and early jobs give slightly less EXP
* Studying at a university is now considerably more expensive
* Rebalanced stock market
* Significantly increased cost multiplier for purchasing additional Hacknet Nodes
* The rate at which facility security level increases during infiltration for each clearance level was lowered slightly for all companies
* Updated Faction descriptions
* Changed the way alias works. Normal aliases now only work at the start of a Terminal command (they will only replace the first word in the Terminal command). You can also create global aliases that work on any part of the command, like before. Declare global aliases by entering the optional -g flag: alias -g name="value" - [https://github.com/MrNuggelz Courtesy of Github user MrNuggelz]
* 'top' Terminal command implemented courtesy of [https://github.com/LTCNugget Github user LTCNugget]. Currently, the formatting gets screwed up if your script names are really long.
v0.24.0
-------
* Players now have HP, which is displayed in the top right. To regain HP, visit the hospital. Currently the only way to lose HP is through infiltration
* Infiltration - Attempt to infiltrate a company and steal their classified secrets. See 'Companies' documentation for more details
* Stock Market - Added the World Stock Exchange (WSE), a brokerage that lets you buy/sell stocks. To begin trading you must first purchase an account. A WSE account will persist even after resetting by installing Augmentations. How the stock market works should hopefully be self explanatory. There is no documentation about it currently, I will add some later. NOTE: Stock prices only change when the game is open. The Stock Market is reset when installing Augmentations, which means you will lose all your stocks
* Decreased money gained from hacking by ~12%
* Increased reputation required for all Augmentations by ~40%
* Cost increase when purchasing multiple augmentations increased from 75% to 90%
* Added basic variable runtime to Netscript operations. Basic commands run in 100ms. Any function incurs another 100ms in runtime (200ms total). Any function that starts with getServer incurs another 100ms runtime (300ms total). exec() and scp() require 400ms total. 
* Slightly reduced the amount of experience gained from hacking
v0.23.1
-------
* scan() Netscript function now takes a single argument representing the server from which to scan. 
v0.23.0
-------
* You can now purchase multiple Augmentations in a run. When you purchase an Augmentation you will lose money equal to the price and then the cost of purchasing another Augmentation during this run will be increased by 75%. You do not gain the benefits of your purchased Augmentations until you install them. This installation can be done through the 'Augmentation' tab. When you install your Augmentations, your game will reset like before. 
* Reputation needed to gain a favor from faction decreased from 7500 to 6500
* Reputation needed to gain a favor from company increased from 5000 to 6000
* Reputation cost of all Augmentations increased by 16%
* Higher positions at companies now grant slightly more reputation for working
* Added getServerMaxMoney() Netscript function
* Added scan() Netscript function
* Added getServerNumPortsRequired() Netscript function
* There is now no additional RAM cost incurred when multithreading a script
v0.22.1
-------
* You no longer lose progress on creating programs when cancelling your work. Your progress will be saved and you will pick up where you left off when you start working on it again
* Added two new programs: AutoLink.exe and ServerProfiler.exe
* Fixed bug with Faction Field work reputation gain
v0.22.0 - Major rebalancing, optimization, and favor system
-----------------------------------------------------------
* Significantly nerfed most augmentations
* Almost every server with a required hacking level of 200 or more now has slightly randomized server parameters. This means that after every Augmentation purchase, the required hacking level, base security level, and growth factor of these servers will all be slightly different
* The hacking speed multiplier now increases rather than decreases. The hacking time is now divided by your hacking speed multiplier rather than multiplied. In other words, a higher hacking speed multiplier is better
* Servers now have a minimum server security, which is approximately one third of their starting ('base') server security
* If you do not steal any money from a server, then you gain hacking experience equal to the amount you would have gained had you failed the hack
* The effects of grow() were increased by 50%
* grow() and weaken() now give hacking experience based on the server's base security level, rather than a flat exp amount
* Slightly reduced amount of exp gained from hack(), weaken(), and grow()
* Rebalanced formulas that determine crime success
* Reduced RAM cost for multithreading a script. The RAM multiplier for each thread was reduced from 1.02 to 1.005
* Optimized Script objects so they take less space in the save file
* Added getServerBaseSecurityLevel() Netscript function
* New favor system for companies and factions. Earning reputation at a company/faction will give you favor for that entity when you reset after installing an Augmentation. This favor persists through the rest of the game. The more favor you have, the faster you will earn reputation with that faction/company
* You can no longer donate to a faction for reputation until you have 150 favor with that faction
* Added unalias Terminal command
* Changed requirements for endgame Factions
v0.21.1
-------
* IF YOUR GAME BREAKS, DO THE FOLLOWING: Options -> Soft Reset -> Save Game -> Reload Page. Sorry about that! 
* Autocompletion for aliases - courtesy of [https://github.com/LTCNugget Github user LTCNugget]
v0.21.0
-------
* Added dynamic arrays. See Netscript documentation
* Added ability to pass arguments into scripts. See documentation
* The implementation/function signature of functions that deal with scripts have changed. Therefore, some old scripts might not work anymore. Some of these functions include run(), exec(), isRunning(), kill(), and some others I may have forgot about. Please check the updated Netscript documentation if you run into issues.-Note that scripts are now uniquely identified by the script name and their arguments. For example, you can run a script using::
run foodnstuff.script 1
and you can also run the same script with a different argument::
run foodnstuff.script 2
These will be considered two different scripts. To kill the first script you must run::
kill foodnstuff.script 1
and to kill the second you must run::
kill foodnstuff.script 2
Similar concepts apply for Terminal Commands such as tail, and Netscript commands such as run(), exec(), kill(), isRunning(), etc.
* Added basic theme functionality using the 'theme' Terminal command - All credit goes to /u/0x726564646974 who implemented the awesome feature
* Optimized Script objects, which were causing save errors when the player had too many scripts
* Formula for determining exp gained from hacking was changed
* Fixed bug where you could purchase Darkweb items without TOR router
* Slightly increased cost multiplier for Home Computer RAM
* Fixed bug where you could hack too much money from a server (and bring its money available below zero)
* Changed tail command so that it brings up a display box with dynamic log contents. To get old functionality where the logs are printed to the Terminal, use the new 'check' command
* As a result of the change above, you can no longer call tail/check on scripts that are not running
* Added autocompletion for buying Programs in Darkweb
v0.20.2
-------
* Fixed several small bugs
* Added basic array functionality to Netscript
* Added ability to run scripts with multiple threads. Running a script with n threads will multiply the effects of all hack(), grow(), and weaken() commands by n. However, running a script with multiple threads has drawbacks in terms of RAM usage. A script's ram usage when it is 'multithreaded' is calculated as: base cost * numThreads * (1.02 ^ numThreads). A script can be run multithreaded using the 'run [script] -t n' Terminal command or by passing in an argument to the run() and exec() Netscript commands. See documentation.
* RAM is slightly (~10%) more expensive (affects purchasing server and upgrading RAM on home computer)
* NeuroFlux Governor augmentation cost multiplier decreased
* Netscript default operation runtime lowered to 200ms (was 500ms previously)
v0.20.1
-------
* Fixed bug where sometimes scripts would crash without showing the error
* Added Deepscan programs to Dark Web
* Declining a faction invite will stop you from receiving invitations from that faction for the rest of the run
* (BETA) Added functionality to export/import saves. WARNING This is only lightly tested. You cannot choose where to save your file it just goes to the default save location. Also I have no idea what will happen if you try to import a file that is not a valid save. I will address these in later updates
v0.20.0
-------
* Refactored Netscript Interpreter code. Operations in Netscript should now run significantly faster (Every operation such as a variable assignment, a function call, a binary operator, getting a variable's value, etc. used to take up to several seconds, now each one should only take ~500 milliseconds). 
* Percentage money stolen when hacking lowered to compensate for faster script speeds
* Hacking experience granted by grow() halved
* Weaken() is now ~11% faster, but only grants 3 base hacking exp upon completion instead of 5 
* Rebalancing of script RAM costs. Base RAM Cost for a script increased from 1GB to 1.5GB. Loops, hack(), grow() and weaken() all cost slightly less RAM than before 
* Added getServerRequiredHackingLevel(server) Netscript command. 
* Added fileExists(file, [server]) Netscript command, which is used to check if a script/program exists on a specified server
* Added isRunning(script, [server]) Netscript command, which is used to check if a script is running on the specified server
* Added killall Terminal command. Kills all running scripts on the current machine
* Added kill() and killall() Netscript commands. Used to kill scripts on specified machines. See Netscript documentation
* Re-designed 'Active Scripts' tab
* Hacknet Node base production rate lowered from 1.6 to 1.55 ($/second)
* Increased monetary cost of RAM (Upgrading home computer and purchasing servers will now be more expensive)
* NEW GROWTH MECHANICS - The rate of growth on a server now depends on a server's security level. A higher security level will result in lower growth on a server when using the grow() command. Furthermore, calling grow() on a server raises that server's security level by 0.004. For reference, if a server has a security level of 10 it will have approximately the same growth rate as before. 
* Server growth no longer happens naturally
* Servers now have a maximum limit to their money. This limit is 50 times it's starting money
* Hacking now grants 10% less hacking experience
* You can now edit scripts that are running
* Augmentations cost ~11% more money and 25% more faction reputation
v0.19.7
-------
* Added changelog to Options menu
* Bug fix with autocompletion (wasn't working properly for capitalized filenames/programs
v0.19.6
-------
* Script editor now saves its state even when you change tabs 
* scp() command in Terminal/script will now overwrite files at the destination 
* Terminal commands are no longer case-sensitive (only the commands themselves such as 'run' or 'nano'. Filenames are still case sensitive
* Tab automcompletion will now work on commands
v0.19.0
-------
* Hacknet Nodes have slightly higher base production, and slightly increased RAM multiplier. But they are also a bit more expensive at higher levels
* Calling grow() and weaken() in a script will now work offline, at slower rates than while online (The script now keeps track of the rate at which grow() and weaken() are called when the game is open. These calculated rates are used to determine how many times the calls would be made while the game is offline)
* Augmentations now cost 20% more reputation and 50% more money
* Changed the mechanic for getting invited to the hacking factions (CyberSec, NiteSec, The Black Hand, BitRunners) Now when you get to the required level to join these factions you will get a message giving you instructions on what to do in order to get invited.
* Added a bit of backstory/plot into the game. It's not fully fleshed out yet but it will be used in the future
* Made the effects of many Augmentations slightly more powerful
* Slightly increased company job wages across the board (~5-10% for each position)
* Gyms and classes are now significantly more expensive
* Doubled the amount by which a server's security increases when it is hacked. Now, it will increase by 0.002. Calling weaken() on a server will lower the security by 0.1.
v0.18.0
-------
* Major rebalancing (sorry didn't record specifics. But in general hacking gives more money and hacknet nodes give less)
* Server growth rate (both natural and manual using grow()) doubled
* Added option to Soft Reset
* Cancelling a full time job early now only results in halved gains for reputation. Exp and money earnings are gained in full
* Added exec() Netscript command, used to run scripts on other servers. 
* NEW HACKING MECHANICS: Whenever a server is hacked, its 'security level' is increased by a very small amount. The security level is denoted by a number between 1-100. A higher security level makes it harder to hack a server and also decreases the amount of money you steal from it. Two Netscript functions, weaken() and getServerSecurityLevel() level, were added. The weaken(server) function lowers a server's security level. See the Netscript documentation for more details
* When donating to factions, the base rate is now $1,000,000 for 1 reputation point. Before, it was $1,000 for 1 reputation point.
* Monetary costs for all Augmentations increased. They are now about ~3.3 - 3.75 times more expensive than before
v0.17.1
-------
* Fixed issue with purchasing Augmentations that are 'upgrades' and require previous Augmentations to be installed
* Increased the percentage of money stolen from servers when hacking
v0.17.0
-------
* Greatly increased amount of money gained for crimes (by about 400% for most crimes)
* Criminal factions require slightly less negative karma to get invited to
* Increased the percentage of money stolen from servers when hacking
* Increased the starting amount of money available on beginning servers (servers with <50 required hacking))
* Increased the growth rate of servers (both naturally and manually when using the grow() command in a script)
* Added getHostname() command in Netscript that returns the hostname of the server a script is running on
* jQuery preventDefault() called when pressing ctrl+b in script editor
* The Neuroflux Governor augmentation (the one that can be repeatedly leveled up) now increases ALL multipliers by 1%. To balance it out, it's price multiplier when it levels up was increased
* Hacknet Node base production decreased from $1.75/s to $1.65/s
* Fixed issue with nested for loops in Netscript (stupid Javascript references)
* Added 'scp' command to Terminal and Netscript
* Slightly nerfed Hacknet Node Kernel DNI and Hacknet Node Core DNI Augmentations
* Increased TOR Router cost to $200k
v0.16.0
-------
* New Script Editor interface 
* Rebalanced hacknet node - Increased base production but halved the multiplier from additional cores. This should boost its early-game production but nerf its late-game production
* Player now starts with 8GB of RAM on home computer
* 'scan-analyze' terminal command displays RAM on servers
* Slightly buffed the amount of money the player steals when hacking servers (by about ~8%)
* Time to execute grow() now depends on hacking skill and server security, rather than taking a flat 2 minutes.
* Clicking outside of a pop-up dialog box will now close it
* BruteSSH.exe takes 33% less time to create
* 'iron-gym' and 'max-hardware' servers now have 2GB of RAM
* Buffed job salaries across the board
* Updated Tutorial
* Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work 
v0.15.0
-------
* Slightly reduced production multiplier for Hacknet Node RAM
* Faction pages now scroll
* Slightly increased amount of money gained from hacking
* Added 'alias' command
* Added 'scan-analyze' terminal command - used to get basic hacking info about all immediate network connections
* Fixed bugs with upgradeHacknetNode() and purchaseHacknetNode() commands
* Added getNumHacknetNodes() and hasRootAccess(hostname/ip) commands to Netscript
* Increased Cost of university classes/gym
* You can now see what an Augmentation does and its price even while its locked

@ -22,6 +22,7 @@ secrets that you've been searching for.
Netscript <netscript>
Terminal <terminal>
Keyboard Shortcuts <shortcuts>
Changelog <changelog>
Indices and tables

@ -648,7 +648,7 @@ purchaseServer
.. js:function:: purchaseServer(hostname, ram)
:param string hostname: Hostname of the purchased server
:param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.)
:param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)
Purchased a server with the specified hostname and amount of RAM.

@ -58,6 +58,36 @@ var DocCommentHighlightRules = acequire("./doc_comment_highlight_rules").DocComm
var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*";
let NetscriptFunctions =
"hack|sleep|grow|weaken|print|tprint|scan|nuke|brutessh|ftpcrack|" + //Netscript functions
"clearLog|disableLog|enableLog|" +
"relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" +
"scp|ls|hasRootAccess|" +
"getIp|getHackingMultipliers|getBitNodeMultipliers|getStats|isBusy|" +
"getHacknetMultipliers|" +
"getHostname|getHackingLevel|getServerMoneyAvailable|getServerMaxMoney|" +
"getServerGrowth|getServerSecurityLevel|getServerBaseSecurityLevel|" +
"getServerMinSecurityLevel|" +
"getServerRequiredHackingLevel|getServerNumPortsRequired|getServerRam|" +
"serverExists|fileExists|isRunning|getNextHacknetNodeCost|" +
"purchaseHacknetNode|deleteServer|getPurchasedServers|" +
"purchaseServer|round|write|read|peek|clear|rm|getPortHandle|" +
"scriptRunning|scriptKill|getScriptName|getScriptRam|" +
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
"getTimeSinceLastAug|prompt|" +
"universityCourse|getCharacterInformation|" +
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
"getCompanyFavor|stopAction|getFactionFavor|" +
"checkFactionInvitations|joinFaction|workForFaction|getFactionRep|" +
"createProgram|commitCrime|getCrimeChance|getOwnedAugmentations|" +
"getAugmentationsFromFaction|" +
"getAugmentationCost|purchaseAugmentation|" +
"installAugmentations|hacknetnodes|upgradeLevel|upgradeRam|upgradeCore|" +
"getLevelUpgradeCost|getRamUpgradeCost|getCoreUpgradeCost|" +
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
"placeOrder|cancelOrder";
var NetscriptHighlightRules = function(options) {
var keywordMapper = this.createKeywordMapper({
"variable.language":
@ -69,37 +99,11 @@ var NetscriptHighlightRules = function(options) {
"SyntaxError|TypeError|URIError|" +
"decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions
"isNaN|parseFloat|parseInt|" +
"hack|sleep|grow|weaken|print|tprint|scan|nuke|brutessh|ftpcrack|" + //Netscript functions
"clearLog|disableLog|enableLog|" +
"relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" +
"scp|ls|hasRootAccess|" +
"getIp|getHackingMultipliers|getBitNodeMultipliers|getStats|isBusy|" +
"getHostname|getHackingLevel|getServerMoneyAvailable|getServerMaxMoney|" +
"getServerGrowth|getServerSecurityLevel|getServerBaseSecurityLevel|" +
"getServerMinSecurityLevel|" +
"getServerRequiredHackingLevel|getServerNumPortsRequired|getServerRam|" +
"serverExists|fileExists|isRunning|getNextHacknetNodeCost|" +
"purchaseHacknetNode|deleteServer|getPurchasedServers|" +
"purchaseServer|round|write|read|peek|clear|" +
"scriptRunning|scriptKill|getScriptRam|" +
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
"getTimeSinceLastAug|" +
"universityCourse|" +
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
"stopAction|" +
"checkFactionInvitations|joinFaction|workForFaction|getFactionRep|" +
"createProgram|commitCrime|getCrimeChance|getOwnedAugmentations|" +
"getAugmentationsFromFaction|" +
"getAugmentationCost|purchaseAugmentation|" +
"installAugmentations|hacknetnodes|upgradeLevel|upgradeRam|upgradeCore|" +
"getLevelUpgradeCost|getRamUpgradeCost|getCoreUpgradeCost|" +
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
"placeOrder|cancelOrder|" +
"ns|" + NetscriptFunctions +"|" +
"JSON|Math|" + // Other
"this|arguments|prototype|window|document" , // Pseudo
"keyword":
"const|yield|import|get|set|async|await|" +
"const|yield|import|get|set|async|await|foop|" +
"break|case|catch|continue|default|delete|do|else|finally|for|function|" +
"if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" +
"__parent__|__count__|escape|unescape|with|__proto__|" +
@ -239,6 +243,9 @@ var NetscriptHighlightRules = function(options) {
}, {
token : "punctuation.operator",
regex : /[.](?![.])/
}, {
token : "support.function",
regex : "/|" + NetscriptFunctions + "|/"
}, {
token : "support.function",
regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/

@ -47,10 +47,12 @@ var ActionCountGrowthPeriod = 300; //Time (s) it takes for action count to g
var RankToFactionRepFactor = 2; //Delta Faction Rep = this * Delta Rank
var ContractSuccessesPerLevel = 15; //How many successes you need to level up a contract
var OperationSuccessesPerLevel = 10; //How many successes you need to level up an op
var OperationSuccessesPerLevel = 10; //How many successes you need to level up an op
var RanksPerSkillPoint = 4; //How many ranks needed to get 1 Skill Point
var ContractBaseMoneyGain = 5e3; //Base Money Gained per contract
//DOM related variables
var ActiveActionCssClass = "bladeburner-active-action";
@ -1066,7 +1068,7 @@ Bladeburner.prototype.startAction = function(actionId) {
break;
case ActionTypes["Recruitment"]:
var effCharisma = Player.charisma * this.skillMultipliers.effCha;
var charismaFactor = Math.pow(effCharisma, 0.8) + effCharisma / 90;
var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90;
var time = Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor));
this.actionTimeToComplete = time;
break;
@ -1120,6 +1122,13 @@ Bladeburner.prototype.completeAction = function() {
++action.successes;
--action.count;
//Earn money for contracts
var moneyGain = 0;
if (!isOperation) {
moneyGain = ContractBaseMoneyGain * rewardMultiplier;
Player.gainMoney(moneyGain);
}
if (isOperation) {
action.maxLevel = Math.floor(action.successes / OperationSuccessesPerLevel) + 1;
} else {
@ -1131,7 +1140,7 @@ Bladeburner.prototype.completeAction = function() {
if (isOperation && this.logging.ops) {
this.log(action.name + " successfully completed! Gained " + formatNumber(gain, 3) + " rank");
} else if (!isOperation && this.logging.contracts) {
this.log(action.name + " contract successfully completed! Gained " + formatNumber(gain, 3) + " rank");
this.log(action.name + " contract successfully completed! Gained " + formatNumber(gain, 3) + " rank and " + numeral(moneyGain).format("$0.000a"));
}
}
isOperation ? this.completeOperation(true) : this.completeContract(true);
@ -1283,10 +1292,11 @@ Bladeburner.prototype.completeAction = function() {
Player.gainHackingExp(hackingExpGain);
Player.gainIntelligenceExp(BaseIntGain);
Player.gainCharismaExp(charismaExpGain);
this.changeRank(0.1);
console.log("DEBUG: Field Analysis effectiveness is " + (eff * this.skillMultipliers.successChanceEstimate));
this.getCurrentCity().improvePopulationEstimateByPercentage(eff * this.skillMultipliers.successChanceEstimate);
if (this.logging.general) {
this.log("Field analysis completed. Gained " + formatNumber(hackingExpGain, 1) + " hacking exp and " + formatNumber(charismaExpGain, 1) + " charisma exp");
this.log("Field analysis completed. Gained 0.1 rank, " + formatNumber(hackingExpGain, 1) + " hacking exp, and " + formatNumber(charismaExpGain, 1) + " charisma exp");
}
this.startAction(this.action); //Repeat action
break;
@ -1949,10 +1959,10 @@ Bladeburner.prototype.createContractsContent = function() {
}
DomElems.actionsAndSkillsDesc.innerHTML =
"Complete contracts in order to increase your Bitburner rank. " +
"Complete contracts in order to increase your Bitburner rank and earn money. " +
"Failing a contract will cause you to lose HP, which can lead to hospitalization.<br><br>" +
"You can unlock higher-level contracts by successfully completing them. " +
"Higher-level contracts are more difficult, but grant more rank and experience.";
"Higher-level contracts are more difficult, but grant more rank, experience, and money.";
for (var contractName in this.contracts) {
if (this.contracts.hasOwnProperty(contractName)) {
@ -3132,6 +3142,7 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
}
}
Bladeburner.prototype.toJSON = function() {
return Generic_toJSON("Bladeburner", this);
}

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.37.0",
Version: "0.37.1",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -90,6 +90,7 @@ let CONSTANTS = {
ServerWeakenAmount: 0.05, //Amount by which server's security decreases when weakened
PurchasedServerLimit: 25,
PurchasedServerMaxRam: 1048576, //2^20
//Augmentation Constants
AugmentationCostMultiplier: 5, //Used for balancing costs without having to readjust every Augmentation cost
@ -382,666 +383,9 @@ let CONSTANTS = {
"whenever you reload or re-open the game all of the scripts that you are running will " +
"start running from the BEGINNING of the code. The game does not keep track of where exactly " +
"the execution of a script is when it saves/loads. </strong><br><br>",
TutorialNetscriptText: "Netscript is a programming language implemented for this game. The language has " +
"your basic programming constructs and several built-in commands that are used to hack. <br><br>" +
"<u><h1>Official Documentation</h1></u><br>" +
"<a href='https://bitburner.readthedocs.io/en/latest/index.html' target='_blank'>Check out Bitburner's official Netscript documentation</a>" +
". This official documentation will contain more details and " +
"code examples than this documentation page. Also, it can be opened up in another tab/window for convenience!<br><br>" +
"<u><h1> Variables and data types </h1></u><br>" +
"The following data types are supported by Netscript: <br>" +
"numeric - Integers and floats (eg. 6, 10.4999)<br>" +
"string - Encapsulated by single or double quotes (eg. 'this is a string')<br>" +
"boolean - true or false<br><br>" +
"Strings are fully functional <a href='https://www.w3schools.com/jsref/jsref_obj_string.asp' target='_blank'>Javascript strings</a>, " +
"which means that all of the member functions of Javascript strings such as toLowerCase() and includes() are also " +
"available in Netscript!<br><br>" +
"To create a variable, use the assign (=) operator. The language is not strongly typed. Examples: <br>" +
"i = 5;<br>" +
"s = 'this game is awesome!';<br><br>" +
"In the first example above, we are creating the variable i and assigning it a value of 5. In the second, " +
"we are creating the variable s and assigning it the value of a string. Note that all expressions must be " +
"ended with a semicolon. <br><br>" +
"<u><h1> Operators</h1> </u><br>" +
"The following operators are supported by Netscript: <br>" +
"&nbsp;+<br>" +
"&nbsp;-<br>" +
"&nbsp;*<br>" +
"&nbsp;/<br>" +
"&nbsp;%<br>" +
"&nbsp;&&<br>" +
"&nbsp;||<br>" +
"&nbsp;<<br>" +
"&nbsp;><br>" +
"&nbsp;<=<br>" +
"&nbsp;>=<br>" +
"&nbsp;==<br>" +
"&nbsp;!=<br>" +
"&nbsp;++ (Note: This ONLY pre-increments. Post-increment does not work)<br>" +
"&nbsp;-- (Note: This ONLY pre-decrements. Post-decrement does not work)<br>" +
"&nbsp;- (Negation operator)<br>" +
"&nbsp;!<br><br>" +
"<u><h1> Arrays </h1></u><br>" +
"Netscript arrays have the same properties and functions as javascript arrays. For information see javascripts <a href=\"https://www.w3schools.com/js/js_arrays.asp\" target='_blank'>array</a> documentation.<br><br>"+
"<u><h1> Script Arguments </h1></u><br>" +
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
"operator. (args[0], args[1], args[2]...) <br><br>" +
"For example, let's say we want to make a generic script 'generic-run.script' and we plan to pass two arguments into that script. The first argument will be the name of " +
"another script, and the second argument will be a number. This generic script will run the script specified in the first argument " +
"with the amount of threads specified in the second element. The code would look like:<br><br>" +
"run(args[0], args[1]);<br><br>" +
"It is also possible to get the number of arguments that was passed into a script using:<br><br>" +
"args.length<br><br>" +
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
"args array.<br><br>" +
"<u><h1>Javascript Modules</h1></u><br>" +
"Netscript supports the following Javascript Modules:<br><br>" +
"Math<br>Date (static functions only)<br><br>" +
"<u><h1> Functions </h1></u><br>" +
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
"you may use: <br><br> " +
"<i><u>hack(hostname/ip)</u></i><br>Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " +
"either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " +
" A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " +
"For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. A successful hack() on " +
"a server will raise that server's security level by 0.002. Returns the amount of money stolen if the hack is successful and " +
"0 if the hack fails. <br>" +
"Examples: hack('foodnstuff'); or hack('148.192.0.12');<br><br>" +
"<i><u>sleep(n)</u></i><br>Suspends the script for n milliseconds.<br>Example: sleep(5000);<br><br>" +
"<i><u>grow(hostname/ip)</u></i><br>Use your hacking skills to increase the amount of money available on a server. The argument passed in " +
"must be a string with either the IP or hostname of the target server. The runtime for this command depends on your hacking level and the target server's security level. " +
"When grow() completes, the money available on a target server will be increased by a certain, fixed percentage. This percentage " +
"is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates. <br><br> " +
"Like hack(), grow() can be called on any server, regardless of where the script is running. " +
"The grow() command requires root access to the target server, but there is no required hacking level to run the command. " +
"It also raises the security level of the target server by 0.004. " +
"Returns the number by which the money on the server was multiplied for the growth. " +
"Works offline at a slower rate. <br> Example: grow('foodnstuff');<br><br>" +
"<i><u>weaken(hostname/ip)</u></i><br>Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " +
"in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " +
"hacking level and the target server's security level. This function lowers the security level of the target server by " +
"0.05.<br><br> Like hack() and grow(), weaken() can be called on " +
"any server, regardless of where the script is running. This command requires root access to the target server, but " +
"there is no required hacking level to run the command. Returns " +
"0.1. Works offline at a slower rate<br> Example: weaken('foodnstuff');<br><br>" +
"<i><u>print(x)</u></i><br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br><br>" +
"<i><u>tprint(x)</u></i><br>Prints a value or a variable to the Terminal<br><br>" +
"<i><u>clearLog()</u></i><br>Clears the script's logs. <br><br>" +
"<i><u>disableLog(fn)</u></i><br>Disables logging for the given function. Logging can be disabled for every function " +
"by passing 'ALL' as an argument.<br><br>" +
"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.<br><br>" +
"Notable functions that cannot have their logs disabled: run, exec, exit<br><br>" +
"<i><u>enableLog(fn)</u></i><br>Re-enables logging for the given function. If 'ALL' is passed into this function " +
"as an argument, then it will revert the effects of disableLog('ALL')<br><br>" +
"<i><u>scan(hostname/ip, [hostnames=true])</u></i><br>Returns an array containing the hostnames or IPs of all servers that are one node away from the specified server. " +
"The argument must be a string containing the IP or hostname of the target server. The second argument is a boolean that specifies whether " +
"the hostnames or IPs of the scanned servers should be output. If it is true then hostnames will be returned, and if false then IP addresses will. " +
"This second argument is optional and, if ommitted, the function will output " +
"the hostnames of the scanned servers. The hostnames/IPs in the returned array are strings.<br><br>" +
"<i><u>nuke(hostname/ip)</u></i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer.<br> Example: nuke('foodnstuff'); <br><br>" +
"<i><u>brutessh(hostname/ip)</u></i><br>Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer.<br> Example: brutessh('foodnstuff');<br><br>" +
"<i><u>ftpcrack(hostname/ip)</u></i><br>Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer.<br> Example: ftpcrack('foodnstuff');<br><br>" +
"<i><u>relaysmtp(hostname/ip)</u></i><br>Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer.<br> Example: relaysmtp('foodnstuff');<br><br>" +
"<i><u>httpworm(hostname/ip)</u></i><br>Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer.<br> Example: httpworm('foodnstuff');<br><br>" +
"<i><u>sqlinject(hostname/ip)</u></i><br>Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer.<br> Example: sqlinject('foodnstuff');<br><br>" +
"<i><u>run(script, [numThreads], [args...])</u></i> <br> Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " +
"be used to run scripts located on the current server (the server running the script that calls this function). The second argument " +
"is optional, and it specifies how many threads to run the script with. This argument must be a number greater than 0. If it is omitted, then the script will be run single-threaded. Any additional arguments will specify " +
"arguments to pass into the new script that is being run. If arguments are specified for the new script, then the second argument numThreads argument must be filled in with a value.<br><br>" +
"Returns true if the script is successfully started, and false otherwise. Requires a significant amount " +
"of RAM to run this command.<br><br>" +
"The simplest way to use the run command is to call it with just the script name. The following example will run 'foo.script' single-threaded with no arguments:<br><br>" +
"run('foo.script');<br><br>" +
"The following example will run 'foo.script' but with 5 threads instead of single-threaded:<br><br>" +
"run('foo.script', 5);<br><br>" +
"The following example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script as an argument:<br><br>" +
"run('foo.script', 1, 'foodnstuff');<br><br>" +
"<i><u>exec(script, hostname/ip, [numThreads], [args...])</u></i><br>Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
"second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. " +
"The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " +
"This argument must be a number that is greater than 0. Any additional arguments will specify arguments to pass into the new script that is being run. If " +
"arguments are specified for the new script, then the third argument numThreads must be filled in with a value.<br><br>Returns " +
"true if the script is successfully started, and false otherwise.<br><br> " +
"The simplest way to use the exec command is to call it with just the script name and the target server. The following example will try to run 'generic-hack.script' " +
"on the 'foodnstuff' server:<br><br>" +
"exec('generic-hack.script', 'foodnstuff');<br><br>" +
"The following example will try to run the script 'generic-hack.script' on the 'joesguns' server with 10 threads:<br><br>" +
"exec('generic-hack.script', 'joesguns', 10);<br><br>" +
"The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " +
"to the script.<br><br>" +
"exec('foo.script', 'foodnstuff', 5, 1, 'test');<br><br>" +
"<i><u>spawn(script, numThreads, [args...])</u></i><br>Terminates the current script, and then after a delay of about 20 seconds " +
"it will execute the newly specified script. The purpose of this function is to execute a new script without being constrained " +
"by the RAM usage of the current one. This function can only be used to run scripts on the local server.<br><br>" +
"The first argument must be a string with the name of the script. The second argument must be an integer specifying the number " +
"of threads to run the script with. Any additional arguments will specify arguments to pass into the 'newly-spawned' script." +
"Because this function immediately terminates the script, it does not have a return value.<br><br>" +
"The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90:<br><br>" +
"spawn('foo.script', 10, 'foodnstuff', 90);<br><br>" +
"<i><u>kill(script, hostname/ip, [args...])</u></i><br>Kills the script on the target server specified by the script's name and arguments. Remember that " +
"scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " +
"same as 'foo.script' run with the argument 2, even though they have the same code. <br><br>" +
"The first argument must be a string with the name of the script. The name is case-sensitive. " +
"The second argument must be a string with the hostname or IP of the target server. Any additional arguments to the function will specify the arguments passed " +
"into the script that should be killed. <br><br>The function will try to kill the specified script on the target server. " +
"If the script is found on the specified server and is running, then it will be killed and this function " +
"will return true. Otherwise, this function will return false. <br><br>" +
"Examples:<br>" +
"If you are trying to kill a script named 'foo.script' on the 'foodnstuff' server that was ran with no arguments, use this:<br><br>" +
"kill('foo.script', 'foodnstuff');<br><br>" +
"If you are trying to kill a script named 'foo.script' on the current server that was ran with no arguments, use this:<br><br>" +
"kill('foo.script', getHostname());<br><br>" +
"If you are trying to kill a script named 'foo.script' on the current server that was ran with the arguments 1 and 'foodnstuff', use this:<br><br>" +
"kill('foo.script', getHostname(), 1, 'foodnstuff');<br><br>" +
"<i><u>killall(hostname/ip)</u></i><br>Kills all running scripts on the specified server. This function takes a single argument which " +
"must be a string containing the hostname or IP of the target server. This function returns true if any scripts were killed, and false otherwise.<br><br>" +
"<i><u>exit()</u></i><br>Terminates the script immediately<br><br>" +
"<i><u>scp(script, [source], destination)</u></i><br>Copies a script or literature (.lit) file to another server. The first argument is a string with " +
"the filename of the script or literature file " +
"to be copied, or an array of filenames to be copied. The next two arguments are strings containing the hostname/IPs of the source and target server. " +
"The source refers to the server from which the script/literature file will be copied, while the destination " +
"refers to the server to which it will be copied. The source server argument is optional, and if ommitted the source " +
"will be the current server (the server on which the script is running). Returns true if the script/literature file is " +
"successfully copied over and false otherwise. If the first argument passed in is an array, then the function " +
"will return if at least one of the files in the array is successfully copied over.<br><br>" +
"Example: scp('hack-template.script', 'foodnstuff'); //Copies hack-template.script from the current server to foodnstuff<br>" +
"Example: scp('foo.lit', 'helios', 'home'); //Copies foo.lit from the helios server to the home computer<br><br>" +
"<i><u>ls(hostname/ip)</u></i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
"string with the hostname or IP of the target server.<br><br>" +
"<i><u>hasRootAccess(hostname/ip)</u></i><br> Returns a boolean (true or false) indicating whether or not the Player has root access to a server. " +
"The argument passed in must be a string with either the hostname or IP of the target server.<br> " +
"Example:<br>if (hasRootAccess('foodnstuff') == false) {<br>&nbsp;&nbsp;&nbsp;&nbsp;nuke('foodnstuff');<br>}<br><br>" +
"<i><u>getIp()</u></i><br>Returns a string with the IP Address of the server that the script is running on <br><br>" +
"<i><u>getHostname()</u></i><br>Returns a string with the hostname of the server that the script is running on<br><br>" +
"<i><u>getHackingLevel()</u></i><br>Returns the Player's current hacking level.<br><br> " +
"<i><u>getHackingMultipliers()</u></i><br>Returns an object containing the Player's hacking related multipliers. " +
"These multipliers are returned in integer forms, not percentages (e.g. 1.5 instead of 150%). " +
"The object has the following structure:<br><br>" +
"{<br>" +
"chance: Player's hacking chance multiplier<br>" +
"speed: Player's hacking speed multiplier<br>" +
"money: Player's hacking money stolen multiplier<br>" +
"growth: Player's hacking growth multiplier<br>" +
"}<br><br>Example:<br><br>" +
"mults = getHackingMultipliers();<br>" +
"print(mults.chance);<br>" +
"print(mults.growth);<br><br>" +
"<i><u>getBitNodeMultipliers()</u></i><br>Returns an object containing the current BitNode multipliers. " +
"This function requires Source-File 5 in order to run. The multipliers are returned in integer forms, not percentages " +
"(e.g. 1.5 instead of 150%). The multipliers represent the difference between the current BitNode and the " +
"original BitNode (BitNode-1). For example, if the 'CrimeMoney' multiplier has a value of 0.1 then that means " +
"that committing crimes in the current BitNode will only give 10% of the money you would have received in " +
"BitNode-1. The object has the following structure (subject to change in the future):<br><br>" +
"{<br>" +
"ServerMaxMoney: 1,<br>" +
"ServerStartingMoney: 1,<br>" +
"ServerGrowthRate: 1,<br>" +
"ServerWeakenRate: 1,<br>" +
"ServerStartingSecurity: 1,<br>" +
"ManualHackMoney: 1,<br>" +
"ScriptHackMoney: 1,<br>" +
"CompanyWorkMoney: 1,<br>" +
"CrimeMoney: 1,<br>" +
"HacknetNodeMoney: 1,<br>" +
"CompanyWorkExpGain: 1,<br>" +
"ClassGymExpGain: 1,<br>" +
"FactionWorkExpGain: 1,<br>" +
"HackExpGain: 1,<br>" +
"CrimeExpGain: 1,<br>" +
"FactionWorkRepGain: 1,<br>" +
"FactionPassiveRepGain: 1,<br>" +
"AugmentationRepCost: 1,<br>" +
"AugmentationMoneyCost: 1,<br>" +
"}<br><br>Example:<br><br>" +
"mults = getBitNodeMultipliers();<br>" +
"print(mults.ServerMaxMoney);<br>" +
"print(mults.HackExpGain);<br><br>" +
"<i><u>getServerMoneyAvailable(hostname/ip)</u></i><br> Returns the amount of money available on a server. The argument passed in must be a string with either the " +
"hostname or IP of the target server.<br> Example: getServerMoneyAvailable('foodnstuff');<br><br>" +
"<i><u>getServerMaxMoney(hostname/ip)</u></i><br>Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " +
"the hostname or IP of the target server.<br>Example: getServerMaxMoney('foodnstuff');<br><br>" +
"<i><u>getServerGrowth(hostname/ip)</u></i><br>Returns the server's intrinsic 'growth parameter'. This growth parameter is a number " +
"between 1 and 100 that represents how quickly the server's money grows. This parameter affects the percentage by which this server's " +
"money is increased when using the grow() function. A higher growth parameter will result in a higher percentage from grow().<br><br>" +
"The argument passed in must be a string with the hostname or IP of the target server.<br><br>" +
"<i><u>getServerSecurityLevel(hostname/ip)</u></i><br>Returns the security level of a server. The argument passed in must be a string with either the " +
"hostname or IP of the target server. A server's security is denoted by a number, typically between 1 and 100.<br><br>" +
"<i><u>getServerBaseSecurityLevel(hostname/ip)</u></i><br>Returns the base security level of a server. This is the security level that the server starts out with. " +
"This is different than getServerSecurityLevel() because getServerSecurityLevel() returns the current security level of a server, which can constantly change " +
"due to hack(), grow(), and weaken() calls on that server. The base security level will stay the same until you reset by installing an Augmentation. <br><br>" +
"The argument passed in must be a string with either the hostname or IP of the target server. A server's base security is denoted by a number, typically between 1 and 100. " +
"<br><br>" +
"<i><u>getServerMinSecurityLevel(hostname/ip)</u></i>Returns the minimum security level of a server. The argument passed in must be a string with " +
"either the hostname or IP of the target server.<br><br>" +
"<i><u>getServerRequiredHackingLevel(hostname/ip)</u></i><br>Returns the required hacking level of a server. The argument passed in must be a string with either the " +
"hostname or IP or the target server.<br><br>" +
"<i><u>getServerNumPortsRequired(hostname/ip)</u></i><br>Returns the number of open ports required to successfully run NUKE.exe on a server. The argument " +
"passed in must be a string with either the hostname or IP of the target server.<br><br>" +
"<i><u>getServerRam(hostname/ip)</u></i><br>Returns an array with two elements that gives information about the target server's RAM. The first " +
"element in the array is the amount of RAM that the server has (in GB). The second element in the array is the amount of RAM that " +
"is currently being used on the server.<br><br>" +
"<i><u>serverExists(hostname/ip)</u></i><br>Returns a boolean denoting whether or not the specified server exists. The argument " +
"must be a string with the hostname or IP of the target server.<br><br>" +
"<i><u>fileExists(filename, [hostname/ip])</u></i><br> Returns a boolean (true or false) indicating whether the specified file exists on a server. " +
"The first argument must be a string with the filename. A file can either be a script, program, literature file, or a text file. The filename for a script is case-sensitive, but " +
"for the other files it is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe. <br><br> " +
"The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " +
"If it is omitted, then the function will search through the current server (the server running the script that calls this function) for the file. <br> " +
"Example: fileExists('foo.script', 'foodnstuff');<br>" +
"Example: fileExists('ftpcrack.exe');<br><br>" +
"The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " +
"return true if the current server (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise. <br><br>" +
"<i><u>isRunning(filename, hostname/ip, [args...])</u></i><br> Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
"Remember that a script is uniquely identified by both its name and its arguments. <br><br>" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " +
"hostname or IP of the target server. Any additional arguments passed to the function will specify the arguments passed into the target script. " +
"The function will check whether the script is running on that target server.<br>" +
"Example: isRunning('foo.script', 'foodnstuff');<br>" +
"Example: isRunning('foo.script', getHostname());<br>" +
"Example: isRunning('foo.script', 'joesguns', 1, 5, 'test');<br><br>" +
"The first example above will return true if there is a script named 'foo.script' with no arguments running on the 'foodnstuff' server, and false otherwise. The second " +
"example above will return true if there is a script named 'foo.script' with no arguments running on the current server, and false otherwise. " +
"The third example above will return true if there is a script named 'foo.script' with the arguments 1, 5, and 'test' running on the 'joesguns' server, and " +
"false otherwise.<br><br>" +
"<i><u>getNextHacknetNodeCost()</u></i><br>Returns the cost of purchasing a new Hacknet Node<br><br>" +
"<i><u>purchaseHacknetNode()</u></i><br>Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " +
"at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " +
"a new Hacknet Node then the function will return false. Does NOT work offline<br><br>" +
"<i><u>purchaseServer(hostname, ram)</u></i><br> Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " +
"but it will be converted to a string using Javascript's String function. Anything that resolves to an empty string will cause the function to fail. " +
"The second argument specified the amount of RAM (in GB) for the server. This argument must resolve to a numeric and it must be a power of 2 " +
"(2, 4, 8, etc...). <br><br>" +
"This function returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return " +
"an empty string. The function will fail if the arguments passed in are invalid or if the player does not have enough money to purchase the specified server.<br><br>" +
"<i><u>deleteServer(hostname)</u></i><br>Deletes one of the servers you've purchased with the specified hostname. The function will fail if " +
"there are any scripts running on the specified server. Returns true if successful and false otherwise<br><br>" +
"<i><u>getPurchasedServers([hostname=true])</u></i><br>Returns an array with either the hostname or IPs of all of the servers you " +
"have purchased. It takes an optional parameter specifying whether the hostname or IP addresses will be returned. If this " +
"parameter is not specified, it is true by default and hostnames will be returned<br><br>" +
"<i><u>write(port/fn, data='', mode='a')</u></i><br>This function can be used to either write data to a port or to a text file (.txt).<br><br>" +
"If the first argument is a number between 1 and 10, then it specifies a port and this function will write data to a port. If the second " +
"argument is not specified then it will write an empty string to the port. The third argument, mode, is not used when writing data to a port.<br><br>" +
"If the first argument is a string, then it specifies the name of a text file (.txt) and this function will write data to a text file. " +
"The second argument defines the data to be written to the text file. If it is not specified then it is an empty string by default. " +
"This third argument, mode, defines how the data will be written to the text file. If mode is set to 'w', then the data is written in 'write' " +
"mode which means that it will overwrite the existing data on the file, or it will create a new file if it does not already exist. Otherwise, " +
"the data will be written in 'append' mode which means that the data will be added at the end of the existing file, or it will create a new file if it " +
"does not already exist. If mode isn't specified then it will be 'a' for 'append' mode by default.<br><br>" +
"<i><u>read(port/fn)</u></i><br>This function is used to read data from a port or from a text file (.txt).<br><br>" +
"This function takes a single argument. If this argument is a number between 1 and 10, then it specifies a port and it will read data from " +
"a port. A port is a serialized queue. This function will remove the first element from the queue and return it. If the queue is empty, " +
"then the string 'NULL PORT DATA' will be returned.<br><br>" +
"If the first argument is a string, then it specifies the name of a text file and this function will return the data in the " +
"specified text file. If the text file does not exist, an empty string will be returned<br><br>" +
"<i><u>peek(port)</u></i><br>This function is used to peek data from a port. It returns the first element from the specified " +
"Netscript Port without removing that element. If the port is empty, then the string 'NULL PORT DATA' will be returned.<br><br>" +
"The argument must be an integer between 1 and 10.<br><br>" +
"<i><u>clear(port/fn)</u></i><br>This function is used to clear a Netscript Port or a text file.<br><br>" +
"It takes a single argument. If this argument is a number between 1 and 10, then it specifies a port and will clear it (deleting all data from it). " +
"If the argument is a string, then it specifies the name of a text file (.txt) and will clear the text file so that it is empty.<br><br>" +
"<i><u>rm(fn)</u></i><br>This function is used to remove a file. It takes a string with the filename as the argument. Returns " +
"true if it successfully deletes the given file, and false otherwise. This function works for every file type except message files (.msg).<br><br>" +
"<i><u>scriptRunning(scriptname, hostname/ip)</u></i><br>Returns a boolean indicating whether any instance of the specified script is running " +
"on a server, regardless of its arguments. This is different than the isRunning() function because it does not " +
"try to identify a specific instance of a running script by its arguments.<br><br>" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
"a string with the hostname or IP of the target server. Both arguments are required.<br><br>" +
"<i><u>scriptKill(scriptname, hostname/ip)</u></i><br>Kills all scripts with the specified filename that are running on the server specified by the " +
"hostname/ip, regardless of arguments. Returns true if one or more scripts were successfully killed, and false if there were none. <br><br>" +
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
"a string with the hostname or IP of the target server. Both arguments are required.<br><br>" +
"<i><u>getScriptName()</u></i><br>Returns the filename of the current script (including the extension)<br><br>" +
"<i><u>getScriptRam(scriptname, hostname/ip)</u></i><br>Returns the amount of RAM required to run the specified script on the " +
"target server. The first argument must be a string with the name of the script. The script name is case sensitive. " +
"The second argument is a string with the hostname or IP of the server where that script is. Both arguments are required.<br><br>" +
"<i><u>getHackTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the hack() Netscript function " +
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
"<i><u>getGrowTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the grow() Netscript function " +
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
"<i><u>getWeakenTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the weaken() Netscript function " +
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
"<i><u>getScriptIncome([scriptname], [hostname/ip], [args...])</u></i><br>" +
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
"offline income). This function can also be called with no arguments. If called with no arguments, then this function " +
"will return an array of two values. The first value is the total income ($/sec) of all of your active scripts (currently running). " +
"The second value is the total income ($/sec) from scripts since you last installed Augmentations (or destroyed a BitNode).<br><br>" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.<br><br>" +
"The first argument, if specified, must be a string with the name of the script (including the .script extension). " +
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.<br><br>" +
"<i><u>getScriptExpGain([scriptname], [hostname/ip], [args...])</u></i><br>" +
"Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for " +
"offline experience gains). This function can also return the total experience gain rate of all of your active scripts by running the function " +
"with no arguments.<br><br>" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.<br><br>" +
"The first argument, if specified, must be a string with the name of the script (including the .script extension). " +
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.<br><br>" +
"<i><u>getTimeSinceLastAug()</u></i><br>" +
"Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).<br><br>" +
"<i><u>sprintf()/vsprintf()</u></i><br>" +
"<a href='https://github.com/alexei/sprintf.js' target='_blank'>See this link for details</a><br><br>" +
"<i><u>prompt(message)</u></i><br>" +
"Prompts the player with a dialog box with two options: 'Yes' and 'No'. This function will returns true if " +
"the player clicks 'Yes' and false if the player click's 'No'. The script's execution is halted until the " +
"player selects 'Yes' or 'No'. The function takes a single string as an argument which specifies the text " +
"that appears on the dialog box.<br><br>" +
"<u><h1>Hacknet Nodes API</h1></u><br>" +
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.<br><br>" +
"<i><u>hacknetnodes</u></i><br>A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
"indexes. These indexes correspond to the number at the end of the name of the Hacknet Node. For example, the first Hacknet Node you purchase " +
"will have the same 'hacknet-node-0' and can be accessed with hacknetnodes[0]. The fourth Hacknet Node you purchase will have the name " +
"'hacknet-node-3' and can be accessed with hacknetnodes[3]. <br><br>" +
"<i><u>hacknetnodes.length</u></i><br>Returns the number of Hacknet Nodes that the player owns<br><br>" +
"<i><u>hacknetnodes[i].level</u></i><br>Returns the level of the corresponding Hacknet Node<br><br>" +
"<i><u>hacknetnodes[i].ram</u></i><br>Returns the amount of RAM on the corresponding Hacknet Node<br><br>" +
"<i><u>hacknetnodes[i].cores</u></i><br>Returns the number of cores on the corresponding Hacknet Node<br><br>" +
"<i><u>hacknetnodes[i].totalMoneyGenerated</u></i><br>Returns the total amount of money that the corresponding Hacknet Node has earned<br><br>" +
"<i><u>hacknetnodes[i].onlineTimeSeconds</u></i><br>Returns the total amount of time that the corresponding Hacknet Node has existed<br><br>" +
"<i><u>hacknetnodes[i].moneyGainRatePerSecond</u></i><br>Returns the income ($ / sec) that the corresponding Hacknet Node earns<br><br>" +
"<i><u>hacknetnodes[i].upgradeLevel(n)</u></i><br>Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
"positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times or up to the max level (200), and false otherwise.<br><br>" +
"<i><u>hacknetnodes[i].upgradeRam()</u></i><br>Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
"RAM is successfully upgraded, and false otherwise. <br><br>" +
"<i><u>hacknetnodes[i].upgradeCore()</u></i><br>Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
"additional core is successfully purchase, and false otherwise. <br><br>" +
"Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " +
"This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " +
"to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.<br><br>" +
"while(hacknetnodes.length < 4) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;purchaseHacknetNode();<br>" +
"}<br>" +
"for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].level <= 75) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeLevel(5);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"}<br>" +
"for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].ram < 8) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeRam();<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"}<br>" +
"for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].cores < 2) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeCore();<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"}<br><br>" +
"<u><h1>Trade Information eXchange (TIX) API</h1></u><br>" +
"<i><u>getStockPrice(sym)</u></i><br>Returns the price of a stock. The argument passed in must be the stock's symbol (NOT THE COMPANY NAME!). The symbol " +
"is a sequence of two to four capital letters. The symbol argument must be a string. <br><br>" +
"Example: getStockPrice('FSIG');<br><br>" +
"<i><u>getStockPosition(sym)</u></i><br>Returns an array of two elements that represents the player's position in a stock. The first element " +
"in the array is the number of shares the player owns of the specified stock. The second element in the array is the average price of the player's " +
"shares. Both elements are numbers. The argument passed in must be the stock's symbol, which is a sequence of two to four capital letters.<br><br>" +
"Example: <br><br>pos = getStockPosition('ECP');<br>shares = pos[0];<br>avgPx = pos[1];<br><br>"+
"<i><u>buyStock(sym, shares)</u></i><br>Attempts to purchase shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
"must be the number of shares to purchase.<br><br>" +
"If the player does not have enough money to purchase specified number of shares, then no shares will be purchased (it will not purchase the most you can afford). " +
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
"If this function successfully purchases the shares, it will return the stock price at which each share was purchased. Otherwise, it will return 0.<br><br>" +
"<i><u>sellStock(sym, shares)</u></i><br>Attempts to sell shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
"must be the number of shares to sell.<br><br>" +
"If the specified number of shares in the function exceeds the amount that the player actually owns, then this function will sell all owned shares. " +
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
"The net profit made from selling stocks with this function is reflected in the script's statistics. This net profit is calculated as: <br><br>" +
"shares * (sell price - average price of purchased shares)<br><br>" +
"If the sale is successful, this function will return the stock price at which each share was sold. Otherwise, it will return 0.<br><br>" +
"<i><u>shortStock(sym, shares)</u></i><br>" +
"Attempts to purchase a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
"must be the number of shares to purchase.<br><br>" +
"In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.<br><br>" +
"If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. Remember that every " +
"every transaction on the stock exchange costs a certain commission fee.<br><br>" +
"If the purchase is successful, this function will return the stock price at which each share was purchased. Otherwise, it will return 0.<br><br>" +
"<i><u>sellShort(sym, shares)</u></i><br>" +
"Attempts to sell a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument must be the " +
"number of shares to sell.<br><br>" +
"In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.<br><br>" +
"If the specified number of shares exceeds the amount that the player actually owns, then this function will sell all owned shares. " +
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
"If the sale was successful, this function will return the stock price at which each sale was sold. Otherwise, it will return 0.<br><br>" +
"<i><u>placeOrder(sym, shares, price, type, pos)</u></i><br>" +
"Places an order on the stock market. This function only works for Limit and Stop Orders. Use the buyStock/sellStock/shortStock/sellShort functions " +
"to place Market Orders. In order to use this function the player must be in BitNode-8 or must have Level 3 of Source-File 8.<br><br>" +
"The 'sym' argument must be a string with the symbol of the stock. The 'shares' and 'price' arguments " +
"specify the number of shares and the execution price for the order. They must be numeric.<br><br>" +
"The 'type' argument is a string that specifies the type of order. It must specify either 'limit' or 'stop', and must " +
"also specify 'buy' or 'sell'. This argument is NOT case-sensitive. Here are four examples that will work: <br><br>" +
"limitbuy, limitsell, stopbuy, stopsell<br><br>" +
"The last argument, 'pos', is a string that specifies whether the order is a 'Long' or 'Short' position. The values 'L' and " +
"'S' can also be used. This argument is NOT case-sensitive.<br><br>" +
"Returns true if the order is successfully placed, and false otherwise.<br><br>" +
"<i><u>cancelOrder(sym, shares, price, type, pos)</u></i><br>" +
"Cancels an oustanding order on the stock market. In order to use this function the player must be in BitNode-8 or must have " +
"Level 3 of Source-File 8. This function uses the same arguments as placeOrder()<br><br>" +
"<u><h1>While loops </h1></u><br>" +
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
"<i>while (<i>[cond]</i>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;<i>[code]</i><br>}</i><br><br>" +
"As long as <i>[cond]</i> remains true, the code block <i>[code]</i> will continuously execute. Example: <br><br>" +
"<i>i = 0; <br> while (i < 10) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>&nbsp;&nbsp;&nbsp;&nbsp;i = i + 1;<br> } </i><br><br>" +
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" +
"<i>while(true) { <br>&nbsp;&nbsp;&nbsp;&nbsp; hack('foodnstuff'); <br> }</i><br><br> " +
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " +
"<u><h1>For loops</h1></u><br>" +
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " +
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;<i>code</i> <br> } </i><br><br>" +
"The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " +
"as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " +
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
" using a for loop: <br><br>" +
"<i>for (i = 0; i < 10; i = i++) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>} </i><br><br>" +
"<u><h1> If statements </h1></u><br>" +
"If/Else if/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
"<i>if (condition1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code1<br>} else if (condition2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code2<br>} else {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;code3<br>}</i><br><br>" +
"In the code above, first <i>condition1</i> will be checked. If this condition is true, then <i>code1</i> will execute and the " +
"rest of the if/else if/else statement will be skipped. If <i>condition1</i> is NOT true, then the code will then go on to check " +
"<i>condition2</i>. If <i>condition2</i> is true, then <i>code2</i> will be executed, and the rest of the if/else if/else statement " +
"will be skipped. If none of the conditions are true, then the code within the else block (<i>code3</i>) will be executed. " +
"Note that a conditional statement can have any number of 'else if' statements. <br><br>" +
"Example: <br><br>" +
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>" +
"} else {<br>&nbsp;&nbsp;&nbsp;&nbsp;grow('foodnstuff');<br>}<br><br>" +
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
"then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>",
TutorialSingularityFunctionsText: "<u><h1>Singularity Functions</h1></u><br>" +
"The Singularity Functions are a special set of Netscript functions that are unlocked in BitNode-4. " +
"These functions allow you to control many additional aspects of the game through scripts, such as " +
"working for factions/companies, purchasing/installing Augmentations, and creating programs.<br><br>" +
"If you are in BitNode-4, then you will automatically have access to all of these functions. " +
"You can use the Singularity Functions in other BitNodes if and only if you have the Source-File " +
"for BitNode-4 (aka Source-File 4). Each level of Source-File 4 will open up additional Singularity " +
"Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to level 3, " +
"then you will be able to access all of the Singularity Functions.<br><br>" +
"Note that Singularity Functions require a lot of RAM outside of BitNode-4 (their RAM costs are multiplied by " +
"10 if you are not in BitNode-4).<br><br>" +
"<i><u>universityCourse(universityName, courseName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically set you to start taking a course at a university. If you are already " +
"in the middle of some 'working' action (such as working at a company, for a faction, or on a program), " +
"then running this function will automatically cancel that action and give you your earnings.<br><br>" +
"The first argument must be a string with the name of the university. The names are NOT case-sensitive. " +
"Note that you must be in the correct city for whatever university you specify. The three universities are:<br><br>" +
"Summit University<br>Rothman University<br>ZB Institute of Technology<br><br>" +
"The second argument must be a string with the name of the course you are taking. These names are NOT case-sensitive. " +
"The available courses are:<br><br>" +
"Study Computer Science<br>Data Structures<br>Networks<br>Algorithms<br>Management<br>Leadership<br><br>" +
"The cost and experience gains for all of these universities and classes are the same as if you were to manually " +
"visit and take these classes.<br><br>" +
"This function will return true if you successfully start taking the course, and false otherwise.<br><br>" +
"<i><u>gymWorkout(gymName, stat)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically set you to start working out at a gym to train a particular stat. If you are " +
"already in the middle of some 'working' action (such as working at a company, for a faction, or on a program), then " +
"running this function will automatically cancel that action and give you your earnings.<br><br>" +
"The first argument must be a string with the name of the gym. The names are NOT case-sensitive. Note that you must " +
"be in the correct city for whatever gym you specify. The available gyms are:<br><br>" +
"Crush Fitness Gym<br>Snap Fitness Gym<br>Iron Gym<br>Powerhouse Gym<br>Millenium Fitness Gym<br><br>" +
"The second argument must be a string with the stat you want to work out. These are NOT case-sensitive. " +
"The valid stats are:<br><br>strength OR str<br>defense OR def<br>dexterity OR dex<br>agility OR agi<br><br>" +
"The cost and experience gains for all of these gyms are the same as if you were to manually visit these gyms and train " +
"This function will return true if you successfully start working out at the gym, and false otherwise.<br><br>" +
"<i><u>travelToCity(cityname)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
"This function allows the player to travel to any city. The cost for using this function is the same as the cost for traveling through the Travel Agency.<br><br>" +
"The argument passed into this must be a string with the name of the city to travel to. Note that this argument IS CASE SENSITIVE. The valid cities are:<br><br>" +
"Aevum<br>Chongqing<br>Sector-12<br>New Tokyo<br>Ishima<br>Volhaven<br><br>" +
"This function will return true if you successfully travel to the specified city and false otherwise.<br><br>" +
"<i><u>purchaseTor()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
"This function allows you to automatically purchase a TOR router. The cost for purchasing a TOR router using this " +
"function is the same as if you were to manually purchase one.<br><br>" +
"This function will return true if it successfully purchase a TOR router and false otherwise.<br><br>" +
"<i><u>purchaseProgram(programName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
"This function allows you to automatically purchase programs. You MUST have a TOR router in order to use this function.<br><br>" +
"The argument passed in must be a string with the name of the program (including the '.exe' extension). This argument is " +
"NOT case-sensitive.<br><br>Example: " +
"purchaseProgram('brutessh.exe');<br><br>" +
"The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web (using " +
"the buy Terminal command).<br><br>" +
"This function will return true if the specified program is purchased, and false otherwise.<br><br>" +
"<i><u>getStats()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
"function.<br><br>Returns an object with the Player's stats. The object has the following properties:<br><br>" +
"Player.hacking<br>Player.strength<br>Player.defense<br>Player.dexterity<br>Player.agility<br>Player.charisma<br>Player.intelligence<br><br>" +
"Example: <br><br>" +
"res = getStats();<br>print('My charisma level is: ' + res.charisma);<br><br>" +
"<i><u>isBusy()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
"function.<br><br>Returns a boolean indicating whether or not the player is currently performing an 'action'. " +
"These actions include working for a company/faction, studying at a univeristy, working out at a gym, " +
"creating a program, or committing a crime.<br><br>" +
"<i><u>stopAction()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to " +
"run this function.<br><br>This function is used to end whatever 'action' the player is currently performing. The player " +
"will receive whatever money/experience/etc. he has earned from that action. The actions that can be stopped with this function " +
"are:<br><br> " +
"-Studying at a university<br>-Working for a company/faction<br>-Creating a program<br>-Committing a Crime<br><br> " +
"This function will return true if the player's action was ended. It will return false if the player was not " +
"performing an action when this function was called.<br><br>" +
"<i><u>upgradeHomeRam()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually.<br><br>" +
"This function will return true if the player's home computer RAM is successfully upgraded, and false otherwise.<br><br>" +
"<i><u>getUpgradeHomeRamCost()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"Returns the cost of upgrading the player's home computer RAM.<br><br>" +
"<i><u>workForCompany()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically set you to start working at the company at which you are employed. If you are already " +
"in the middle of some 'working' action (such as working for a faction, training at a gym, or creating a program), then " +
"running this function will automatically cancel that action and give you your earnings.<br><br>" +
"This function will return true if the player starts working, and false otherwise.<br><br>" +
"<i><u>applyToCompany(companyName, field)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically try to apply to the specified company for a position in the specified field. This " +
"function can also be used to apply for promotions by specifying the company and field you are already employed at.<br><br>" +
"The first argument must be a string with the name of the company. This argument IS CASE-SENSITIVE. The second argument must " +
"be a string representing the 'field' to which you want to apply. This second argument is NOT case-sensitive. Valid values for " +
"the second argument are:<br><br>" +
"software<br>software consultant<br>it<br>security engineer<br>network engineer<br>business<br>business consultant<br>" +
"security<br>agent<br>employee<br>part-time employee<br>waiter<br>part-time waiter<br><br>" +
"This function will return true if you successfully get a job/promotion, and false otherwise. Note " +
"that if you are trying to use this function to apply for a promotion and you don't get one, it will return false.<br><br>" +
"<i><u>getCompanyRep(companyName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will return the amount of reputation you have at the specified company. If the company passed in as " +
"an argument is invalid, -1 will be returned.<br><br>" +
"The argument passed in must be a string with the name of the company. This argument IS CASE-SENSITIVE.<br><br>" +
"<i><u>checkFactionInvitations()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"Returns an array with the name of all Factions you currently have oustanding invitations from.<br><br>" +
"<i><u>joinFaction(name)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically accept an invitation from a faction and join it.<br><br>" +
"The argument must be a string with the name of the faction. This name IS CASE-SENSITIVE.<br><br>" +
"<i><u>workForFaction(factionName, workType)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically set you to start working for the specified Faction. Obviously, you " +
"must be a member of the Faction or else this function will fail. If you are already in the middle of " +
"some 'working' action (such as working for a company, training at a gym, or creating a program), then running " +
"this function will automatically cancel that action and give you your earnings.<br><br>" +
"The first argument must be a string with the name of the faction. This argument IS CASE-SENSITIVE. The second argument " +
"must be a string with the type of work you want to perform for the faction. The valid values for this argument are:<br><br>" +
"<br>hacking/hacking contracts/hackingcontracts<br>field/fieldwork/field work<br>security/securitywork/security work<br><br>" +
"This function will return true if you successfully start working for the specified faction, and false otherwise.<br><br>" +
"<i><u>getFactionRep(factionName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function returns the amount of reputation you have for the specified Faction. The argument must be a " +
"string with the name of the Faction. The argument IS CASE-SENSITIVE.<br><br>" +
"<i><u>createProgram(programName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically set you to start working on creating the specified program. If you are already in " +
"the middle of some 'working' action (such as working for a company, training at a gym, or taking a course), then " +
"running this function will automatically cancel that action and give you your earnings.<br><br>" +
"The argument passed in must be a string designating the name of the program. This argument is NOT case-sensitive.<br><br>" +
"Example:<br><br>createProgram('relaysmtp.exe');<br><br>" +
"Note that creating a program using this function has the same hacking level requirements as it normally would. These level requirements are:<br><br>" +
"BruteSSH.exe: 50<br>FTPCrack.exe: 100<br>relaySMTP.exe: 250<br>HTTPWorm.exe: 500<br>SQLInject.exe: 750<br>" +
"DeepscanV1.exe: 75<br>DeepscanV2.exe: 400<br>ServerProfiler.exe: 75<br>AutoLink.exe: 25<br><br>" +
"This function returns true if you successfully start working on the specified program, and false otherwise.<br><br>" +
"<i><u>commitCrime(crime)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function is used to automatically attempt to commit crimes. If you are already in the middle of some 'working' " +
"action (such as working for a company or training at a gym), then running this function will automatically cancel " +
"that action and give you your earnings.<br><br>" +
"The function takes a string that specifies what crime to attempt. This argument is not case-sensitive and is fairly " +
"lenient in terms of what inputs it accepts. Here is a list of valid inputs for all of the crimes:<br><br>" +
"shoplift, rob store, mug, larceny, deal drugs, bond forgery, traffick arms, homicide, grand theft auto, " +
"kidnap, assassinate, heist<br><br> " +
"Crimes committed using this function will have all of their earnings halved (this applies for both money and experience!)<br><br>" +
"This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt " +
"the 'Rob Store' crime, so running commitCrime('rob store') will return 60). Warning: I do not recommend using the time " +
"returned from this function to try and schedule your crime attempts. Instead, I would use the isBusy() Singularity function " +
"to check whether you have finished attempting a crime. This is because although the game sets a certain crime to be X amount of seconds, " +
"there is no guarantee that your browser will follow that time limit.<br><br>" +
"<i><u>getCrimeChance(crime)</u></i><br>If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to " +
"use this function.<br><br>" +
"This function returns your chance of success at commiting the specified crime. The chance is returned as a decimal " +
"(i.e. 60% would be returned as 0.6). The argument for this function is a string. It is not case-sensitive and is fairly " +
"lenient in terms of what inputs it accepts. Check the documentation for the commitCrime() Singularity Function to see " +
"examples of valid inputs.<br><br>" +
"<i><u>getOwnedAugmentations(purchased=false)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function returns an array of the names of all Augmentations you own as strings. It takes a single optional " +
"boolean argument that specifies whether the returned array should include Augmentations you have purchased " +
"but not yet installed. If it is true, then the returned array will include these Augmentations. By default, " +
"this argument is false.<br><br>" +
"<i><u>getAugmentationsFromFaction(facName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"Returns an array containing the names (as strings) of all Augmentations that are available from the specified faction. " +
"The argument must be a string with the faction's name. This argument is case-sensitive.<br><br>" +
"<i><u>getAugmentationCost(augName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function returns an array with two elements that gives the cost for the specified Augmentation" +
". The first element in the returned array is the reputation requirement of the Augmentation, and the second element " +
"is the money cost.<br><br>" +
"The argument passed in must be a string with the name of the Augmentation. This argument IS CASE-SENSITIVE. " +
"If an invalid Augmentation name is passed in, this function will return the array [-1, -1].<br><br>" +
"<i><u>purchaseAugmentation(factionName, augName)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function will try to purchase the specified Augmentation through the given Faction.<br><br>" +
"The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.<br><br>" +
"This function will return true if the Augmentation is successfully purchased, and false otherwise.<br><br>" +
"<i><u>installAugmentations(cbScript)</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
"This function will automatically install your Augmentations, resetting the game as usual.<br><br>" +
"It will return true if successful, and false otherwise.<br><br>" +
"This function takes a single optional parameter that specifies a callback script. This is " +
"a script that will automatically be run after Augmentations are installed (after the reset). " +
"This script will be run with no arguments and 1 thread. It must be located on your home computer. This argument, if used, " +
"must be a string with the name of the script.",
TutorialNetscriptText: "Netscript is a programming language implemented for this game. There are two versions of Netscript: " +
"Netscript 1.0 and Netscript 2.0 (NetscriptJS).<br><br>" +
"<a href='https://bitburner.readthedocs.io/en/latest/index.html' target='_blank'>Click here for Bitburner's official Netscript documentation</a>",
TutorialTravelingText:"There are six major cities in the world that you are able to travel to: <br><br> " +
" Aevum<br>" +
" Chongqing<br>" +
@ -1140,10 +484,16 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.37.0<br>" +
"* NetscriptJS (Netscript 2.0) released<br>" +
"* Running the game with the '?noScripts' query will start the game without loading any of your scripts. " +
"This should be used if you accidentally write a script that crashes your game<br>"
"v0.37.1<br>" +
"* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based " +
"on the difficulty of the contract.<br>" +
"* Completing Field Analysis in Bladeburner now grants 0.1 rank<br>" +
"* The maximum RAM you can get on a purchased server is now 1,048,576GB (2^20)<br>" +
"* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS<br>" +
"* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS<br>" +
"* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to<br>" +
"* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.<br>" +
"* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms<br>"
}
export {CONSTANTS};

@ -18,6 +18,7 @@ import {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
determineCrimeChanceHeist} from "./Crimes.js";
import {Bladeburner} from "./Bladeburner.js";
import {Companies, Company, CompanyPosition,
CompanyPositions, companyExists} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
@ -66,13 +67,15 @@ import {yesNoBoxClose, yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxCreate,
yesNoBoxOpen} from "../utils/YesNoBox.js";
var hasCorporationSF=false, //Source-File 3
hasSingularitySF=false, //Source-File 4
hasAISF=false, //Source-File 5
hasBladeburnerSF=false, //Source-File 6
hasWallStreetSF=false, //Source-File 8
hasBn11SF=false; //Source-File 11
var hasCorporationSF = false, //Source-File 3
hasSingularitySF = false, //Source-File 4
hasAISF = false, //Source-File 5
hasBladeburnerSF = false, //Source-File 6
hasBladeburner2079SF = false, //Source-File 7
hasWallStreetSF = false, //Source-File 8
hasBn11SF = false; //Source-File 11
var singularitySFLvl=1, wallStreetSFLvl=1;
var possibleLogs = {
ALL: true,
@ -124,31 +127,22 @@ var possibleLogs = {
sellShort: true,
}
var singularitySFLvl=1, wallStreetSFLvl=1;
//Used to check and set flags for every Source File, despite the name of the function
function initSingularitySFFlags() {
for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n === 3) {
hasCorporationSF = true;
}
if (Player.sourceFiles[i].n === 3) {hasCorporationSF = true;}
if (Player.sourceFiles[i].n === 4) {
hasSingularitySF = true;
singularitySFLvl = Player.sourceFiles[i].lvl;
}
if (Player.sourceFiles[i].n === 5) {
hasAISF = true;
}
if (Player.sourceFiles[i].n === 6) {
hasBladeburnerSF = true;
}
if (Player.sourceFiles[i].n === 5) {hasAISF = true;}
if (Player.sourceFiles[i].n === 6) {hasBladeburnerSF = true;}
if (Player.sourceFiles[i].n === 7) {hasBladeburner2079SF = true;}
if (Player.sourceFiles[i].n === 8) {
hasWallStreetSF = true;
wallStreetSFLvl = Player.sourceFiles[i].lvl;
}
if (Player.sourceFiles[i].n === 11) {
hasBn11SF = true;
}
if (Player.sourceFiles[i].n === 11) {hasBn11SF = true;}
}
}
@ -234,7 +228,7 @@ function NetscriptFunctions(workerScript) {
var rand = Math.random();
var expGainedOnSuccess = scriptCalculateExpGain(server) * threads;
var expGainedOnFailure = (expGainedOnSuccess / 4);
if (rand < hackChance) { //Success!
if (rand < hackChance) { //Success!
var moneyGained = scriptCalculatePercentMoneyHacked(server);
moneyGained = Math.floor(server.moneyAvailable * moneyGained) * threads;
@ -1700,7 +1694,12 @@ function NetscriptFunctions(workerScript) {
ram = Math.round(ram);
if (isNaN(ram) || !powerOfTwo(ram)) {
workerScript.scriptRef.log("Error: Invalid ram argument passed to purchaseServer(). Must be numeric and a power of 2");
workerScript.scriptRef.log("Error: purchaseServer() failed due to invalid ram argument. Must be numeric and a power of 2");
return "";
}
if (ram > CONSTANTS.PurchasedServerMaxRam) {
workerScript.scriptRef.log("Error: purchasedServer() failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB");
return "";
}
@ -1747,17 +1746,23 @@ function NetscriptFunctions(workerScript) {
return false;
}
if (!server.purchasedByPlayer || server.hostname == "home") {
if (!server.purchasedByPlayer || server.hostname === "home") {
workerScript.scriptRef.log("Error: Server " + server.hostname + " is not a purchased server. " +
"Cannot be deleted. deleteServer failed");
"Cannot be deleted. deleteServer() failed");
return false;
}
var ip = server.ip;
//Can't delete server you're currently connected to
if (server.isConnectedTo) {
workerScript.scriptRef.log("Error: deleteServer() failed because you are currently connected to the server you are trying to delete");
return false;
}
//A server cannot delete itself
if (ip == workerScript.serverIp) {
workerScript.scriptRef.log("Error: Cannot call deleteServer() on self. Function failed");
if (ip === workerScript.serverIp) {
workerScript.scriptRef.log("Error: Cannot call deleteServer() on self. deleteServer() failed");
return false;
}
@ -2382,8 +2387,8 @@ function NetscriptFunctions(workerScript) {
return false;
}
Player.location = Locations.AevumCrushFitnessGym;
costMult = 2;
expMult = 1.5;
costMult = 3;
expMult = 2;
break;
case Locations.AevumSnapFitnessGym.toLowerCase():
if (Player.city != Locations.Aevum) {
@ -2391,8 +2396,8 @@ function NetscriptFunctions(workerScript) {
return false;
}
Player.location = Locations.AevumSnapFitnessGym;
costMult = 6;
expMult = 4;
costMult = 10;
expMult = 5;
break;
case Locations.Sector12IronGym.toLowerCase():
if (Player.city != Locations.Sector12) {
@ -2409,8 +2414,8 @@ function NetscriptFunctions(workerScript) {
return false;
}
Player.location = Locations.Sector12PowerhouseGym;
costMult = 10;
expMult = 7.5;
costMult = 20;
expMult = 10;
break;
case Locations.VolhavenMilleniumFitnessGym:
if (Player.city != Locations.Volhaven) {
@ -2418,8 +2423,8 @@ function NetscriptFunctions(workerScript) {
return false;
}
Player.location = Locations.VolhavenMilleniumFitnessGym;
costMult = 3;
expMult = 2.5;
costMult = 7;
expMult = 4;
break;
default:
workerScript.scriptRef.log("Invalid gym name: " + gymName + ". gymWorkout() failed");
@ -3657,9 +3662,167 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
installAugmentations(cbScript);
return true;
},
//Bladeburner API
bladeburner : {
isContractName : function(name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isOperationName : function(name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isBlackOpName : function(name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isGeneralActionName : function(name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isSkillName : function(name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
startAction : function(type, name) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
stopAction : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getActionTime : function(type="", name="") {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getActionEstimatedSuccessChance : function(type="", name="") {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getActionCountRemaining : function(type="", name="") {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getRank : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getSkillPoints : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getSkillLevel : function(skillName="") {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
upgradeSkill : function(skillName) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getTeamSize : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
setTeamSize : function(type="", name="", size) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getCityEstimatedPopulation : function(cityName) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getCityEstimatedCommunities : function(cityName) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getCityChaos : function(cityName) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
switchCity : function(cityName) {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getStamina : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
joinFaction : function() {
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
}
}
}
}
} //End return
} //End NetscriptFunction()
export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF,
hasWallStreetSF, wallStreetSFLvl, hasCorporationSF, hasAISF, hasBladeburnerSF};

@ -345,7 +345,6 @@ Script.prototype.saveScript = function() {
//Calculate/update ram usage, execution time, etc.
this.updateRamUsage();
console.log(this.module);
this.module = "";
}
@ -539,6 +538,10 @@ function parseOnlyCalculateDeps(code, currentModule) {
node.consequent && walkDeeper(node.consequent, st);
node.alternate && walkDeeper(node.alternate, st);
},
MemberExpression: (node, st, walkDeeper) => {
node.object && walkDeeper(node.object, st);
node.property && walkDeeper(node.property, st);
},
}
}

@ -1411,12 +1411,7 @@ let Engine = {
Engine.Clickables.tutorialNetscriptButton = document.getElementById("tutorial-netscript-link");
Engine.Clickables.tutorialNetscriptButton.addEventListener("click", function() {
if (Player.bitNodeN === 4 || hasSingularitySF) {
Engine.displayTutorialPage(CONSTANTS.TutorialNetscriptText + CONSTANTS.TutorialSingularityFunctionsText);
} else {
Engine.displayTutorialPage(CONSTANTS.TutorialNetscriptText);
}
Engine.displayTutorialPage(CONSTANTS.TutorialNetscriptText);
});
Engine.Clickables.tutorialTravelingButton = document.getElementById("tutorial-traveling-link");