{"id":30065048,"url":"https://github.com/robynllama/ffu--beyond-reach","last_synced_at":"2025-08-08T05:47:11.731Z","repository":{"id":307390688,"uuid":"1029366237","full_name":"RobynLlama/FFU--Beyond-Reach","owner":"RobynLlama","description":"A fork of Warstalker's lovely FFU beyond reach for Ostranauts","archived":false,"fork":false,"pushed_at":"2025-07-31T00:22:26.000Z","size":132,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-31T03:13:02.684Z","etag":null,"topics":["monomod","ostranauts"],"latest_commit_sha":null,"homepage":"https://git.soon-tm.info/warstalker/FFU-BR/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobynLlama.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-31T00:07:44.000Z","updated_at":"2025-07-31T00:22:30.000Z","dependencies_parsed_at":"2025-07-31T03:23:19.603Z","dependency_job_id":null,"html_url":"https://github.com/RobynLlama/FFU--Beyond-Reach","commit_stats":null,"previous_names":["robynllama/ffu--beyond-reach"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/RobynLlama/FFU--Beyond-Reach","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobynLlama%2FFFU--Beyond-Reach","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobynLlama%2FFFU--Beyond-Reach/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobynLlama%2FFFU--Beyond-Reach/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobynLlama%2FFFU--Beyond-Reach/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobynLlama","download_url":"https://codeload.github.com/RobynLlama/FFU--Beyond-Reach/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobynLlama%2FFFU--Beyond-Reach/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269372814,"owners_count":24406282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-08T02:00:09.200Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["monomod","ostranauts"],"created_at":"2025-08-08T05:46:53.457Z","updated_at":"2025-08-08T05:47:11.697Z","avatar_url":"https://github.com/RobynLlama.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Description\n\n\u003e [!IMPORTANT]\n\u003e This is a fork of Warstalker's FFU Beyond Reach. The original can be found [HERE](https://git.soon-tm.info/warstalker/FFU-BR/)\n\u003e 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](https://github.com/RobynLlama/Ostranauts.Autoloader) for delivery via the Thunderstore. If you are manually installing all your mods, feel free to use the original instead!\n \n**Fight for Universe: Beyond Reach** is modification for Ostranauts, which\nexpands modding capabilities of the original game, makes modding API more \nflexible and resolves some issues related to having multiple mods. It relies \non BepInEx and MonoMod Patch Loader.\n\nOstranauts Steam Page: https://store.steampowered.com/app/1022980/Ostranauts/  \nOstranauts Discord Server: https://discord.gg/bluebottlegames (#modding-discussion channel)\n\n## Installation Instructions\n1\\. Download BepInEx v5.4.23.2 WINx64: https://github.com/BepInEx/BepInEx/releases/tag/v5.4.23.2  \n2\\. Unzip all contents into `Ostranauts` root folder. It should contain now `BepInEx`, `winhttp.dll` \u0026 etc.  \n3\\. Download MonoMod Loader: https://github.com/BepInEx/BepInEx.MonoMod.Loader/releases/tag/v1.0.0.0  \n4\\. Unzip all contents into `Ostranauts` root folder. `Ostranauts/BepInEx/core` should now contain `MonoMod.dll`.  \n5\\. Download **all** mod's **DLL files** from releases (or compile them) and put them into `Ostranauts/BepInEx/monomod`.  \n6\\. Launch game, once in the main menu, exit, modify config files as you want. Enjoy playing/modding.  \n\n## Installation Components\n`Assembly-CSharp.FFU_BR.mm.dll` - contains core FFU features, configurations and improved modding API itself.  \n`Assembly-CSharp.FFU_BR_Console.mm.dll` - contains all the commands listed in the **Improved Console Commands**.  \n`Assembly-CSharp.FFU_BR_Extended.mm.dll` - contains all the features listed in the **New Parameters \u0026 Properties**.  \n`Assembly-CSharp.FFU_BR_Fixes.mm.dll` - contains various fixes (such as working `IsPowerObservable` with sub-COs).  \n`Assembly-CSharp.FFU_BR_Quality.mm.dll` - contains various QoL improvements listed in the **Quality Settings**.  \n`Assembly-CSharp.FFU_BR_Super.mm.dll` - contains **Superiority Settings** that can make game easier or harder.  \n\n## Error Reporting Instructions\n1\\. If you already enabled settings previously, you can ignore steps **2** and **3**, and start from step **4** right away.  \n2\\. Go to `Ostranauts/BepInEx/config` and open `BepInEx.cfg` with text editor (Notepad++ for example).  \n3\\. Find `[Logging.Disk]` and set `WriteUnityLog` to `true`in order to force BepInEx to log all the information.  \n4\\. Start game, repeat actions that resulted in error, close game. Upload `Ostranauts/BepInEx/LogOutput.log`.  \n\n# Modding Features\n1\\. Custom synchronized core + mods loading execution flow that resolves data mangling issue.  \n2\\. Partial data overwrite of existing entries (from any JSON file, whether it is core or other mod).  \n3\\. Reference-based creation of new entries with applied values. No need to copy whole code block.  \n4\\. Removal of specific data entries based on their IDs ('strName' parameter) via `mod_info.json`.  \n5\\. Precision array modification via `--ADD--`, `--INS--`, `--DEL--` and `--MOD--` (data only) commands.  \n6\\. Dynamic changes mapping and dynamic data modification (for existing templates and saved games).  \n7\\. Completely new parameters and properties that expand existing different gameplay mechanics.  \n8\\. Option to unlock max random range value that allows unrestricted random/loot lists.  \n9\\. Other various options and settings to alter gameplay and/or make it easier/harder.  \n\n**Note:** in-depth explanation and API examples can be viewed below, in relevant paragraph.  \n\n# Configuration Options\nSettings file can be found at `\\Ostranauts\\BepInEx\\config\\FFU_Beyond_Reach.cfg` (it is\ncreated after running Ostranauts for the first time with this mod installed).\n\n## Configuration Settings\n**SyncLogging** - defines what logging type is used for when overwriting data and/or\ncopy-referencing existing items into new items with various parameters overwriting.  \n**ActLogging** - defines what activity will be shown in the log during specific actions. Applies\nonly to very specific action that related to modified game code (such as inventory sorting).  \n**DynamicRandomRange** - By default loot random range is limited to `1.0f`, thus preventing use of \nloot tables, if total sum of their chances goes beyond `1.0f`. This feature allows to increase max \npossible random range beyond `1.0f`, to the total sum of all chances in the loot table.  \n**MaxLogTextSize** - Defines the max length of the text in the console. Needed in case if you want \nto see the whole list of entries from the console commands without missing anything (whether it is\n`getcond` or any other command). May impact performance, if the value is too big.  \n**ModSyncLoading** - Enables smart loading of modified COs and synchronizing of existing CO saved \ndata with updated CO templates, if they are mapped in the mod info file. Frees the user from the\nneed of manually updating existing save file and existing ship templates, if Parent CO's got new \n(or modified existing) built-in locked COs.  \n\n## Gameplay Settings\n**ModifyUpperLimit** - Enables use of `BonusUpperLimit` to change skill and trait modifier upper limit value.  \n**BonusUpperLimit** - Defines the upper limit for skill and trait modifier bonuses. Original value is **10**.  \n**SuitOxygenNotify** - Specifies the oxygen level threshold (as a percentage) for the gauge of a sealed/airtight \nsuit. When the oxygen level falls below this threshold, the wearer will receive a notification (via occasional \nbeeps) about oxygen usage. If set to `0`, no notification will be given at any time.  \n**SuitPowerNotify** - Specifies the power level threshold (as a percentage) for the gauge of a sealed/airtight \nsuit. When the power level falls below this threshold, the wearer will receive a notification (via frequent \nbeeps) about power usage. If set to `0`, no notification will be given at any time.  \n**ShowEachO2Battery** - Defines whether to show average percentage across all O2/Batteries or calculate each \nO2/Battery independently and summarize their percentages. Affects how soon notifications will begin.  \n**StrictInvSorting** - Defines if game will be using custom, order-based inventory windows sorting that enforces \nstrict UI rendering order. Relevant if slots have `sOrder` parameter set. Defaults to `nDepth` otherwise.  \n\n## Quality Settings\n**AltTempEnabled** - Allows to show temperature in alternative measure beside Kelvin value (in **top right** \ninfo window), similar to how gas shows mass and pressure. Uses formula: `AltTemp = K x Mult + Shift`.  \n**AltTempSymbol** - Defines what symbol will represent alternative temperature measure.  \n**AltTempMult** - Defines alternative temperature multiplier for conversion from Kelvin.  \n**AltTempShift** - Defines alternative temperature value shift for conversion from Kelvin.  \n**TowBraceAllowsKeep** - Defines if it is allowed to use station keeping command, while tow braced to \nanother vessel. As you remember, even when tow braced to another ship, you can only control ship manually, \nbut 'Station Keeping' command is getting turned off. This option resolves this issue.  \n**OrgInventoryMode** - Enables inventory UI tweaking mode that allows to adjust inventory window offsets,\nwhere they open, what range between them and what is the size of padding between sub-windows.  \n**OrgInventoryTweaks** - Defines various offsets that adjust inventory UI. Allows float values. Required\nvalues: Base, Top, Bottom, Padding, Grid, Safety. **Base** - horizontal offset between inventory equipment \nwindow and leftmost side of the screen. **Top** - horizontal offset from topmost inventory window to top of \nthe screen. **Bottom** - horizontal cutout offset, below which inventory window will be shown in next column,\nrequired to balance the 'top' offset. **Padding** - padding between inventory window columns. **Grid** -\ninventory windows column auto-adjustment width for each additional horizontal inventory grid tile, only\nrelevant when inventory width is above 4 grid tiles. **Safety** - is safety multiplier for inventory\nwindow height. If its too big inventory window might overflow to the next column, despite having enough\nspace in the current. If its too small, inventory window might overflow below intended height limit in the\nsame column. If you see that inventory windows overflow one way or another, enable `ActLogging` and try\nvarious `Safety` and `Bottom` values. If there are less than 6 values, parameter is ignored and default \nvalues loaded instead.  \n**BetterInvTransfer** - Changes behavior of **shift-click** item transferring in inventory. Items will be \nauto-transferred to the last inventory window, where player has placed the item manually. Last inventory \nwindow is forgotten, when inventory is closed - thus the exploit of long-distance transferring is avoided.  \n**QuickBarPinning** - Allows to permanently lock the interactions quick bar, where you desire on the screen.  \n**QuickBarTweaks** - Defines various offsets that adjust interactions quick bar position and mode. Required\nvalues: Horizontal, Vertical, Expanded. **Horizontal** - defines horizontal position offset for the \ninteractions quick bar. **Vertical** - defines vertical position offset for the interactions quick bar. \n**Expanded** - defines if interactions quick bar is always expanded or not (only `1` is treated as `true`,\nany other number is treated as `false`).\n\n## Superiority Settings\n**NoSkillTraitCost** - Option to allow learn/unlearn any trait or skill for free.  \n**AllowSuperChars** - Option to allow character to be superior or utterly miserable.  \n**SuperCharMultiplier** - Set above `1.0` to reach the stars, or below `1.0` to descent into abyss.  \n**SuperCharacters** - List of character names in lower case that you want to apply multiplier to.  \n\n# New Parameters \u0026 Properties\n**strReference** - `condowners` parameter that allows to create reference-based copy of the existing CO, \nwhilst overriding only specific parameters. **Note:** will inherit all properties of the original CO.\n\n**strInvSlotEffect** - `condowners` parameter that applies `slot effect` to every inventory item and/or the\ninventory owner. Works pretty much same way as other `slot effects`, except parameters `mapMeshTextures`,\n`strSlotImage` and `strSlotImageUnder` are ignored. Thread carefully, as it applies effect to **every** item,\nincluding whole stacks.\n\n**nSlotOrder** - `slots` parameter that only used, if `StrictInvSorting` gameplay setting is enabled. \nRequires an integer value, but can be nulled. If nulled, defaults to `nDepth` to avoid potential issues. Slots \nwith lesser numbers are rendered first in open inventory UI. Was implemented to avoid `nDepth` collision/issues.\n\n**nMaxDepth** - `condtrigs` parameter that used to check how deeply nested `condowners` object. If object\nis nested at depth greater than `maxDepth` parameter, then condition trigger automatically returns `false`. \nUse console command `getcond [them] *coParents` on selected object and count number of **in**'s to identify \nits current depth.\n\n**strMathCond** - `condtrigs` parameter that is used to compare value of a specific condition with a \nspecific number. In addition, requires defined `nMathOp` and `fMathVal` parameters to work. Supports number \nof different operations.\n\n**nMathOp** - `condtrigs` parameter that defines the math operation that will be used when comparing\ncondition's value (from `strMathCond`) with a `fMathVal` parameter value. **1** → Not Equal (`!=`), **2** → \nEqual (`==`), **3** → Greater Than (`\u003e`), **4** → Greater or Equal (`\u003e=`), **5** → Less Than (`\u003c`), **6** → \nLess or Equal (`\u003c=`). **Formula**: *CT.Value #OP# fMathVal*.\n\n**fMathVal** - `condtrigs` parameter that defines the value, which will be used for mathematical comparison.\nIf `fMathVal` isn't set, default value of `0` will be used. Whilst you can put negative value in `fMathVal`\nparameter, it is irrelevant, since condition values can't be below zero.\n\n**strMultCond** - `condtrigs` parameter that is used to perform various logical operations between value of\n`strMultCond` condition and multiple values (or their fractions) of other conditions. In addition, requires \ndefined `aMultOps` parameter to work, otherwise it will be ignored. Behavior of the parameter greatly depends\non **bAND** value. If `bAND` is set to `true`, the `strMultCond` will only trigger, if **ALL** conditions listed\nin the `aMultOps` are met. If `bAND` is set to `false`, the `strMultCond` will trigger as long as at least \n**ONE** of the conditions listed in the `aMultOps` was met.\n\n**aMultOps** - `condtrigs` parameter that defines operations with conditions that `strMultCond` will perform.\nEach valid entry requires 3 different values in array: `\"COND_NAME\",\"MATH_OP\",\"MATH_MULT\"` (for `MATH_OP` list\nrefer to the `nMathOp` parameter). As long as `aMultOps` structure is defined correctly, amount of possible\nentries has no limit - only potential performance impact. For example, `\"aMultOps\": [\"StatDamageMax\", \"3\", \"0.2\", \n\"StatDamageMax\", \"5\", \"0.7\"]` will return true, if value of the `strMultCond` condition is above 20% and below\n70% value of the `StatDamageMax` condition. Using `null` instead of `\"COND_NAME\"` in the `aMultOps` will treat\n`\"MATH_MULT\"` as value and not as multiplier, thus making `strMultCond` behave like `strMathCond` that allows\nmultiple logic conditions (i.e. `\"aMultOps\": [null, \"3\", \"12.5\", null, \"5\", \"27.5\"]`).\n\n**nIsSameShipCO** - `shipspecs` parameter that allows to find a ship, where object itself is placed. Should\nbe a quite optimized option for `interactions` that allows to access all other COs within confines of same ship \nvia `ShipTest3rd` and `CTTest3rd` parameters without much hassle.\n\n**bForceVerbose** - `interactions` parameter that forces interaction to be verbose even during failed attempts.\nExists only so other mod developers can debug where interactions fail and where they successfully execute. If\n`ActLogging` in options is set to `Interactions`, everything also will be written into log files. Do note, that\nif `nLogging` is set to `0`, no information will be written to logs, except interaction failures.\n\n**bRoomLookup** - `interactions` parameter that allows object to identify its `room` and send message to all \nthe crewmembers in it, if interaction's `nLogging` parameter is set to `2`. Required, because by default CO don't \ncontain current room information and it is only assigned via `CrewSim` (i.e. only to crewmember COs).\n\n## New Hardcoded Conditions\n**StatEmittedTemp** - `simple condition` value that allow to override `StatSolidTemp` without changing it. \nWhen set, temperature emitted from object via `Heater.Heat()` will be based on it instead of `StatSolidTemp` \nparameter.\n\n## Existing Functionality Changes\n**Sensor** - `aUpdateCommands` command. By default it can only execute interactions based on the room\nconditions. Modification allows to run it condition triggers against itself, if **strPoint** is set to `null`.\nIn addition, if **dictGUIPropMap** that it uses, contains **dfUpdateInterval** entry - it replaces default\n`1.0` (value is in **seconds**) update interval with a new value as long as its greater than `0.0`. **Note:** it\nrelies on Unity's internal `Update()` method, so if update interval is set to a too small value (i.e. too \nshort), it just won't be able to keep up with correct timing.\n\n## Improved Console Commands\n`getcond [them] *` - now `getcond` command supports wildcard `*` that lists all stats, regardless of their name.  \n`getcond [them]-NUM` - tells `getcond` to fetch data recursively from parent that is `NUM` above targeted object.  \n`getcond [them] *coParents` - lists all `condowners` parent object recursively and how they are nested.  \n`getcond [them] *coRules` - lists all `condrules` (with stat-related information) attached the targeted object.  \n`getcond [them] *coTickers` - lists all `tickers` (plus related timer information) attached the targeted object.  \n`openinventory` - opens debug inventory (with ground window) from the perspective of the selected target.  \n`repairship` - too lazy to repair ship or ship is too big for proper repairing? This command will do the repairs.  \n`findcondcos \u003cconditions\u003e` - lists all CO template with corresponding condition. Supports any amount of conditions \nvia `IsCondition` or/and via inverse `!IsCondition`. All conditions must be separated by space.  \n`triggerinfo \u003ccondtrigger\u003e \u003cmode\u003e` - prints all rules of a condition trigger as text. Depending on mode, text will \nbe printed as raw JSON values (mode `0`) or as friendly text you see in the game (mode `1`).  \n`triggertest \u003ccondtrigger\u003e \u003ccondowner\u003e` - fires condition trigger against template or selected object and logs \noutcome. Works only if game was loaded. Supports `[them]` (selected object) and `ItmCondownerName` (template).  \n\n## Elastic Mod Data Handling\nExtension to the original modding API that allows precise modification of individual parameters in specific items\nwithout need to overwrite JSON data block. To be precise, it allows:  \n*\\* Simplified Data Overwrite* - frees from need to copy entire data block just to modify single parameter.  \n*\\* Reference-based Creation* - allows to copy entire original data block with only specific parameters modified.  \n*\\* Precision Array Modification* - set of commands to precisely modify original contents of array in a safe manner.  \n*\\* Precision Dictionary Modifications* - set of commands to precisely manipulate dictionaries in same safe manner.\n\n## Existing Entities Removal\nWhilst modding API already implements exclusion based on folder paths, it removes whole files with data and not \nindividual items. Existing entities removal allows to remove specific items based on their type and their exact \nidentifier. For example, by adding the JSON block `\"removeIds\": {\"cooverlays\": [\"OutfitEVA03\", \"OutfitEVA03Off\", \n\"OutfitEVA03Dmg\"]}` into `mod_info.json` will make Data Handler remove specified identifiers from `cooverlays` \nand free them for full implementation as complete condition owners for example. This routine runs before JSON \nobjects are processed, thus prevents identifiers pollution.\n\n## Dynamic Changes Mapping\nModification or removal of some items, might require lots of manual patching for existing ship templates and \npotentially starting new game (or at least pruning existing entities). In order to avoid it, features that allow \nobjects mapping and removal were implemented. Configurable via `mod_info.json` file only.\n\n### Dynamic Changes Map Commands\n**Slotted Items Mapping**: `Switch_Slotted` command that allows to remap existing slotted sub-items into other\nitems in the list. By using code such as this `\"changesMap\": {\"OutfitEVA01\": {\"Switch_Slotted\" : [\"PocketClipPoint01=\nPocketEVAClipPoint01\"]}`, on game or template load, all slotted `PocketClipPoint01` will be converted into the\n`PocketEVAClipPoint01` for all `OutfitEVA01` items. The `Switch_Slotted` can contain multiple entries.\n\n**Recover Missing Sub-Items**: `Recover_Missing` command allows to recover missing sub-items based on the assigned\nloot table of the item itself. By using code `\"changesMap\": {\"OutfitEVA01\": {\"Recover_Missing\" : []}` game \nwill attempt to recover all `bSlotLocked` sub-items for the item itself, if they are list in the assigned loot\ntable of the item. Specifying name of sub-items in the list will make game re-add items, even if they aren't\n`bSlotLocked` as long as they are in the assigned loot table. In addition, this command also supports inverted mode\n`!Recover_Missing: []` - it will attempt to recover all `bSlotLocked` sub-items based on the loot table, if they\naren't listed in the command.\n\n**Saved COs Conditions Sync**: `Sync_Conditions` command allows to add missing conditions to already existing COs\nif they are present in their template counterparts. By using code `\"changesMap\": {\"OutfitEVA01\": {\"Sync_Conditions\": \n[]}}` game will add missing conditions from the template to the existing saved `OutfitEVA01` CO. If you intend only\nto add specific missing conditions that exist in template, listing them as `[\"IsNewCond\", \"StatNewCond\"]` will make\ngame add only them, if they aren't present in saved CO. This command also supports inverted `\"!Sync_Conditions\": \n[]` mode, in which only non-listed conditions are added to the saved CO from the template.\n\n**Saved COs Conditions Update**: `Update_Conditions` command allows to update existing condition in the saved CO\nwith the values from the template CO. By using code `\"changesMap\": {\"OutfitEVA01\": {\"Update_Conditions\": []}}` game\nwill fetch all existing condition values from CO templates and overwrite them in the saved COs.  Do note that such \napproach is extremely dangerous, as some conditions are dynamic and changing them in such way might break game logic \n(or game itself). Use precise approach `\"Update_Conditions\": [\"StatBasePrice\", \"StatDamageMax\"]` to update only \nconditions you know that are static. This command also supports `\"!Update_Conditions\": []` inverted mode that will\nupdate all existing conditions values, except ones that are listed in the command.\n\n**Sync Slotted Conditions**: `Sync_Slot_Effects` command allows to enforce specific conditions to the items that are\nslotted in targeted COs. By using `\"changesMap\": {\"OutfitEVA01\": {\"Sync_Slot_Effects\": [\"IsSlotted=1.0x1\"]}}` all COs\nthat are slotted into `OutfitEVA01` will receive `IsSlotted` condition. If you intention is to apply effect only to\nspecific sub-items, you need to use `\"Sync_Slot_Effects\": [\"IsSlotted=1.0x1|ItemName1|ItemName2\"]` and it will apply \nthe condition only specific items types, if they are slotted. In addition, this feature supports inverted mode via `!`\nsymbol in entries. Code `\"Sync_Slot_Effects\": [\"!IsSlotted\"]` will remove specified condition from slotted sub-items\nand `\"Sync_Slot_Effects\": [\"!IsSlotted|ItemName3\"]` will remove it only from specific item types. It should be only \nused, when you're certain that these conditions are assigned and/or removed to/from the slotted sub-items naturally, \nwhen you slot them into target item, since it ignores all the trigger validations and checks.\n\n**Sync Inventory Conditions**: `Sync_Inv_Effects` command allows to enforce specific conditions to the items that are\nstored in targeted COs. By using `\"changesMap\": {\"OutfitEVA01\": {\"Sync_Inv_Effects\": [\"IsStored=1.0x1\"]}}` all COs\nthat are stored in the `OutfitEVA01` will receive `IsStored` condition. If you intention is to apply effect only to\nspecific items in the inventory, you need to use `\"Sync_Inv_Effects\": [\"IsStored=1.0x1|ItemName1|ItemName2\"]` and it \nwill apply the condition only specific items types. In addition, this feature supports inverted mode via `!` symbol \nin entries. Code `\"Sync_Inv_Effects\": [\"!IsStored\"]` will remove specified condition from all the stored items\nand `\"Sync_Inv_Effects\": [\"!IsStored|ItemName3\"]` will remove it only from specific item types. It should be only \nused, when you're certain that these conditions are assigned and/or removed to/from the stored items naturally, \nwhen you put them into item's attached inventory, since it ignores all the trigger validations and checks.\n\n### Dynamic Changes Map Syntax\nSince all parameters in `changesMap` are additive, option to remove various entries and sub-entries was implemented. \nTo remove specific sub-entry, use code `\"changesMap\": {\"OutfitEVA01\": {\"CommandName\": [\"~\"]}}` and to remove entire \nentry use code `\"changesMap\": {\"OutfitEVA01\": {\"~\": []}}`. In addition, if you're using `{\"~\": [], \"Command\" : []}` \nit pretty much wipes previous mapped changes for that CO, whist filling with your mapped data only (of course - \ndepending on mod order and what loads after your mod). Individual command entries can be modified as well. Using \n`\"Switch_Slotted\" : [\"*Pocket01=NewPocket02\"]` will modify existing entry to have `NewPocket02` instead whatever \nthere was before. Using `\"Switch_Slotted\" : [\"-Pocket01\"]` will remove it instead. Do note that the `changesMap` is\nmodified in the order of loaded mods, thus you need pay utmost attention to it.\n\nIf the `SyncLogging` is set to `ModdedDump` or above, the final/compiled `changesMap` will be shown in the logs.\n\n# Modding API Examples\nA various JSON examples that demonstrate usage of extended modding API features in different ways.\n\n## Removal of Existing Entries Example\n```json\n{\n    \"strName\": \"Your Mod Name\",\n    //...vaious mod parameters...//\n    \"removeIds\": {\n        \"cooverlays\": [\n            \"OutfitHelmet05\",\n            \"OutfitHelmet05Dmg\",\n            \"OutfitEVA05\",\n            \"OutfitEVA05Off\",\n            \"OutfitEVA05Dmg\"\n        ]\n    }\n}\n```\nIn this example all `cooverlays` for Bingham-12C EVA Suit and Helmet will be completely removed from the game, in \norder to give space to proper `condowners` in the mod.  \n\n## Dynamic Changes Map Example \n```json\n{\n    \"strName\": \"Your Mod Name\",\n    //...vaious mod parameters...//\n    \"changesMap\": {\n        \"OutfitEVA01\": {\n            \"Switch_Slotted\": [\"PocketClipPoint01=PocketEVAClipPoint01\"],\n            \"Recover_Missing\": [],\n            \"Sync_Conditions\": [\"StatArmorCut\", \"StatArmorBlunt\"],\n            \"!Update_Conditions\": [\"StatMass\"],\n            \"Sync_Slot_Effects\": [\"IsModified=1.0x1|PocketEVABatt01\"],\n            \"Sync_Inv_Effects\": [\"!IsUnsableItem\"]\n        },\n        \"OutfitEVA03\": {\n            \"Switch_Slotted\": [\"~\"],\n            \"Recover_Missing\": [\"PocketEVAO201\"],\n            \"!Sync_Conditions\": [\"TestCondition\"],\n            \"Sync_Slot_Effects\": [\"-IsSpecial\"]\n        },\n        \"OutfitEVA05\": {\n            \"~\": []\n        }\n    }\n}\n```\nIn this example in saved game or template, all `OutfitEVA01` slotted `PocketClipPoint01` COs with be replaced with\n`PocketEVAClipPoint01` COs. All missing **locked** COs will be restored and re-attached to `OutfitEVA01`. If the CO\n`OutfitEVA01` is missing `StatArmorCut` or/and `StatArmorBlunt` conditions, they will be added to it. In addition,\nall condition values except `StatMass` will be fetched from original template and added to the `OutfitEVA01` CO.\nAnything that is slotted in the `OutfitEVA01` slots will receive `IsModified` condition. And everything that is\nstored in the inventory attached to `OutfitEVA01` will lose `IsUnsableItem` condition.\n\nFor the `OutfitEVA03` CO, the command `Switch_Slotted` will be removed. The `Recover_Missing` command will only\nrestore slotted `PocketEVAO201`, if it is present in the attached loot table. The `Sync_Conditions` command will\nadd all missing conditions (except `TestCondition`) from the template to `OutfitEVA03` CO. And the `Sync_Slot_Effects`\ncommand no longer will add `IsSpecial` to items that are slotted in the `OutfitEVA03` CO.\n\nThe `OutfitEVA05` will be completely removed from the `changesMap`, regardless of what it had previously.\n\n## Simplified Data Overwrite Example\n\n```json\n{\n    \"strName\": \"ItmRackUnder01\",\n    \"strContainerCT\": \"TIsFitContainerSolidCargoBay\",\n    \"nContainerHeight\": 6,\n    \"nContainerWidth\": 6\n}\n```\nAs in example above, you no longer need to copy entire `ItmRackUnder01` code block, just to alter a few \nlines of parameters. Writing valid `strName` (and using relevant folder) is enough to identify which \nentry you want to change.  \n\n## Reference-based Creation Example\n```json\n{\n    \"strName\": \"OutfitEVA05\",\n    \"strReference\": \"OutfitEVA01\",\n    \"strNameFriendly\": \"Bingham-12 Civilian EVA Suit\",\n    \"strItemDef\": \"OutfitEVA05\",\n    \"strPortraitImg\": \"CrewSuit05\",\n    \"mapSlotEffects\": [\n        \"shirt_out\", \"BodyEVA05\",\n        \"heldL\", \"HeldItmDefaultSoftL\",\n        \"heldR\", \"HeldItmDefaultSoftR\"\n    ],\n    \"jsonPI\": \"EVASuit05\"\n}\n```\nIn this example as well, you no longer need to copy entire block just to create one. When creating new entry,\nit is enough to choose valid `strReference` (`strName` of some other entry) and loader will create exact same \ncopy of the entry, but with new `strName` of your choice. Any additional parameters will be used to overwrite\nexisting copied parameters of the new entry.  \n\n## Precision Dictionary Modifications\nSome of the Ostranauts data is stored as dictionaries. In order to precisely modify it, a set modding API\nhandling mechanisms was implemented. In addition, modding API supports indefinite amount of nested dictionaries,\nas long as dictionaries themselves are supported by the data architecture of the game itself.  \n\nThere are 3 methods of modifying dictionary records:  \n`\"KeyName\": {//...DATA...//}` adds new or modifies existing record entry with the new data.  \n`\"*KeyName\": {//...DATA...//}` removes all old data in the record and replaces it with the new data.  \n`\"~KeyName\": {//...DATA...//}` completely removes all data along with the record from the dictionary.  \n\n```json\n{\n    \"strName\": \"Robot\",\n    \"mapIAHist2\": {\n        \"~StatSecurity\": {},\n        \"*StatSelfRespect\": {\n            \"strCondName\": \"StatSelfRespect\",\n            \"mapInteractions\": {\n                \"SeekKOAllow\": {\n                    \"strName\": \"SeekKOAllow\",\n                    \"nIterations\": 41,\n                    \"fTotalValue\": 2461.0\n                }\n            }\n        },\n        \"StatSolidTemp\": {\n            \"mapInteractions\": {\n                \"ACTExcerciseTreadmillDo\": {\n                    \"strName\": \"ACTExcerciseTreadmillDo\",\n                    \"nIterations\": 276,\n                    \"fTotalValue\": 20.42594\n                },\n                \"ACTExcerciseTreadmillDoHot\": {\n                    \"strName\": \"ACTExcerciseTreadmillDoHot\",\n                    \"nIterations\": 242,\n                    \"fTotalValue\": 9.623437\n                },\n                \"~ACTExcerciseStrengthTrainerDo\": {},\n                \"*ACTExcerciseStrengthTrainerDoHot\": {\n                    \"strName\": \"ACTExcerciseStrengthTrainerDoHot\",\n                    \"nIterations\": 555\n                },\n                \"ACTSomethingUnexpected\": {\n                    \"strName\": \"ACTSomethingUnexpected\",\n                    \"nIterations\": 777,\n                    \"fTotalValue\": 77\n                }\n            }\n        }\n    }\n}\n```\nThe best example of usage for this modding API is `ai_training` data. In example above, record `StatSecurity` is\ncompletely removed, record `StatSelfRespect` has all its data replaced with completely new data in the example,\ntwo records `ACTExcerciseTreadmillDo` and `ACTExcerciseTreadmillDoHot` are updated with new data, the record\n`ACTExcerciseStrengthTrainerDo` is removed as well, record `ACTExcerciseStrengthTrainerDoHot` also has its data\ncompletely discarded and replaced with new data, and completely new record `ACTSomethingUnexpected` is added \nto the dictionary. As you can see in example, it allows to operate at various sub-levels without an issue.\n\n## Precision Array Modifications\nSince Ostranauts is extremely data-drive game, lots of various parameters and flags are stored in various arrays \nand sub-arrays. Modified modding/loading API supports precise modifications of such arrays and sub-arrays. If\nyou found yourself in need of modifying such arrays: *here be dragons, thus, abandon all hope, ye who enter here*.\n\nArrays and sub-arrays can be of two types. Data arrays and simple arrays. Data array contain in each entry \n`\"name=value\"` and simple arrays arrays don't contain `=` symbol, but just string as whole, i.e. `\"BodyEVA05\"`.\n\nThere are 4 commands to perform such modifications:  \n`--MOD--` modifies existing entry based on 'name' (for data arrays only), without losing existing data.   \n`--DEL--` removes existing entry based on 'name' (for data arrays) or on whole string (for simple arrays).  \n`--ADD--` just adds the entry to the existing data as is, doesn't care about array type.  \n`--INS--` inserts the entry at designated index, shifting whatever was at this index forward.\n\n**Note:** make sure that precisely modified arrays start from any command. Otherwise, they will be copied as is\nand you're pretty much asking for a trouble. Same applies to sub-arrays, except first goes number of modifier row\nin the array - loader can't do anything with row number, but without command and will tell you about it.\n\n### Precision Array Modification Example\n```json\n{\n    \"aNormalArray\": [\n        \"--MOD--\",\n        \"StatBasePrice=1.0x9000.0\",\n        \"--DEL--\",\n        \"IsBingham=\",\n        \"--ADD--\",\n        \"StatDismantleProgressMax=1.0x180\"\n        \"--INS--4\",\n        \"StatSpecial=1.0x60\"\n    ]\n}\n```\nIn example above existing array `aNormalArray` was modified in the following way: the `StatBasePrice` was \nchanged to `1.0x9000.0`, `IsBingham` was removed from the list disregarding the value, the parameter\n`StatDismantleProgressMax=1.0x180` was added as is to the list and the parameter `StatSpecial=1.0x60` was\ninserted at the place of 4th entry in the array and whatever was there initially shifted forward.\n\n### Precision Sub-Array Modification Example\n```json\n{\n    \"aNestedSubArray\": [\n        \"5|--ADD--|IsClumsy=0.0675x1.0|IsStupid=9000x1.0|--MOD--|IsBrave=0.5675x1.0|--DEL--|IsCraven\",\n        \"13|--ADD--|IsMagic=9000x1.0|IsFriendship=9000x1.0|IsHeresy=9000x1.0|--INS--4|IsGood=1.0x60\"\n    ]\n}\n```\nSub-array is essentially array within array, but with different separator (`|` in that case). First you write \nindex of the row you intend to override (1st row is `1`, 8th is `8` \u0026 etc), then modification command and then\nentries you want to add/remove/modify (depending on type of the sub-array). In example above existing array\n`aNestedSubArray` received modification for 5th and 13th existing rows.\n\n### Mixed Array Modification Example\n```json\n{\n    \"aVeryMixedArray\": [\n        \"5|--ADD--|IsClumsy=0.0675x1.0|IsStupid=9000x1.0|--MOD--|IsBrave=0.5675x1.0|--DEL--|IsCraven\",\n        \"--ADD--\",\n        \"IsGenius=0.0675x1.0|IsObtuse=0.0675x1.0\",\n        \"IsGlutton=0.0675x1.0|IsTemperate=0.0675x1.0\",\n        \"IsGregarious=0.0675x1.0|IsShy=0.0675x1.0\",\n        \"IsHonest=0.0675x1.0|IsLiar=0.0675x1.0\",\n        \"--DEL--\",\n        \"IsBeautiful\",\n        \"IsClumsy\",\n        \"13|--ADD--|IsMagic=9000x1.0|IsFriendship=9000x1.0|IsHeresy=9000x1.0|--INS--4|IsGood=1.0x60\"\n    ]\n}\n```\nIn example above, array is modified both, as array and as sub-array. Be extremely careful when using \n`--MOD--` command, as you can accidentally modify whole sub-array as array entry, if you'll forget to put \na dedicated command into the sub-array entry itself.\n\n## Potential Features\n1\\. Implementation of option that prevents game from unpausing, even when you're queuing any interaction.  \n2\\. Improve shift-click inventory transfer - by default choose latest open container, but not ground.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobynllama%2Fffu--beyond-reach","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobynllama%2Fffu--beyond-reach","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobynllama%2Fffu--beyond-reach/lists"}