Skip to content

RobynLlama/FFU--Beyond-Reach

Repository files navigation

Description

Important

This is a fork of Warstalker's FFU Beyond Reach. The original can be found HERE This fork aims to remove a few non-vanilla friendly assumptions that were made about the mod loading process to ensure compatibility with Ostra.Autoloader for delivery via the Thunderstore. If you are manually installing all your mods, feel free to use the original instead!

Fight for Universe: Beyond Reach is modification for Ostranauts, which expands modding capabilities of the original game, makes modding API more flexible and resolves some issues related to having multiple mods. It relies on BepInEx and MonoMod Patch Loader.

Ostranauts Steam Page: https://store.steampowered.com/app/1022980/Ostranauts/
Ostranauts Discord Server: https://discord.gg/bluebottlegames (#modding-discussion channel)

Installation Instructions

1. Download BepInEx v5.4.23.2 WINx64: https://github.com/BepInEx/BepInEx/releases/tag/v5.4.23.2
2. Unzip all contents into Ostranauts root folder. It should contain now BepInEx, winhttp.dll & etc.
3. Download MonoMod Loader: https://github.com/BepInEx/BepInEx.MonoMod.Loader/releases/tag/v1.0.0.0
4. Unzip all contents into Ostranauts root folder. Ostranauts/BepInEx/core should now contain MonoMod.dll.
5. Download all mod's DLL files from releases (or compile them) and put them into Ostranauts/BepInEx/monomod.
6. Launch game, once in the main menu, exit, modify config files as you want. Enjoy playing/modding.

Installation Components

Assembly-CSharp.FFU_BR.mm.dll - contains core FFU features, configurations and improved modding API itself.
Assembly-CSharp.FFU_BR_Console.mm.dll - contains all the commands listed in the Improved Console Commands.
Assembly-CSharp.FFU_BR_Extended.mm.dll - contains all the features listed in the New Parameters & Properties.
Assembly-CSharp.FFU_BR_Fixes.mm.dll - contains various fixes (such as working IsPowerObservable with sub-COs).
Assembly-CSharp.FFU_BR_Quality.mm.dll - contains various QoL improvements listed in the Quality Settings.
Assembly-CSharp.FFU_BR_Super.mm.dll - contains Superiority Settings that can make game easier or harder.

Error Reporting Instructions

1. If you already enabled settings previously, you can ignore steps 2 and 3, and start from step 4 right away.
2. Go to Ostranauts/BepInEx/config and open BepInEx.cfg with text editor (Notepad++ for example).
3. Find [Logging.Disk] and set WriteUnityLog to truein order to force BepInEx to log all the information.
4. Start game, repeat actions that resulted in error, close game. Upload Ostranauts/BepInEx/LogOutput.log.

Modding Features

1. Custom synchronized core + mods loading execution flow that resolves data mangling issue.
2. Partial data overwrite of existing entries (from any JSON file, whether it is core or other mod).
3. Reference-based creation of new entries with applied values. No need to copy whole code block.
4. Removal of specific data entries based on their IDs ('strName' parameter) via mod_info.json.
5. Precision array modification via --ADD--, --INS--, --DEL-- and --MOD-- (data only) commands.
6. Dynamic changes mapping and dynamic data modification (for existing templates and saved games).
7. Completely new parameters and properties that expand existing different gameplay mechanics.
8. Option to unlock max random range value that allows unrestricted random/loot lists.
9. Other various options and settings to alter gameplay and/or make it easier/harder.

Note: in-depth explanation and API examples can be viewed below, in relevant paragraph.

Configuration Options

Settings file can be found at \Ostranauts\BepInEx\config\FFU_Beyond_Reach.cfg (it is created after running Ostranauts for the first time with this mod installed).

Configuration Settings

SyncLogging - defines what logging type is used for when overwriting data and/or copy-referencing existing items into new items with various parameters overwriting.
ActLogging - defines what activity will be shown in the log during specific actions. Applies only to very specific action that related to modified game code (such as inventory sorting).
DynamicRandomRange - By default loot random range is limited to 1.0f, thus preventing use of loot tables, if total sum of their chances goes beyond 1.0f. This feature allows to increase max possible random range beyond 1.0f, to the total sum of all chances in the loot table.
MaxLogTextSize - Defines the max length of the text in the console. Needed in case if you want to see the whole list of entries from the console commands without missing anything (whether it is getcond or any other command). May impact performance, if the value is too big.
ModSyncLoading - Enables smart loading of modified COs and synchronizing of existing CO saved data with updated CO templates, if they are mapped in the mod info file. Frees the user from the need of manually updating existing save file and existing ship templates, if Parent CO's got new (or modified existing) built-in locked COs.

Gameplay Settings

ModifyUpperLimit - Enables use of BonusUpperLimit to change skill and trait modifier upper limit value.
BonusUpperLimit - Defines the upper limit for skill and trait modifier bonuses. Original value is 10.
SuitOxygenNotify - Specifies the oxygen level threshold (as a percentage) for the gauge of a sealed/airtight suit. When the oxygen level falls below this threshold, the wearer will receive a notification (via occasional beeps) about oxygen usage. If set to 0, no notification will be given at any time.
SuitPowerNotify - Specifies the power level threshold (as a percentage) for the gauge of a sealed/airtight suit. When the power level falls below this threshold, the wearer will receive a notification (via frequent beeps) about power usage. If set to 0, no notification will be given at any time.
ShowEachO2Battery - Defines whether to show average percentage across all O2/Batteries or calculate each O2/Battery independently and summarize their percentages. Affects how soon notifications will begin.
StrictInvSorting - Defines if game will be using custom, order-based inventory windows sorting that enforces strict UI rendering order. Relevant if slots have sOrder parameter set. Defaults to nDepth otherwise.

Quality Settings

AltTempEnabled - Allows to show temperature in alternative measure beside Kelvin value (in top right info window), similar to how gas shows mass and pressure. Uses formula: AltTemp = K x Mult + Shift.
AltTempSymbol - Defines what symbol will represent alternative temperature measure.
AltTempMult - Defines alternative temperature multiplier for conversion from Kelvin.
AltTempShift - Defines alternative temperature value shift for conversion from Kelvin.
TowBraceAllowsKeep - Defines if it is allowed to use station keeping command, while tow braced to another vessel. As you remember, even when tow braced to another ship, you can only control ship manually, but 'Station Keeping' command is getting turned off. This option resolves this issue.
OrgInventoryMode - Enables inventory UI tweaking mode that allows to adjust inventory window offsets, where they open, what range between them and what is the size of padding between sub-windows.
OrgInventoryTweaks - Defines various offsets that adjust inventory UI. Allows float values. Required values: Base, Top, Bottom, Padding, Grid, Safety. Base - horizontal offset between inventory equipment window and leftmost side of the screen. Top - horizontal offset from topmost inventory window to top of the screen. Bottom - horizontal cutout offset, below which inventory window will be shown in next column, required to balance the 'top' offset. Padding - padding between inventory window columns. Grid - inventory windows column auto-adjustment width for each additional horizontal inventory grid tile, only relevant when inventory width is above 4 grid tiles. Safety - is safety multiplier for inventory window height. If its too big inventory window might overflow to the next column, despite having enough space in the current. If its too small, inventory window might overflow below intended height limit in the same column. If you see that inventory windows overflow one way or another, enable ActLogging and try various Safety and Bottom values. If there are less than 6 values, parameter is ignored and default values loaded instead.
BetterInvTransfer - Changes behavior of shift-click item transferring in inventory. Items will be auto-transferred to the last inventory window, where player has placed the item manually. Last inventory window is forgotten, when inventory is closed - thus the exploit of long-distance transferring is avoided.
QuickBarPinning - Allows to permanently lock the interactions quick bar, where you desire on the screen.
QuickBarTweaks - Defines various offsets that adjust interactions quick bar position and mode. Required values: Horizontal, Vertical, Expanded. Horizontal - defines horizontal position offset for the interactions quick bar. Vertical - defines vertical position offset for the interactions quick bar. Expanded - defines if interactions quick bar is always expanded or not (only 1 is treated as true, any other number is treated as false).

Superiority Settings

NoSkillTraitCost - Option to allow learn/unlearn any trait or skill for free.
AllowSuperChars - Option to allow character to be superior or utterly miserable.
SuperCharMultiplier - Set above 1.0 to reach the stars, or below 1.0 to descent into abyss.
SuperCharacters - List of character names in lower case that you want to apply multiplier to.

New Parameters & Properties

strReference - condowners parameter that allows to create reference-based copy of the existing CO, whilst overriding only specific parameters. Note: will inherit all properties of the original CO.

strInvSlotEffect - condowners parameter that applies slot effect to every inventory item and/or the inventory owner. Works pretty much same way as other slot effects, except parameters mapMeshTextures, strSlotImage and strSlotImageUnder are ignored. Thread carefully, as it applies effect to every item, including whole stacks.

nSlotOrder - slots parameter that only used, if StrictInvSorting gameplay setting is enabled. Requires an integer value, but can be nulled. If nulled, defaults to nDepth to avoid potential issues. Slots with lesser numbers are rendered first in open inventory UI. Was implemented to avoid nDepth collision/issues.

nMaxDepth - condtrigs parameter that used to check how deeply nested condowners object. If object is nested at depth greater than maxDepth parameter, then condition trigger automatically returns false. Use console command getcond [them] *coParents on selected object and count number of in's to identify its current depth.

strMathCond - condtrigs parameter that is used to compare value of a specific condition with a specific number. In addition, requires defined nMathOp and fMathVal parameters to work. Supports number of different operations.

nMathOp - condtrigs parameter that defines the math operation that will be used when comparing condition's value (from strMathCond) with a fMathVal parameter value. 1 → Not Equal (!=), 2 → Equal (==), 3 → Greater Than (>), 4 → Greater or Equal (>=), 5 → Less Than (<), 6 → Less or Equal (<=). Formula: CT.Value #OP# fMathVal.

fMathVal - condtrigs parameter that defines the value, which will be used for mathematical comparison. If fMathVal isn't set, default value of 0 will be used. Whilst you can put negative value in fMathVal parameter, it is irrelevant, since condition values can't be below zero.

strMultCond - condtrigs parameter that is used to perform various logical operations between value of strMultCond condition and multiple values (or their fractions) of other conditions. In addition, requires defined aMultOps parameter to work, otherwise it will be ignored. Behavior of the parameter greatly depends on bAND value. If bAND is set to true, the strMultCond will only trigger, if ALL conditions listed in the aMultOps are met. If bAND is set to false, the strMultCond will trigger as long as at least ONE of the conditions listed in the aMultOps was met.

aMultOps - condtrigs parameter that defines operations with conditions that strMultCond will perform. Each valid entry requires 3 different values in array: "COND_NAME","MATH_OP","MATH_MULT" (for MATH_OP list refer to the nMathOp parameter). As long as aMultOps structure is defined correctly, amount of possible entries has no limit - only potential performance impact. For example, "aMultOps": ["StatDamageMax", "3", "0.2", "StatDamageMax", "5", "0.7"] will return true, if value of the strMultCond condition is above 20% and below 70% value of the StatDamageMax condition. Using null instead of "COND_NAME" in the aMultOps will treat "MATH_MULT" as value and not as multiplier, thus making strMultCond behave like strMathCond that allows multiple logic conditions (i.e. "aMultOps": [null, "3", "12.5", null, "5", "27.5"]).

nIsSameShipCO - shipspecs parameter that allows to find a ship, where object itself is placed. Should be a quite optimized option for interactions that allows to access all other COs within confines of same ship via ShipTest3rd and CTTest3rd parameters without much hassle.

bForceVerbose - interactions parameter that forces interaction to be verbose even during failed attempts. Exists only so other mod developers can debug where interactions fail and where they successfully execute. If ActLogging in options is set to Interactions, everything also will be written into log files. Do note, that if nLogging is set to 0, no information will be written to logs, except interaction failures.

bRoomLookup - interactions parameter that allows object to identify its room and send message to all the crewmembers in it, if interaction's nLogging parameter is set to 2. Required, because by default CO don't contain current room information and it is only assigned via CrewSim (i.e. only to crewmember COs).

New Hardcoded Conditions

StatEmittedTemp - simple condition value that allow to override StatSolidTemp without changing it. When set, temperature emitted from object via Heater.Heat() will be based on it instead of StatSolidTemp parameter.

Existing Functionality Changes

Sensor - aUpdateCommands command. By default it can only execute interactions based on the room conditions. Modification allows to run it condition triggers against itself, if strPoint is set to null. In addition, if dictGUIPropMap that it uses, contains dfUpdateInterval entry - it replaces default 1.0 (value is in seconds) update interval with a new value as long as its greater than 0.0. Note: it relies on Unity's internal Update() method, so if update interval is set to a too small value (i.e. too short), it just won't be able to keep up with correct timing.

Improved Console Commands

getcond [them] * - now getcond command supports wildcard * that lists all stats, regardless of their name.
getcond [them]-NUM - tells getcond to fetch data recursively from parent that is NUM above targeted object.
getcond [them] *coParents - lists all condowners parent object recursively and how they are nested.
getcond [them] *coRules - lists all condrules (with stat-related information) attached the targeted object.
getcond [them] *coTickers - lists all tickers (plus related timer information) attached the targeted object.
openinventory - opens debug inventory (with ground window) from the perspective of the selected target.
repairship - too lazy to repair ship or ship is too big for proper repairing? This command will do the repairs.
findcondcos <conditions> - lists all CO template with corresponding condition. Supports any amount of conditions via IsCondition or/and via inverse !IsCondition. All conditions must be separated by space.
triggerinfo <condtrigger> <mode> - prints all rules of a condition trigger as text. Depending on mode, text will be printed as raw JSON values (mode 0) or as friendly text you see in the game (mode 1).
triggertest <condtrigger> <condowner> - fires condition trigger against template or selected object and logs outcome. Works only if game was loaded. Supports [them] (selected object) and ItmCondownerName (template).

Elastic Mod Data Handling

Extension to the original modding API that allows precise modification of individual parameters in specific items without need to overwrite JSON data block. To be precise, it allows:
* Simplified Data Overwrite - frees from need to copy entire data block just to modify single parameter.
* Reference-based Creation - allows to copy entire original data block with only specific parameters modified.
* Precision Array Modification - set of commands to precisely modify original contents of array in a safe manner.
* Precision Dictionary Modifications - set of commands to precisely manipulate dictionaries in same safe manner.

Existing Entities Removal

Whilst modding API already implements exclusion based on folder paths, it removes whole files with data and not individual items. Existing entities removal allows to remove specific items based on their type and their exact identifier. For example, by adding the JSON block "removeIds": {"cooverlays": ["OutfitEVA03", "OutfitEVA03Off", "OutfitEVA03Dmg"]} into mod_info.json will make Data Handler remove specified identifiers from cooverlays and free them for full implementation as complete condition owners for example. This routine runs before JSON objects are processed, thus prevents identifiers pollution.

Dynamic Changes Mapping

Modification or removal of some items, might require lots of manual patching for existing ship templates and potentially starting new game (or at least pruning existing entities). In order to avoid it, features that allow objects mapping and removal were implemented. Configurable via mod_info.json file only.

Dynamic Changes Map Commands

Slotted Items Mapping: Switch_Slotted command that allows to remap existing slotted sub-items into other items in the list. By using code such as this "changesMap": {"OutfitEVA01": {"Switch_Slotted" : ["PocketClipPoint01= PocketEVAClipPoint01"]}, on game or template load, all slotted PocketClipPoint01 will be converted into the PocketEVAClipPoint01 for all OutfitEVA01 items. The Switch_Slotted can contain multiple entries.

Recover Missing Sub-Items: Recover_Missing command allows to recover missing sub-items based on the assigned loot table of the item itself. By using code "changesMap": {"OutfitEVA01": {"Recover_Missing" : []} game will attempt to recover all bSlotLocked sub-items for the item itself, if they are list in the assigned loot table of the item. Specifying name of sub-items in the list will make game re-add items, even if they aren't bSlotLocked as long as they are in the assigned loot table. In addition, this command also supports inverted mode !Recover_Missing: [] - it will attempt to recover all bSlotLocked sub-items based on the loot table, if they aren't listed in the command.

Saved COs Conditions Sync: Sync_Conditions command allows to add missing conditions to already existing COs if they are present in their template counterparts. By using code "changesMap": {"OutfitEVA01": {"Sync_Conditions": []}} game will add missing conditions from the template to the existing saved OutfitEVA01 CO. If you intend only to add specific missing conditions that exist in template, listing them as ["IsNewCond", "StatNewCond"] will make game add only them, if they aren't present in saved CO. This command also supports inverted "!Sync_Conditions": [] mode, in which only non-listed conditions are added to the saved CO from the template.

Saved COs Conditions Update: Update_Conditions command allows to update existing condition in the saved CO with the values from the template CO. By using code "changesMap": {"OutfitEVA01": {"Update_Conditions": []}} game will fetch all existing condition values from CO templates and overwrite them in the saved COs. Do note that such approach is extremely dangerous, as some conditions are dynamic and changing them in such way might break game logic (or game itself). Use precise approach "Update_Conditions": ["StatBasePrice", "StatDamageMax"] to update only conditions you know that are static. This command also supports "!Update_Conditions": [] inverted mode that will update all existing conditions values, except ones that are listed in the command.

Sync Slotted Conditions: Sync_Slot_Effects command allows to enforce specific conditions to the items that are slotted in targeted COs. By using "changesMap": {"OutfitEVA01": {"Sync_Slot_Effects": ["IsSlotted=1.0x1"]}} all COs that are slotted into OutfitEVA01 will receive IsSlotted condition. If you intention is to apply effect only to specific sub-items, you need to use "Sync_Slot_Effects": ["IsSlotted=1.0x1|ItemName1|ItemName2"] and it will apply the condition only specific items types, if they are slotted. In addition, this feature supports inverted mode via ! symbol in entries. Code "Sync_Slot_Effects": ["!IsSlotted"] will remove specified condition from slotted sub-items and "Sync_Slot_Effects": ["!IsSlotted|ItemName3"] will remove it only from specific item types. It should be only used, when you're certain that these conditions are assigned and/or removed to/from the slotted sub-items naturally, when you slot them into target item, since it ignores all the trigger validations and checks.

Sync Inventory Conditions: Sync_Inv_Effects command allows to enforce specific conditions to the items that are stored in targeted COs. By using "changesMap": {"OutfitEVA01": {"Sync_Inv_Effects": ["IsStored=1.0x1"]}} all COs that are stored in the OutfitEVA01 will receive IsStored condition. If you intention is to apply effect only to specific items in the inventory, you need to use "Sync_Inv_Effects": ["IsStored=1.0x1|ItemName1|ItemName2"] and it will apply the condition only specific items types. In addition, this feature supports inverted mode via ! symbol in entries. Code "Sync_Inv_Effects": ["!IsStored"] will remove specified condition from all the stored items and "Sync_Inv_Effects": ["!IsStored|ItemName3"] will remove it only from specific item types. It should be only used, when you're certain that these conditions are assigned and/or removed to/from the stored items naturally, when you put them into item's attached inventory, since it ignores all the trigger validations and checks.

Dynamic Changes Map Syntax

Since all parameters in changesMap are additive, option to remove various entries and sub-entries was implemented. To remove specific sub-entry, use code "changesMap": {"OutfitEVA01": {"CommandName": ["~"]}} and to remove entire entry use code "changesMap": {"OutfitEVA01": {"~": []}}. In addition, if you're using {"~": [], "Command" : []} it pretty much wipes previous mapped changes for that CO, whist filling with your mapped data only (of course - depending on mod order and what loads after your mod). Individual command entries can be modified as well. Using "Switch_Slotted" : ["*Pocket01=NewPocket02"] will modify existing entry to have NewPocket02 instead whatever there was before. Using "Switch_Slotted" : ["-Pocket01"] will remove it instead. Do note that the changesMap is modified in the order of loaded mods, thus you need pay utmost attention to it.

If the SyncLogging is set to ModdedDump or above, the final/compiled changesMap will be shown in the logs.

Modding API Examples

A various JSON examples that demonstrate usage of extended modding API features in different ways.

Removal of Existing Entries Example

{
    "strName": "Your Mod Name",
    //...vaious mod parameters...//
    "removeIds": {
        "cooverlays": [
            "OutfitHelmet05",
            "OutfitHelmet05Dmg",
            "OutfitEVA05",
            "OutfitEVA05Off",
            "OutfitEVA05Dmg"
        ]
    }
}

In this example all cooverlays for Bingham-12C EVA Suit and Helmet will be completely removed from the game, in order to give space to proper condowners in the mod.

Dynamic Changes Map Example

{
    "strName": "Your Mod Name",
    //...vaious mod parameters...//
    "changesMap": {
        "OutfitEVA01": {
            "Switch_Slotted": ["PocketClipPoint01=PocketEVAClipPoint01"],
            "Recover_Missing": [],
            "Sync_Conditions": ["StatArmorCut", "StatArmorBlunt"],
            "!Update_Conditions": ["StatMass"],
            "Sync_Slot_Effects": ["IsModified=1.0x1|PocketEVABatt01"],
            "Sync_Inv_Effects": ["!IsUnsableItem"]
        },
        "OutfitEVA03": {
            "Switch_Slotted": ["~"],
            "Recover_Missing": ["PocketEVAO201"],
            "!Sync_Conditions": ["TestCondition"],
            "Sync_Slot_Effects": ["-IsSpecial"]
        },
        "OutfitEVA05": {
            "~": []
        }
    }
}

In this example in saved game or template, all OutfitEVA01 slotted PocketClipPoint01 COs with be replaced with PocketEVAClipPoint01 COs. All missing locked COs will be restored and re-attached to OutfitEVA01. If the CO OutfitEVA01 is missing StatArmorCut or/and StatArmorBlunt conditions, they will be added to it. In addition, all condition values except StatMass will be fetched from original template and added to the OutfitEVA01 CO. Anything that is slotted in the OutfitEVA01 slots will receive IsModified condition. And everything that is stored in the inventory attached to OutfitEVA01 will lose IsUnsableItem condition.

For the OutfitEVA03 CO, the command Switch_Slotted will be removed. The Recover_Missing command will only restore slotted PocketEVAO201, if it is present in the attached loot table. The Sync_Conditions command will add all missing conditions (except TestCondition) from the template to OutfitEVA03 CO. And the Sync_Slot_Effects command no longer will add IsSpecial to items that are slotted in the OutfitEVA03 CO.

The OutfitEVA05 will be completely removed from the changesMap, regardless of what it had previously.

Simplified Data Overwrite Example

{
    "strName": "ItmRackUnder01",
    "strContainerCT": "TIsFitContainerSolidCargoBay",
    "nContainerHeight": 6,
    "nContainerWidth": 6
}

As in example above, you no longer need to copy entire ItmRackUnder01 code block, just to alter a few lines of parameters. Writing valid strName (and using relevant folder) is enough to identify which entry you want to change.

Reference-based Creation Example

{
    "strName": "OutfitEVA05",
    "strReference": "OutfitEVA01",
    "strNameFriendly": "Bingham-12 Civilian EVA Suit",
    "strItemDef": "OutfitEVA05",
    "strPortraitImg": "CrewSuit05",
    "mapSlotEffects": [
        "shirt_out", "BodyEVA05",
        "heldL", "HeldItmDefaultSoftL",
        "heldR", "HeldItmDefaultSoftR"
    ],
    "jsonPI": "EVASuit05"
}

In this example as well, you no longer need to copy entire block just to create one. When creating new entry, it is enough to choose valid strReference (strName of some other entry) and loader will create exact same copy of the entry, but with new strName of your choice. Any additional parameters will be used to overwrite existing copied parameters of the new entry.

Precision Dictionary Modifications

Some of the Ostranauts data is stored as dictionaries. In order to precisely modify it, a set modding API handling mechanisms was implemented. In addition, modding API supports indefinite amount of nested dictionaries, as long as dictionaries themselves are supported by the data architecture of the game itself.

There are 3 methods of modifying dictionary records:
"KeyName": {//...DATA...//} adds new or modifies existing record entry with the new data.
"*KeyName": {//...DATA...//} removes all old data in the record and replaces it with the new data.
"~KeyName": {//...DATA...//} completely removes all data along with the record from the dictionary.

{
    "strName": "Robot",
    "mapIAHist2": {
        "~StatSecurity": {},
        "*StatSelfRespect": {
            "strCondName": "StatSelfRespect",
            "mapInteractions": {
                "SeekKOAllow": {
                    "strName": "SeekKOAllow",
                    "nIterations": 41,
                    "fTotalValue": 2461.0
                }
            }
        },
        "StatSolidTemp": {
            "mapInteractions": {
                "ACTExcerciseTreadmillDo": {
                    "strName": "ACTExcerciseTreadmillDo",
                    "nIterations": 276,
                    "fTotalValue": 20.42594
                },
                "ACTExcerciseTreadmillDoHot": {
                    "strName": "ACTExcerciseTreadmillDoHot",
                    "nIterations": 242,
                    "fTotalValue": 9.623437
                },
                "~ACTExcerciseStrengthTrainerDo": {},
                "*ACTExcerciseStrengthTrainerDoHot": {
                    "strName": "ACTExcerciseStrengthTrainerDoHot",
                    "nIterations": 555
                },
                "ACTSomethingUnexpected": {
                    "strName": "ACTSomethingUnexpected",
                    "nIterations": 777,
                    "fTotalValue": 77
                }
            }
        }
    }
}

The best example of usage for this modding API is ai_training data. In example above, record StatSecurity is completely removed, record StatSelfRespect has all its data replaced with completely new data in the example, two records ACTExcerciseTreadmillDo and ACTExcerciseTreadmillDoHot are updated with new data, the record ACTExcerciseStrengthTrainerDo is removed as well, record ACTExcerciseStrengthTrainerDoHot also has its data completely discarded and replaced with new data, and completely new record ACTSomethingUnexpected is added to the dictionary. As you can see in example, it allows to operate at various sub-levels without an issue.

Precision Array Modifications

Since Ostranauts is extremely data-drive game, lots of various parameters and flags are stored in various arrays and sub-arrays. Modified modding/loading API supports precise modifications of such arrays and sub-arrays. If you found yourself in need of modifying such arrays: here be dragons, thus, abandon all hope, ye who enter here.

Arrays and sub-arrays can be of two types. Data arrays and simple arrays. Data array contain in each entry "name=value" and simple arrays arrays don't contain = symbol, but just string as whole, i.e. "BodyEVA05".

There are 4 commands to perform such modifications:
--MOD-- modifies existing entry based on 'name' (for data arrays only), without losing existing data.
--DEL-- removes existing entry based on 'name' (for data arrays) or on whole string (for simple arrays).
--ADD-- just adds the entry to the existing data as is, doesn't care about array type.
--INS-- inserts the entry at designated index, shifting whatever was at this index forward.

Note: make sure that precisely modified arrays start from any command. Otherwise, they will be copied as is and you're pretty much asking for a trouble. Same applies to sub-arrays, except first goes number of modifier row in the array - loader can't do anything with row number, but without command and will tell you about it.

Precision Array Modification Example

{
    "aNormalArray": [
        "--MOD--",
        "StatBasePrice=1.0x9000.0",
        "--DEL--",
        "IsBingham=",
        "--ADD--",
        "StatDismantleProgressMax=1.0x180"
        "--INS--4",
        "StatSpecial=1.0x60"
    ]
}

In example above existing array aNormalArray was modified in the following way: the StatBasePrice was changed to 1.0x9000.0, IsBingham was removed from the list disregarding the value, the parameter StatDismantleProgressMax=1.0x180 was added as is to the list and the parameter StatSpecial=1.0x60 was inserted at the place of 4th entry in the array and whatever was there initially shifted forward.

Precision Sub-Array Modification Example

{
    "aNestedSubArray": [
        "5|--ADD--|IsClumsy=0.0675x1.0|IsStupid=9000x1.0|--MOD--|IsBrave=0.5675x1.0|--DEL--|IsCraven",
        "13|--ADD--|IsMagic=9000x1.0|IsFriendship=9000x1.0|IsHeresy=9000x1.0|--INS--4|IsGood=1.0x60"
    ]
}

Sub-array is essentially array within array, but with different separator (| in that case). First you write index of the row you intend to override (1st row is 1, 8th is 8 & etc), then modification command and then entries you want to add/remove/modify (depending on type of the sub-array). In example above existing array aNestedSubArray received modification for 5th and 13th existing rows.

Mixed Array Modification Example

{
    "aVeryMixedArray": [
        "5|--ADD--|IsClumsy=0.0675x1.0|IsStupid=9000x1.0|--MOD--|IsBrave=0.5675x1.0|--DEL--|IsCraven",
        "--ADD--",
        "IsGenius=0.0675x1.0|IsObtuse=0.0675x1.0",
        "IsGlutton=0.0675x1.0|IsTemperate=0.0675x1.0",
        "IsGregarious=0.0675x1.0|IsShy=0.0675x1.0",
        "IsHonest=0.0675x1.0|IsLiar=0.0675x1.0",
        "--DEL--",
        "IsBeautiful",
        "IsClumsy",
        "13|--ADD--|IsMagic=9000x1.0|IsFriendship=9000x1.0|IsHeresy=9000x1.0|--INS--4|IsGood=1.0x60"
    ]
}

In example above, array is modified both, as array and as sub-array. Be extremely careful when using --MOD-- command, as you can accidentally modify whole sub-array as array entry, if you'll forget to put a dedicated command into the sub-array entry itself.

Potential Features

1. Implementation of option that prevents game from unpausing, even when you're queuing any interaction.
2. Improve shift-click inventory transfer - by default choose latest open container, but not ground.

About

A fork of Warstalker's lovely FFU beyond reach for Ostranauts

Topics

Resources

License

Stars

Watchers

Forks

Languages