# Community modding wiki *Shard of mgsv-modding-pack — generated 2026-08-11. 75 files. Provenance is on every entry as `source:path`.* A decade of community reverse engineering. Strong prior, not ground truth; pages can be stale or stubbed. ## MGSV Modding and Research Wiki - `wiki:assets/Chimera_Package_Table/ChimeraPartsPackageTable.lua` — ChimeraPartsPackageTable.lua ### `wiki:README.md` > This is the central hub for information on modding the [Fox Engine](https://en.wikipedia.org/wiki/Fox_Engine) [Metal Gear](https://en.wikipedia.org/wiki/Metal_Gear) games:
- [Metal Gear Solid V: Ground Zeroes](https://en.wikipedia.org/wiki/Metal_Gear_Solid_V:_Ground_Zeroes) - [Metal Gear Solid V: The Phantom Pain](https://en.wikipedia.org/wiki/Metal_Gear_Solid_V:_The_Phantom_Pain) - [Metal Gear Survive](https://en.wikipedia.org/wiki/Metal_Gear_Survive) ##### Main Categories [![Fox](/assets/Philanthropy Icon.webp){:.inline width="145px"}](/Fox) [![FoxKit](/assets/Games Icon.png){:.inline width="145px"}](/FoxKit) [![File Formats](/assets/File Formats Icon.png){:.inline width="145px"}](/File_Formats) [![Tools](/assets/Tools Icon.png){:.inline width="145px"}](/Tools) [![Lua](/assets/Lua Icon.png){:.inline width="145px"}](/Lua) [![Guides](/assets/Guides Icon.png){:.inline width="145px"}](/Guides) [![Infinite Heaven](/assets/InfiniteHeaven Icon.webp){:.inline width="145px"}](/Infinite_Heaven) [![AI](/assets/AI/images/AI Icon.png){:.inline width="145px"}](/AI) {:.center} ### `wiki:wiki/AI/AI.md` [![Metal Gear Sahelanthropus](/assets/AI/images/Shln Icon.png){:.inline width="145px"}](/AI/mgs) [![Volgin](/assets/AI/images/volgin Icon.png){:.inline width="145px"}](/AI) [![Quiet](/assets/AI/images/Quiet Icon.png){:.inline width="145px"}](/AI) [![Skull Units](/assets/AI/images/skulls Icon.png){:.inline width="145px"}](/AI) [![Soldiers](/assets/AI/images/Soldiers Icon.png){:.inline width="145px"}](/AI) [![Pequod](/assets/AI/images/Pequod Icon.png){:.inline width="145px"}](/AI) [![Enemy Vehicles](/assets/AI/images/EnemyHelis Icon.png){:.inline width="145px"}](/AI) [![Animals](/assets/AI/images/Animals Icon.png){:.inline width="145px"}](/AI) {:.center} ##### Metal Gear {:.small} ##### Volgin {:.small} ##### Quiet {:.small} ##### Skull Units {:.small} ##### Soldiers {:.small} ##### Pequod {:.small} ##### Enemy Vehicles {:.small} ##### Animals {:.small} ### `wiki:wiki/Adding_'pack_small'_files_to_an_custom_map.md` ##### Requirements - [Foxtool](https://github.com/Atvaark/FoxTool/releases/tag/v0.2.6) - Hexadecimal editor ([HxD](https://mh-nexus.de/en/downloads.php?product=HxD20) works fine) - [pack_small](https://github.com/TheHuntingParty/TPP-Pack-small) files - Winrar - [Bulk Rename Utility](https://www.bulkrenameutility.co.uk/) ##### Making the game load the pack_small files First thing you want to do is download the required files from the GitHub Repo ![](/assets/GitHub%20repo%20download%20example.png){:.left width="175px"} After downloading open the .zip with WinRAR, if you use the default files explorer it will take ages to open ![](/assets/Pack%20small%20winrar%20Example.png){:.left width="364px"} When you open that file, you will see 3 folders and 2 GitHub files, the GitHub files are useless, extract ONLY expl_fpk and expl_fpkd on your map folder, in this case its Assets\\tpp\\pack\\location\\expl. (expl stands for your 4 map letters) keep the WinRAR window open, the "pack_small" is for later ![](/assets/Winrar%20file%20example%20pack%20small.png){:.left width="614px"} Should look like something like this: ![](/assets/Another%20image%20god%20this%20sucks%20aaaaaa.png){:.left width="532px"} Now rename both folders, remove the "expl" and replace by your map 4 letters, in this example it will be "aaaa", select the 2 folders and use You can use Bulk Rename Utility to do that, Windows 11: select the 2 folders and right click -\> show more options --\> Bulk rename here ![](/assets/Bulk%20file%201.png){:.right width="336px"} Windows 10: select the 2 folders and right click --\> Bulk rename here Now, the program should open with those 2 folders selected, ![](/assets/Bulk%20sofware%20ui%200.png){:.center width="867px"} Next you want to check the option "Subfolder" on Filters(12), after that, all files and folders inside those 2 folder are going to appear on the tree window (where the green circle is on the image above), now you have to select either all files (shift click 1st and last entry) or select only those that contain "expl" on the name, they are 6 to be precise, after you selected them, got to the area 3, called "Replace" On the "Replace" textbox, write expl and on the "with" textbox write your 4 map letters, in this example they are "aaaa" ![](/assets/Bulk%20sofware%20ui%201.png){:.right width="524px"} Was you can see, the names are going to be different, the expl is now the 4 letters that you placed on the "with" textbox, all you have to do now is confirm that all "expl" are renamed, if yes, press "rename" ![](/assets/Bulk%20sofware%20ui%202.png){:.center width="852px"} You should get the confirmation that all files were renamed and an "OK" will appear on front of the files renamed at the tree window. ![](/assets/Another%20one%20image%20aaaa.png){:.right width="721px"} The folder should now look something like this ![](/assets/Fox2%20info%203.png){:.right width="687px"} Inside the fpkd folder there is a file called (4mapletters)_stage.fox2, open that file with Foxtool and edit the xml, on lines 60 and 63 you need to change "expl" to your map 4 letters ![](/assets/Fox2%20info%202.png){:.right width="691px"} Same was to be done on Line 148, replace expl_common_packages.fstb with (4mapletters)_common_packages.fstb and the expl folder too After editing the xml, delete the original fox2 and drop the xml on Foxtool to generate the new one. Now the last step is editing the fstb file, for this you are going to need an Hexadecimal editor, HxD can do it fine. Open your hexadecimal editor and drag the fstb to there, after that you should be looking at something like this: ![](/assets/HXD%20fsbt%20open.png){:.left width="412px"} Now Open an empty text file on notepad, while editing hexadecimal files you need to be cautious, one space or character on wrong place and all thing wont work. Select all the text after "expl" except the last "." and copy it to the empty notepad text ![](/assets/HXD%20fsbt%20copy.png){:.right width="674px"} It should be done like this example here, the "." must remain unchanged. Now on the notepad file, change the "expl" folder to your map 4 letters and the "expl_common.fpk" to your map pack common folder name. in my example the folder will be called aaaa and the pack folder aaaa_common.fpk carefully copy the changed text on notepad and paste it on the right place, 1st delete the text you copied ![](/assets/HXD%20fsbt%20remove.png){:.left width="668px"} and then paste the text on notepad, right behind the ".", it should look like this ![](/assets/HXD%20fsbt%20add.png){:.left width="677px"} after making sure the file is ok, save it and close the hxd app, you can delete the backup file created by the HxD after that. ##### 2 - Adding the pack small files Now comes the most time consuming part, adding the actual pack small files, open the .zip with winrar again and extract the "pack_small" folder to the same folder were pack common and the previously copied fpk/fpkd are. be warned, there is 8,192 Files and 53,312 Folders, its going to take a while, mainly on HDDs. After that operation finishes you should have your map folder looking like this: ![](/assets/Pack%20small%20winrar%20done.png){:.center width="585px"} That is good, but its not over yet snake\! You still need to rename all the folders and .fox2 from "expl" to your map 4 letters, to do that you have to use bulk rename utility. Open the pack_small folder and select all 64 folder inside (you can select the 1st and then shift click the last folder to select all of the 64 folders at once), then press Bulk rename here option was done before, while on the app, select the Filter "Subfolder" and wait, the app will take some time to map and read all of the stuff inside. The total of objects should be 61504. ![](/assets/Bulk%20sofware%20objects.png){:.right } ![](/assets/Bulk%20sofware%20objects%20selected.png){:.right width="194px"} Select all folders by right clicking on the 1st entry, use the scroll bar to go to the end and shift + right click on the last and they should all get selected, it will take a while for the app to select them all After you selected them all, go to the replace area and on the "replace" textbox with "UNSA" and the "with" textbox with your map 4 letters, in this example it is "aaaa". The app will freeze while preparing to change the names. After that check if the new names are fine, if they are press "rename" ![](/assets/Bulk%20sofware%20objects%20rename.png){:.center width="771px"} Renaming will take some time to be done. After its completed your map pack_small files should be working fine. ### `wiki:wiki/Attaching_graphics_debuggers.md` By default, TPP checks the loaded d3d11.dll before and after it creates necessary D3D11 interfaces to confirm d3d11.dll hasn't been hooked. This is likely meant as a countermeasure against cheating in MGO but a side effect is that tools like graphics debuggers (RenderDoc) and mod packages (ReShade) generally do not work. The fix is to simply ignore the result of `fox::gr::dg::CheckModuleHook` by patching a conditional jump to simply always jump to the `true` case. Offsets: |Version|File (Japanese)|Memory (Japanese)|File (English)|Memory (English)|Original JZ|Replace JMP| | - | - | - | - | - | - | - | |1.0.15.3|`0x2B96CB`|`0x1402ba1c0`|`0x2B9C2B`|`0x1402bb242`|`75 2D`|`EB 2D`| |1.0.15.4|`0x2B963B`|`0x1402ba130`|`0x2B90AB`|`0x1402b9a10`|`75 2D`|`EB 2D`| Using a hex editor, navigate to `mgsvtpp.exe+0x(file offset)` or `0x14(memory offset)`: ![Before](/assets/Attaching_graphics_debuggers/BeforeCheckModuleHookFix.png) and set the following six bytes (`0F 84 1F 04 00 00`, (JZ LAB_1402bb667), or Original JZ) to `48 E9 00 00 00 00` (JMP LAB_1402bb248), or Replace JMP: ![After](/assets/Attaching_graphics_debuggers/AfterCheckModuleHookFix.png) ### `wiki:wiki/AutoPftxsTool.md` AutoPftxsTool is an open-source automatic .pftxs unpacker and repacker for Metal Gear Solid V: The Phantom Pain written by BobDoleOwndU. It simplifies the process of adding new textures or sub-textures to a .pftxs file as it eliminates the need to edit an .xml with new entries to do so. ##### Usage To unpack a .pftxs archive, a user simply needs to drag a .pftxs file onto the tool. This will output a folder containing all of the files contained in the .pftxs file. To add new textures, a user simply needs to place the textures inside the unpacked folder. To repack a .pftxs file, the user simply needs to drag an unpacked folder onto the tool. The tool will automatically detect all textures contained in the folder and pack them into a .pftxs file. ### `wiki:wiki/Chelly's_Rad_as_Shit_Guide_to_Mods.md` ![](/assets/So%20meme.jpg){:.left .thumb} So. You've taken an interest in modding MGSV, but you don't know where to begin? Here are some great mods to start you off with\! ##### [Snakebite Mod Manager](https://www.nexusmods.com/metalgearsolidvtpp/mods/106) ![Your](/assets/Snakebite.png){:.thumb} first order of business should be to install Snakebite, the mod manager used for all MGSV mods. Set up is pretty simple: After it backs up your game files, you're good to go. Keep in mind that when you're installing mods, it'll take a moment because Snakebite has to unpack and repack large data files. The more mods you have, the longer this will take. Same goes for uninstalling mods, of course\! ##### [Infinite Heaven](https://www.nexusmods.com/metalgearsolidvtpp/mods/45) ![](/assets/45-0-1448484425.jpg){:.thumb} By far the most useful mod, Infinite Heaven does...basically everything you could want. Tweak health values, guard sight/hearing, timescale, enemy equipment, basically whatever. You can force Subsistence mode for any mission, spawn war games on Mother Base, enable freecam, skip helicopter rides...whatever you want, basically. The UI is a little clunky to navigate, but it's still pretty much mandatory to use. Another bonus is that it's highly modular, allowing you to install various add-ons to it. Which brings us to... ##### [Morbid's Side-Op Expansion Pack](https://www.nexusmods.com/metalgearsolidvtpp/mods/464) ![This](/assets/464-4-1494937450.jpg){:.thumb} mod adds a whopping *50* side ops to the main game\! All of them have unique flavor text and obstacles, so no "Extract the Soldier \#32" here\! When you get done playing them all, you can create your own side-ops with [SideOp Companion\!](https://www.nexusmods.com/metalgearsolidvtpp/mods/571) ##### [The Man Who Sold The World](https://www.nexusmods.com/metalgearsolidvtpp/mods/59) ![Shameless](/assets/59-1532209796-1642007205.png){:.thumb} promotion. Sue me, it's my guide. Anyway, this mod allows you to play as the guy you thought you would be playing as when you bought the game. Not only can you swap Venom Snake's head for Big Boss's, you can swap his bionic arm for a real one\! Includes variations, too\! ##### [Yet Another Weather Mod](https://www.nexusmods.com/metalgearsolidvtpp/mods/328) This mod changes the weather values of the game, so that incliment weather lasts longer. In addition, rain has a chance of appearing in Afghanistan, and fog has a chance of appearing in Africa and Mother Base. ##### [Audio Redux](https://www.nexusmods.com/metalgearsolidvtpp/mods/353) Mutes a lot of repetitive audio cues, from Miller's radio comments to the riff that plays when you mount D-Horse. A godsend if "BOSS GET DOWN" gives you anxiety. ##### Mod authors to keep an eye on So once you've got a grasp on the basics, you might want to check out some other mods that appeal to your niche tastes. I recommend following these mod authors, as they're known for putting out really good stuff. In no particular order... - [Morbidslinky](https://www.nexusmods.com/metalgearsolidvtpp/users/3335983) - [CapLagRobin](https://www.nexusmods.com/metalgearsolidvtpp/users/34529480) - [FrankensteinKappa](https://www.nexusmods.com/metalgearsolidvtpp/users/38775980) - [Cuba](https://www.nexusmods.com/users/6583285) - [BaileyJIII](https://www.nexusmods.com/users/2881893) - [BobDoleOwndU](https://www.nexusmods.com/users/4085798) ##### "But I want to make a mod\!" Then join [Modder's Heaven](https://discord.gg/yttPsfr), a Discord server where people are happy to help new faces learn the ins and outs of MGSV modding\! Welcome aboard\! ### `wiki:wiki/Chimera_Weapon_System.md` What is the **Chimera Weapon System**, or rather, what is **Chimera**? **Chimera** is the internal name for pretty much everything weapon related in MGSV, mainly associated with firearms. The name of it is thanks to how through weapon customization, you're able to mix and match different weapon parts around, essentially creating a [chimera](https://en.wikipedia.org/wiki/Chimera_\(mythology\)) weapon. And while the system has it's limitations set by the game, you can pretty much tinker with each of it's .lua based files to open up more possibilities, customization options, altering stats and the like. ##### **Chimera Categories** There are two kinds of chimera weapons: ###### **True Chimeras** These are weapons that in the base game, the player is allowed to both use and customize at will. They're composed of separate models that are put together by the game, and *only* the player is allowed to use them. ###### **CS Weapons** These weapons, unlike the previous type, can be used by either the player or NPC soldiers. Be it those soldiers being Mother Base Staff, XOF, Soviets, or the various PFs in Africa. The name of the category comes from certain weapons that have the word "CS" added at the end. While they still need to use the standard chimera system in the files, they're composed of one single model. The vast majority of them the player is only able to find and use them in the field, by stealing it from NPCs. Some of them however can be used by being equipped in sortie prep, and have customization options locked up. Weapons such as the Adam-ska Special and the Tornado-6 Revolver are under this category. ###### **How to Identify the Two Types** For this example, I'll be using two versions of the Rasp shotgun. This is the RASP TB-SG SB, which is a True Chimera: ![](/assets/RASP%20-%20True%20Chimera.png){:width="515px"} And this is the RASP SB-SG GOLD, which is a CS Weapon: ![](/assets/RASP%20-%20CS%20Weapon.png){:width="515px"} Notice any differences? Look closely: ![](/assets/True%20Chimera%20-%20Identification.png){:.legacy-small width="320px"}![](/assets/CS%20Weapon%20-%20Identification.png){:.legacy-small width="320px"} True Chimeras always have the Switch Display function added to it's description in the customization menu, which allows you to swap pages and view what parts the weapon is using. CS Weapons completely lack this picture. Futhermore, **CS Weapons cannot be customized**, even if you were to unlock the menu to do so, the game will CTD as soon as you open the menu for the weapon. ##### **Getting Started** There will be three things you'll be needing for the .lua adventure of understanding, and then tinkering with Chimera. This assumes you have basic knowledge on modding the game, such as having SnakeBite installed, and know how to unpack files. ###### **Notepad++** Notepad++ will be the main tool you'll be using for editing, looking, and checking everything related to all .lua files. If you haven't downloaded it, here's a link to [it's official website](https://notepad-plus-plus.org/). After installing it, .lua files will be associated with it. ###### **Altering the appearance of Notepad++** One word of advice is setting a custom theme to use the editor with, as the default editor can be difficult to go through. For example, the default look of Notepad++ is this: ![](/assets/Default%20Notepad++%20Theme.png){:width="725px"} While personally, my custom theme makes it look like: ![](/assets/Muffins%20Notepad++.png){:width="725px"} Font is altered, there are different highlights, numbers are made larger to stand out, color is easier on the eyes. In order to change it, go over to the Item Bar on top and proceed to Settings: ![](/assets/Style%20Configurator.png){:.legacy-small width="250px"} And pick Style Configurator. You'll open a window that allows you to swap themes for Notepad++. Pick a theme you like, and go at it\! If nothing satisfies you, it allows you to change colors to your personal liking. **Please note, for all following .lua files, I'll be using my own personal theme for Notepad++.** ###### **MGSV Deminified Lua** While you can use the .lua files the game provides, **for the love of god don't**. It's difficult to read and edit through them, and chances of making things worse are higher. This is where Deminified Lua comes in, majority of the .lua files of the game were made easier to read, and you can get them [here](https://github.com/TinManTex/mgsv-deminified-lua). Simply when you have unpacked the desired .lua to edit, just copy and paste the deminified version by replacing all of it. ###### **MGS Monster Guns** The Holy Grail of Chimera Modding, without it, I wouldn't be able to setup this guide. You can access it [here](https://github.com/unknown321/mgsmonsterguns). While I'll go over pretty much all of the info displayed in that small guide, it's good to check it, especially because you'll need something from it, that you'll have to go back often to. ###### **Weapons Table** The link of the Weapons Table is available in Monster Guns, but here's a [link to it](http://unknown321.github.io/mgsmonsterguns/). Basically, it lists the vast majority (but not all) of weapons and parts featured in the game, showing their IDs for .lua and their names in the in-game UI. You'll often have to go to it in order to look up a specific part, weapon, or even the development tree. ###### **Backup your Save Data** This is often not necessary, but it's a good precaution to do so. Messing with Chimera can be finicky. It can lead to TPP getting a **crash to desktop**, also known as **CTD**. Or it can lead to an **infinite loading** situation, also known as **hanging**, as in "the game hangs in place." So look up online on how to do so, and you'll be ready to go\! ##### **The .lua Files** The following are the .lua files that contain and / or are related to Chimera. ###### [Chimera Package Table](/Chimera_Package_Table "wikilink") ### `wiki:wiki/Collision_Attributes.md` The following strings are collision attribute names, used in properties like collisionAttributeNames in GeoxCollisionFreeShape. #### Attributes - CHARA - PLAYER - RECOIL - ENEMY - BULLET. Bullet model at collision. - MISSILE - BOMB - BLOOD. Blood at collision. - IK. Inverse kinematic of model get adjusted with the geometry of collision. If collision have angle the player will get the foot adjusted to the surface. - STAIRWAY - STOP_EYE - CLIFF - DONT_FALL. When player get off the collision it will fall naturally and not a step out or jumping that usually do. Need more tests. - CAMERA. Without this Tag the camera will pass through the model. If active, camera will circumvent the model but with player center of attention. - CLIFF_FLOOR - BULLET_MARK. Texture of bullet mark at collision. - HEIGHT_LIMIT - DOUBLE_SLIDE - WATER_SURFACE - TARGET_BLOCK - DOG - NO_EFFECT - EVENT_PHYSICS - NO_WALL_MOVE - MISSILE2 - RIDE_ON_OUTER - FLAME - IGNORE_PHYSICS - CLIMB - HORSE - VEHICLE - MARKER. Turn available the scope marker at the collision. - RIDE_ON - THROUGH_LINE_OF_FIRE - THROUGH_ITEM_CHECK - NO_CREEP - NO_FULTON - FULTON - ITEM - BOSS ### `wiki:wiki/Create_a_Custom_Map.md` The guide will present a custom map template by **CapLag** and describe the file to help understand how to work with a new simple map with no small blocks. Download: [Sample_Empty_Map_No_Small_Blocks_b11](https://drive.google.com/file/d/1MWWUN4U0chH84fnAprCx1lbIL5BDbQPf/view?usp=sharing) Requires [Infinite Heaven](/Infinite_Heaven "wikilink"). You could probably just run the sample map and it should load fast. ##### **Creating the Mod Folder** Unpack the .mgsv with your preferred archive unzipper tool. Change the name of the folder to fit your taste. ![](/assets/Map01.jpg) Inside the Mod Folder, you should have the folders Assets and GameDir. `smpl` is the four letter name that will be the unique locationName for your custom location. `afgh`, `mafr`, `cypr`, `mtbs` are some of what's used by the game, for example, in its vanilla [Locations](/Locations "wikilink"). In this guide we will use `mapa`, and change all instances of `smpl` in the example to that. It can be whatever you think would be better and unique. Change the name of `smpl.fpk` and `smpl.fpkd` in `mapa` to `mapa.fpk` and `mapa.fpkd`, and then unpack them with a recent enough version of [GzsTool](/GzsTool "wikilink"). The renaming doesn't matter much as long as the location script calls for the right path. It's a matter of organization only as you can have as many `.fpk`/`.fpkd` folders with any names. MakeBite from [SnakeBite](/SnakeBite_Mod_Manager "wikilink") will pack all `_fpk` and `_fpkd` folders to `.fpk` and `.fpkd` pack files. ![](/assets/Map02.jpg) `mapa.fpk` will have assets such as .[fmdl](/FMDL "wikilink"), .[geom](/GEOM "wikilink"), .[twpf](/TWPF "wikilink"), .[frt](/FRT "wikilink"), [motions](/MTAR "wikilink"), .[nav2](/nav2 "wikilink"), .[lba](/LBA "wikilink") and whatever... `mapa.fpkd` will have various accompanying object placement parameter data, such as .[fox2](/FOX2 "wikilink"), [scripts](/Lua "wikilink") and .[vfx](/VFX "wikilink"). ###### **Main Location .fpkd Pack Contents** Inside the \_fpkd folder there should be three folders: `level`, `level_asset` and `ui`. In `level_asset`, there should be the block data loading .fox2 dataset files for memory allocation of the player block, buddy block and vehicle block. No need to change things here, though maps have been known to work even without the player block entity. In `ui`, the `result_option_subtitles_boot.fox2` will load the subtitles for the result screen. It's not needed for the map to function, but all maps place this here. In `level`, change the 4 letter `smpl` name to your `mapa` equivalent, as well the these three files. The `.fox2` files here don't matter much, and neither do their names, unless they need to be referenced by `EntityLink` references in some `.fox2` entities. ![](/assets/Map03.jpg){:width="516.981px"} ###### **_common_asset_floor.fox2** The `_common_asset_floor.fox2` is the dataset which stores the data in which a `.fmdl`/`.geom` pair from the `.fpkd`'s associated `.fpk` called `mtbs_flor011` is placed as a `StaticModel`, rotated and scaled. To edit `.fox2` files in XML, download [FoxTool](/FoxTool "wikilink") and unpack the `.fox2`. Check out the guide [FoxKit: StaticModel and GeoxCollisionFreeShape](/FoxKit-_StaticModel_and_GeoxCollisionFreeShape "wikilink") by **Ventos** to understand more about how to add more assets to the custom map. You can place as many `.fox2` files with as many placed assets in them as the game could possibly take it. You can completely remove this file along with the `.fpk`'s `mtbs_flor011` `.fmdl`/`.geom` pair, as the map doesn't require a floor for the player to stand on - there's already an invisible floor at Y -80, so while testing the map, you can simply specify the later described mission `.lua` script's `startPos`'s Y value to -79.2 to safely spawn on the always present invisible floor. ###### **_common_data.fox2** The `_common_data.fox2` defines the entity `TppLocationData`. It doesn't matter much in terms of the map actually loading in, so you can leave it out for now, if you don't deem the sky tinting, global fog and color correction parameters important for your map just yet. You should change the name of it to `mapa_location` (or with your equivalent of `mapa`) where `smpl_location` is. While `locationId` works with 0, like it does with MGO maps it might be interesting to choose a unique one, and you will need to pick one later in the location `.lua` script later on. Please see [Things Codes](/Things_Codes "wikilink") to have a look of each number location is already taken by the vanilla game. There aren't many custom locations at the moment, so there's no need for a custom location number id reservation system. To follow the vanilla game's location ids count, anything beyond 120 is fine. `scriptPath` has yet to be seen in vanilla uses with anything but an empty value, so it can be left as is. For the map to have weather and sky tinting based on time of day, you should write down a path between `` to the weather parameters file, .twpf, where it should be in `mapa_fpk/Assets/tpp/level/location/mapa/` folder, like: `/Assets/tpp/level/location/mapa/mapa_weatherParams.twpf` It can be empty for now. There's no tools yet to generate `.twpf` files yet, so it's best to reuse vanilla ones from TPP and onwards. ![](/assets/Map04.jpg) ###### **_mission_block.fox2** This dataset loads the important `TppSimpleMissionBlockControllerData` entity. It has to be in, but doesn't require any changes. You can rename the .fox2's name, though. ###### **Main Location .fpk Pack Contents** The template map only loads the `StaticModel` `mtbs_flor011.fmdl` and `.geom`. If you removed the floor dataset as previously suggested, you can remove these ones as well. ![](/assets/Map05.jpg){:width="446.993px"} `_fpk/Assets/tpp` could store a lot of types of asset files. Environmental assets like rocks, trees, ground and houses can be found in the `environ` folder**.** If a `location_common_sky.fox2` dataset needs a sky model, it'll look for a `sky_dome` in the `effect` folder. If a dataset needs to add `.mtar` files, it'll look in the `motion` folder. If it needs to find a weapon model, it'll look in the `weapon`, so on and so forth. And, of course, the `level` folder which stores files like `.twpf`, `.nav2`, `.lba`, `.geoms`, .`obr`, `.grxla`, `.gpfp`, etc. It's best to look up examples of the uses of those entities in vanilla maps, and when tools are made to create them, there should be guides here on how to create them and made your map use them\! ##### **GameDir Folder** `The GameDir` folder will have the external Infinite Heaven add-on location `.lua` script and the mission add-on `.lua` script to prepare the pack paths and other parameters for Infinite Heaven to pipeline and inject into the game's location and mission definition tables. ###### **Location** Inside the `GameDir/mod/location/SMPL.lua` script you will also find CapLag's initial comments on these files and parameters. Change the name of `SMPL.lua` to your location's name. Open the file using any editor that accepts `.lua`, like Notepad++ or Visual Studio. Change the `locationName` and the `locationId` according to our previous changes to the TppLocationData, and change the path to the `.fpk` to the right one, also according to our previous changes. Make sure your paths always start with `/Assets/` and use `/` instead of `\`. Note that inside the packs, you can specify multiple `.fpk` paths as a list, for example: `packs= { "/Assets/tpp/pack/location/mapa/mapa.fpk", "/Assets/tpp/pack/location/mapa/secondFPK.fpk", },` ![](/assets/Map06.jpg) ###### **Mission** The sample map file has a `12000_sample.lua` script: the code in the name needs to be unique as it might conflict with another one with the same name. `12000` is of course none of the vanilla have, and it's unlikely for any mod show that soon, because we don't have much mod maps available. You can choose any mission id from the 12k range for testing, but for release you should contact us at Modders' Heaven to reserve a mission id, so anything in the 13k range above `13010` is fine. Currently there's not many mission mods, so no serious mission reserving system is in place yet. Open the mission add-on `.lua` script and change the `missionCode`, add the right location. The pack here loads a minimal sample mission `.fpk` that's already included with Infinite Heaven. If you want to make a unique mission `.fpk` with NPCs and objectives and such, the path should point to another `.fpk` in `/Assets/tpp/pack/mission2/` and not in `location`. And the `startPos` should write the coordinates for where the player will spawn on mission start. if you previously removed the floor dataset as suggested, change the Y, the second value, to -79.2. For further mission and location add-on script parameters, check out Infinite Heaven's `InfMission.lua` script usually found in `/MGS_TPP` or `GameDir/mod/modules/InfMission.lua`. ![](/assets/Map07.jpg) ##### **Building and Testing It** If you wish to expand the map, check out the guide [FoxKit: Installing, Import Files and Terrain](/FoxKit-_Installing_Import_Files_and_Terrain "wikilink") by **Ventos**. You should understand how `.fox2` file works and get used to all the entities game has, the folder structure of game and what file does what. To write missions, see how side ops are made with [Side Op Companion](https://github.com/JosephZoeller/SOC), how other users' locations missions and side ops are made, or how all of the above work in the vanilla game. See .lng2 files to add a suited name for the area as well some images of location. This is just the beginning. ### `wiki:wiki/Creating_a_Custom_Sound_Bank.md` So, you want to create custom sound banks? Perhaps you want to create a custom radio call or dialogue for a mission you’re developing. Or, you want to use some custom ambience for an entirely new location\! Or better yet, change the background music of the game\! In all of these cases, you need to create a custom sound bank. Before we get into the process, I’ll have to mention a couple of things. Also, this tutorial assumes that you have prior knowledge and a good understanding of MGS:V’s file structure, **fpk**/**fpkd** files, and the **.fox2** (also known as **DataSet**) files. 1. This process is **not** the same as sound swapping. Sound swapping replaces already existing sounds in the game, whereas custom sound banks let you create entirely new ones, and give you a lot more control. 2. Custom sound bank creation will never replace the method of sound swapping. Sound swapping is the recommended method of replacing already existing sounds 99% of the time. 3. This tutorial will not specifically mention how to properly create new dialogue, or background music, or ambience. It only shows how to implement a very basic sound. But for all the above cases, the process is at least 85% the same. You will still generate and patch up sound banks the same way, and the process of properly loading the sound bank in the game is also the same. What does differ are some of the steps in creating the various events and how you actually play the sounds in the game. For instance, the game will play dialogue differently than say, ambient sounds. Now, let’s first clear out what a sound bank even is (skip this next paragraph if you want to get straight to the tutorial). ##### The Sound Engine of MGS:V As the name implies, a sound bank is a file that contains all kinds of audio for the game. In the case of MGS:V, all audio is always stored inside an **sbp** file (**s**ound **b**ank **p**ackage?). The Phantom Pain specifically contains 215 of these\! Those include every audio: weapon sounds, cutscenes, ambience, vehicles, you name it\! Now I know what you’re thinking: “How are these sound bank files generated?”. You might think that the answer is very simple: Kojima Productions have programmed their own sound system, with its own tooling for it\! But no, that’s not the case, unlike 99% of the file formats of MGS:V. Luckily for us (or unluckily if you want to look at it that way\!), Kojima Productions used a very popular audio engine that has been used by many other game developer studios as well. Witcher 3 is one of those games that uses this exact same audio engine. It’s called WWise. Thankfully, there’s a free program with the same name that does just that, create sound banks (which is obviously made by the same company). This is the program that we will use to create our own custom sound banks. The free version has some limitations to it though, but we really don’t have to worry about that right now. ##### Requirements So for this process, we’ll need 3 things: [WWise 2013](https://www.nexusmods.com/witcher3/mods/3234), as well as any hex editor program, such as [HxD](https://mh-nexus.de/en/hxd/) or [010 Editor](https://www.sweetscape.com/010editor/). Furthermore, you’ll need [FoxTool](https://github.com/Atvaark/FoxTool/releases) for turning an xml file to a **.fox2** and an **.sdf**. Another thing you’ll obviously need is the sound file that you want to add to the game. Unfortunately, WWise only likes .wav formats, so if your sound effect isn’t a .wav, you’ll have to convert it to one. This can be done in many ways, such as using [Audacity](https://www.audacityteam.org/) or some online website that does the job automatically. It’s recommended that your sound effect is 16-bit (99% of sounds are already 16-bit, unless you’re porting sounds from some game from the 90’s or before that) and in the range of 44100 or 48000 Hz, since these are the most common frequencies (and they can give you more sound quality than you’ll ever need). ##### Setting Up WWise After you’ve done that, it’s time to install & open WWise 2013 (yes, it must be the 2013 version). The first menu that will pop up is the Project Launcher. This is where all of your WWise projects will appear. To create a new project, just click on **New** and give your project a name. You can also change the location of your project folder if you so wish. Below these options there’s an import assets option that will add some extra presets, effects and models inside your project. These are quite big (heck one of them is 294 MB\!) and you really don’t need them, since WWise already has more than you’ll ever need in terms of effects or functionality. It’s recommended to turn them off. Besides, your project files will become huge anyway, so why make it waste even more space? ![](/assets/Project%20launcher%20assets.png) Finally, create your project by pressing **OK**. You will now be greeted with this pop up: ![](/assets/Wwise%20licensing.png) This is the biggest (and the only?) limitation of the free version of WWise. The program will only let you have 200 media items at once. The term “media items” basically refers to any sound file you’ve imported, so can only have 200 of them at all times. This isn’t a huge problem, since you can always just separate your project into many many smaller parts, and then make the game load all of them. But for now, we don’t have to worry about this, so just press on **Close**. Now, I can imagine people freaking out when seeing WWise for the first time, with all of its menus & buttons all over the screen. ![](/assets/Wwise%20is%20scary.png){:width="480px"} But no need to worry because for the purposes of this tutorial, we won’t be using 80% of the stuff you see on screen. Just like any program, you get used to it as time goes on. At this point I should also mention that AudioKinetic, the company that created WWise, has a lot of tutorials on YouTube about the many different things you can do with it (including Dialogue and Music). For this tutorial we’re going to do something very simple: import an audio file, and then create a new event that will activate this audio file so that it can start playing in the game. \== Importing Sound Files == Importing an audio file is easy, and can be done in two ways: either by right-clicking on the **Default Work Unit** of the **Actor-Mixer Hierarchy** on the top-left and choosing **Import Audio Files**: ![](/assets/Import%20method1.gif){:width="696px"} Or just doing a classic drag & drop onto the same **Default Work Unit**: ![](/assets/Import%20method2.gif){:width="696px"} If everything went well, you should see your audio file underneath the **Default Work Unit**. Again, I should mention that WWise only accepts non-8-bit .wav audio. If you want to preview what your sound *sounds* like, you can either press Space when you have it selected, or go at the bottom of the screen where the **Transport Control** menu is displayed, and press the play button. ##### The Sound Property Editor You might have noticed that, once the sound file is selected, a new menu appears at the middle of the screen, called **Sound Property Editor**. ![](/assets/Sound%20property%20editor.png){:width="828px"} This is where all of your sound properties are located. Here you can add any effect you can imagine. Low pass filter, high pass filter, pitch, reverb, echo, you name it\! The General Settings tab has the usual things like volume, pitch, and low pass filter. There’s also a loop tick box, which has to be enabled if you’re planning on making ambience or perhaps music, so that the sound doesn’t stop after it’s finished. If you want more advanced effects, go to the Effects tab, and play around with all the available effects (there’s a lot of them)\! ![](/assets/All%20the%20wwise%20effects.png){:.legacy-small width="369px"} As you can see, WWise is no joke. There’s a very good reason so many AAA game developer studios use it. Just imagine the amount of time it would’ve taken a studio to program all of this into their own sound engine from scratch\! Madness. But unfortunately for us, WWise makes sound modding a major pain, due to the way it’s been designed (the sound banks are only generated one-way, meaning that it’s extremely hard to reverse the process and see how they’ve been created. In other words, you can’t just open an .**sbp** and see what’s inside it). ##### Sound Positioning ###### The Two Positioning Types Another important setting is the type of positioning of the sound. This can be found in the **Positioning** tab. WWise 2013 lets us choose between 2 types of sound: **2D** and **3D** (more recent versions of this software have massively changed how this system works). As you might imagine, **2D** is for sound that has no specific direction, so it’s like it’s coming from everywhere. This is what you would expect from music, or radio calls. For environmental sound effects, **3D** is usually the better option. We won’t get into all the details for the settings of each one for this tutorial. But I’ll mention the most important bits. ###### 2D Positioning If you’re using **2D** positioning, then the only extra option you can use is **Enable Panner**, which lets you change the direction that the sound is coming from. This is useful for something like a horror map, where you would want the sound to be heard behind you no matter what\! 2D positioning can also be used for ambient sounds. However, since 2D positioning doesn’t have any attenuation, there will be no fade in or fade out effects, so the sound will immediately start playing at full volume when the player is in its radius. This should typically be used for very subtle ambient sounds inside buildings. For things like pipe noises, or machinery, use 3D instead. ###### 3D Positioning For **3D**, the settings are much more complicated, but I’ll keep it short. The **Position Source** should just be kept at **Game-defined**, so that they play at the exact position you’ve placed them in FoxKit or as you have defined it in your **fox2** sound entity. What you have to watch out for is the **Attenuation** option\! This controls how the sound fades in and out the more you approach it or move away from it, as well as the maximum distance from where it can be heard. If you do not create an **Attenuation**, then your sound will not have any fade in/out, and the sound will immediately play at full volume when you get close, it won’t sound right. For that reason, you should create one by pressing the **\>\>** button (under the **Attenuation** title) and then clicking on **New**. Give it a name and click **OK**. Now you’ll see the **Edit…** button unlock, which will bring you to the **Attenuation Editor** menu. ![](/assets/Making%20an%20attenuation.gif){:width="551px"} And here we are, we have yet another scary menu with so many settings & buttons\! This is a common theme with WWise, so you should get used to seeing this. ![](/assets/Scary%20attenuation%20menu.png){:width="580px"} But once again, it’s not too complicated. The **Curves** window you see at the bottom left define what property of the sound changes based on distance. In this case, only the **Output Bus volume** changes (the red one), which is the volume of the sound. You can also add a **Low-pass filter** and **Spread** effect for when the player moves more and more away from the sound (I can't figure out what Spread does though). Change the settings of **Curve** from **None** to **Custom** to do just that. Finally, here’s a simple demonstration of playing around with the curve by adding extra points and changing the curve type (double left click on a curve to make an extra point, right click to change its type): ![](/assets/Changing%20the%20curve.gif){:width="582px"} One rule of thumb is to make sure that the volume of the sound isn’t decreased too much in the first few meters. Otherwise, the volume will change very intensively when you’re close to it, which is a bit unrealistic if you’re going for very loud sounds. It can also become an annoyance, given that the volume changes based on the position of the player’s camera (which changes very fast), and not the player itself. But luckily, WWise makes this distance testing very easy\! The little **Distance \** box you see at the top of the graph is a button that you can move around, emulating how it would sound in the actual game\! This should always be used for fine-tuning the current configuration. If you want to learn more about the **Attenuation** settings, I will highly recommend you to check out [this](https://www.youtube.com/watch?v=AZuXuzDKJmw) tutorial by AudioKinetic. Also, [here](https://www.youtube.com/watch?v=bpjVT-Gdal8) is another tutorial for the **User-defined** position source setting when using 3D sounds. ##### Creating an Event Okay, so now we have our sound effect imported and its settings all configured properly\! But how do we create an event that will activate it? This is simple to do, and again, can be done in two ways (well actually three but I’ll show two). The first is to right click on the sound file, go to **New Event** and then **Play**. Give your event a name and you’re done\! ![](/assets/Event%20creation%20method1.gif){:width="717px"} The second way it to go to the **Events** tab in the project explorer, then click on the **Default Work Unit** under the **Events** folder, and press the **Create New Event** icon. Give your event a name, press enter and then select it, so that a new **Event Editor** menu pops up at the center of the screen (it’s important that it actually appears). Now, go to the **Audio** tab in the **Project Explorer** again, and then perform a drag and drop of your sound file inside the **Event Actions** window. Make sure you don’t accidently select the sound, or else the **Event Actions** window will be replaced with the **Sound Property** Editor. Done\! WWise will automatically pick **Play** as the action, so no need to touch anything else. ![](/assets/Event%20creation%20method2.gif){:width="717px"} I would recommend to always give your event name the “play_” prefix, just so that it easily helps you understand what it does if you forget later. Events can do a lot more than just tell a sound to play or stop, which is why prefixes like these are always useful to have. Although if you’re making ambient sounds, you don’t have to do this, since they’re never supposed to stop playing at any time anyway. For instance, TPP always just uses the **sfx_** prefix for its ambient sounds, but does use **play_** for other cases, such as background music. At this point it’s worth mentioning that the event name is what we’ll use to tell the game to play the sound. So if you named your event **sfx_ambientsound_0000**, then this string is what the game will use to play it. The sound files (which are converted to **.wem** when building a sound bank) don’t do anything by themselves, they’re just the raw sound data. Every single sound you hear in the game is played through an event. ##### Creating & Building a Sound Bank ###### Creating the Bank Alright, now that we’ve done that, it’s time to build the sound bank\! We’ll have to create it by going to the **SoundBanks** menu in the **Project Explorer**, then selecting the **Default Work Unit** under the **SoundBanks** folder icon and clicking the small **Create New SoundBank** icon a bit above that. Give it a name. Now if you click on it, you’ll notice that nothing happens\! This is because we’re using the **Designer** layout, which is what WWise defaults to. We can change this by going to **Layouts** at the very top of the screen and selecting **SoundBank**, or just by pressing F7 (use F5 to go back to **Designer**). These layouts are useful to have, depending on what you’re working on. For music, there’s the **Interactive Music** layout. For dialogue, you have the **Dynamic Dialogue** and so on. ![](/assets/Creating%20soundbank.gif){:width="646px"} ###### Configuring the Sound Bank Now that we’ve changed to the SoundBank layout, we have yet another new menu: the SoundBank manager\! This is where we have the configuration for the soundbank(s) we want to build. In our case, there’s only one sound bank, right under the **Default Work Unit** (make sure you expand it by pressing the **+** button). You will also notice a check box next to it. The sound banks that are ticked are the ones that will be generated when you press the **Generate** or **Update** buttons. But before we build the sound bank, we will also have to configure what will be contained inside it. WWise doesn’t know what should or should not be included in a sound bank automatically, so it has to be done the manual way. But it’s very easy to do. All that’s required is a simple drag and drop of your events and sounds into the sound bank. But you don’t have to select every single one if you have a lot of them. Instead, you can drag all of your Default Work Units onto the sound bank, and WWise will handle the rest for you. Doing this means that everything that’s inside the Default Work Units will automatically be included in the sound bank. That is, of course, if those sounds are ticked. That’s what the tick boxes next to the sounds are for. Excluding sounds is as simple as unticking their tick boxes. Here’s this entire process in a GIF: ![](/assets/Configuring%20soundbank.gif){:width="742px"} ###### Building the Sound Bank! Okay, so now that everything’s configured, it’s time to build the sound bank\! WWise lets you create a sound bank for many different systems, such as Windows, Mac, iOS and Android, as well as for different languages. But for MGS:V, we only use Windows, and English (unless you want to implement dialogue in many different languages). Don’t worry if you’re using Linux or Mac, these options only exist if the developer wants to do things differently for every platform. For MGS:V, you’ll never need to do this. So, all you have to do now is tick the **Default Work Unit** (and then the sound bank will also be ticked), and then go to the other menus on the right and tick **Windows** and **English (US)**. And finally, press **Generate**\! ![](/assets/Generating%20soundbank.gif){:width="956px"} Congratulations\! You’ve created your very first sound bank\! But where was it saved? The answer is: in your project folder, and then in GeneratedSoundBanks and Windows. By default, your project folder is in your **Documents/WwiseProjects** folder. You will find two soundbank files: **Init.bnk** and **\.bnk**, as well as some more miscellaneous files. For the purposes of MGS:V, we leave **Init.bnk** alone. The second bank is what we want. It stores your sound files, as well as any events and anything else you’ve done with your project. Something that you might’ve noticed by now is that WWise creates **.bnk** files, but MGS:V uses **.sbp**, so what gives? We should just rename the bnk to sbp and that should be enough, right? Well, no\! Sbp files are a little bit different from bnk, but not that different. They include some unique sections that are never found in a bnk. Fortunately, we only need one of those sections for this custom sound bank to work, and it’s easy to do\! ##### Hex-Editing the Generated Bank ###### Adding the SBPL Section Remember how I mentioned at the start of the tutorial that you’ll need a hex editor? Well, now we’re going to use it. We’re going to modify the sound bank (no, not **Init.bnk**, the other one that has the same name as your sound bank in WWise) and add a new section, which has the signature of **SBPL**. So, open it up with HxD or the hex editor of your choice, and you should be greeted with something like this: ![](/assets/Hex%20editor%20sound%20bank.png){:width="760px"} This is the binary representation of your custom sound bank in a hexadecimal format. All that needs to be done is a simple copy + paste, and a small change in an integer. The **SBPL** section that I mentioned is always contained at the start of the file, so that makes the job even easier. Here’s the hex bytes you’ll need to copy and paste: `53 42 50 4C 01 14 00 00 62 6E 6B 00 20 00 00 00 83 73 C7 01 00 00 00 00 00 00 00 00 00 00 00 00` (Ctrl + C and Ctrl + V, or right click and Paste Insert). But make sure that you’ve selected the first hex byte of the file, so that the cursor is at the very start of the file: ![](/assets/Hex%20byte%20placing.gif){:width="755px"} And of course, make sure that the new hex bytes are inserted into the file, and it doesn’t replace the **BKHD** section below. If it does that, then you can press your insert key to change the write type to **Insert** instead of **Overwrite**. But wait, there’s more\! ###### Updating the SBPL Section Size Integer This section that we just pasted in has an unsigned integer that holds a size. We won’t get into the details of what it is, but it has to be updated for every sound bank you make. Calculating the new value is easy. All you have to do is select the entire file in your hex editor (or just Ctrl + A), and see the length of this selection, which is usually mentioned at the bottom of the screen. In HxD it’s referred to as “length”, and by default it’s stored in a hexadecimal format (you can verify this if there’s an (h) next to “length”). If this is the case, you’ll have to convert it back to decimal using the good old calculator (if your calculator can convert between decimal and hexadecimal that is. For Windows 10, change the calculator category from Standard to Programmer). After the conversion, subtract 32 from this number (32 when in decimal, or 20 in hexadecimal). This is the new value we’ll have to replace. For instance, if the length of the file is **DA28200**, converting it to decimal gives us **228753920**, and subtracting 32 from that is – hey\! This isn’t first grade math class\! But where do we replace this integer? The answer is, at the offset 0x10 in hexadecimal, or 16 in decimal, from the start of the file. The hex editor of your choice must have a “Go to” menu that comes in handy for doing this. Usually the shortcut is Ctrl + G. After going to this location, we use the **Data Inspector** on the right, and replace the integer that way. Make sure you replace the variable in the **UInt32** section (or just **Int32** if the number isn’t larger than 2 billion), because we’re modifying a 32 bit integer. ![](/assets/Replacing%20integer%20wwise%20soundbank.gif){:width="755px"} Now we’re done\! So, go to File -\> Save As, and save your file with the extension of **.sbp**. This is our final sound bank file that the game will read. If you ever make any changes to your sound bank, you’ll have to re-do this process again. As of writing this tutorial, there isn’t a program that automatically does this. Beware though: if this number is incorrect, the sound bank may not work\! ##### Setting Up the Mod Files ###### Explanation We are finally done with the WWise part of this tutorial\! The rest will explain how to add the sound bank in a mod and also add the necessary files so that the game loads it properly. This step is required, regardless of how the actual sound is used in the game. The process isn’t hard to do, but it will feel like chaos when done for the very first time (same goes for WWise or anything Fox Engine related really). There are two necessary files needed in order for TPP to load a sound bank: a **fox2**, also known as a **DataSet** file, and an **sdf**. The **fox2** will load the **sdf**, which in turn will load the custom sound bank (**sbp** file). Depending on where you want to use the sound bank, both of these files will exist in different folders. For a custom mission, for example, both of them will be in your mission’s **fpkd** file. For a custom location, they will typically be inside the “common” **fpkd** file of said location, and so on. However, the path to the sound bank will always be the same. All sound banks in TPP (and GZ) are always stored in **/Assets/tpp/sound/asset/**. It can’t be any other folder, and it must not be in an **fpk** or **fpkd**. In other words, it has to exist in the root location of your mod’s folder. For example, if your soundbank is named **testbank.sbp** and your mod folder is called **MyMod**, then the path will be **MyMod/Assets/tpp/sound/asset/testbank.sbp**. For beginners, notice the capital ‘**A**’ in **Assets**. It has to be capitalized, due to the way the game handles the file paths by turning them into a hash. Likewise, **tpp**, **sound** and **asset** have to be lowercase. ###### The Fox2 File Now, here’s a simple example of a **fox2** xml file that loads an **sdf** (you can copy it if you want): ``` xml 0x00000000 0x05A7B300 0x05047390 example_soundbank 0x05A7B290 /Assets/tpp/sound/package/example_soundbank.sdf false TexturePackLoadConditioner0000 0x05A7B290 ``` As you can see, it loads the **sdf** file at the specified folder. That folder path should point to the **sdf** inside your **fpkd**, and not in some **sdf** at the root folder of your mod, because that’s very messy and unorganized. If you rename your **sdf** name in the path to something else, make sure the actual file has the same name, or else the game won’t find it and it will be very hard to track down the problem. Note: The name and path of the **fox2** file doesn’t matter (it has to be inside an **fpkd** though). The game always “opens” any **fox2** file that it can find automatically. This isn’t the case for **sdf**, which is why we need a **fox2** to load that one. The **SoundPackage** entity in the **fox2** has a **syncLoad** setting, but what it does is unknown. Perhaps it forces the game to load the sound bank when you’re in a loading screen, instead of when it’s actually required? ###### The Sdf File Next up is the **sdf** file. Now this one is what actually loads the sound bank. Again, here’s another example of a simple one: ``` xml 0x00000000 0x05A7C020 SoundDataFileInfo0000 0x05A7C250 example_soundbank ``` As you can see, this time we don’t have a path, but only the name of the sound bank, without the extension. This is why I mentioned that the path to the sound bank must be **/Assets/tpp/sound/asset/**, it’s hard-coded. And again, the actual sound bank (**.sbp**) must not be in any **fpk** or **fpkd** file, but in the root location of your mod’s folder. Change the **loadBanks** string to your sound bank’s name (without the **.sbp** extension) and you’re done\! Also, don’t touch the **prepareBanks** or the **prepareEvents** options. I’ve never seen them being used anywhere in the game anyway. Never forget to re-build your **fox2** and **sdf** files when you update their corresponding **xml** using **FoxTool**\! It’s very easy to miss. You can always just check the last modified date to verify. Also, I have to mention again that the name of the event is what’s actually used to play the sound, not the name of the sound itself\! This is true for anything you’re using the sound for. Dialogue, ambience, background music, anything. The name of the sound file doesn’t matter in the end. What matters is the name of the event that plays it. For example, here’s how it’s done for an ambient sound: ![](/assets/Event%20name%20to%20eventName%20property.png){:width="790px"} ##### Conclusion That’s basically it for the tutorial\! If everything went well, your custom sound bank should work in the game\! If you want a quick way to test if it really worked, you can use some of TPP’s lua commands that play events, such as: `TppSoundDaemon.PostEvent(“Your event name here”)` or, `TppSoundDaemon.PostEvent3D("Your event name here",Vector3(1, 2, 3) )` for 3D sounds (change the 1, 2, 3 to your desired coordinates). These can be used in a custom mission’s **sequence.lua**, or the empty mission of a custom location (also known as “free roam”). If you’re making ambient sounds, then you should use the **SoundSource** or **TppAmbientSoundWorld** entities for that purpose (those are entities in **fox2** files). Just replace the **eventName** with the name of your event, and update the **playRange** accordingly. Also, set the **volumeRtpc** to **ambient_volume**. As a final note: you might have noticed that the custom sound is quite loud in-game. This is because the volume is the same as the original sound .wav file, which is usually as loud as it can be. The easiest solution to this is to just decrease the volume in WWise, in the **General Settings** of the sound. However, this isn’t how the game’s sounds actually fix this problem. The actual solution would be to use the correct Audio Bus that the game has for the specific scenario (ambient sounds, dialogue etc). But this isn’t well known territory, so even I don’t have the answer as to what Audio Bus should even be used for every case. Unfortunately, we only know too few of the hashes of the names of the game’s audio busses, which makes it very hard to identify what audio bus does what (since the hashes are just numbers). But I don’t think this is a huge concern, because the sound will work perfectly fine, even if it uses the default Master Audio Bus. Although a bizarre bug has been found, where sometimes a sound doesn’t get muted when the game is paused. No one knows the cause of that as of yet. Even some of TPP’s ambient sounds suffer from this issue (the flag in Wakh Sind Barracks, for instance). ##### Troubleshooting If the custom sound bank doesn’t work, here’s the most common causes: 1. The **xml** files of either the **fox2** or the **sdf** were not run through FoxTool after being changed (so just drag and drop the xml one by one into FoxTool and the file will be generated). 2. The path to the **sdf** in the **fox2** file is incorrect. This is very easy to miss. 3. The sound bank file (**.sbp**) is not inside **\/Assets/tpp/sound/asset/**. 4. The sound bank name in the **sdf** is misspelled. ### `wiki:wiki/DFRM.md` The .dfrm, short for **d**e**f**o**rm**, is the format believed to be used for morph targets in Metal Gear Solid V: The Phantom Pain. Much like the .fmdl, it is a Little-Endian format, meaning bytes are written in reverse order of significance. i.e. 00 00 A2 2B, would be read as: 2B A2 00 00 ##### Structure The .dfrm file is split into sections. The known/suspected sections are: - 0x0 - 0x40: Header. - 0x40 - 0xC: Section 1. - 0xC - 0x6160: Section 2. - 0x6160 - 0x6BE0: Section 3. - 0x6BE0 - 0x9D00: Section 4. - 0x9D00 - 0x17660: Section 5. - 0x17660 - End Of File: Section 6. ##### Header - 0x0 - 0x3 (string): Signature. "DFRM". - 0x4 - 0x7 (float): 1.0. - 0x8 - 0xB (uint): Length of the header. - 0xC - 0xF (uint): Number of entries in section 1. - 0x10 - 0x13 (uint): Number of entries in section 2. - 0x14 - 0x17 (uint): Number of entries in section 3. - 0x18 - 0x1B (uint): Number of entries in section 4. - 0x1C - 0x1F (uint): Number of entries in section 5. - 0x20 - 0x23 (uint):Number of entries in section 6. PLACEHOLDER ##### Resources - [010 Editor Template](https://gist.github.com/Joey35233/6fd79695e34db56b37e656b3460bdfd7) ### `wiki:wiki/Damage_Tables.md` Recommended reading. To get a good overview of each of the values for editing the hand-to-hand and CQC damage values I recommend having a look at the following spreadsheet of the damage value parameters. Also, Muffins' has created his own notes about what each value of the damage array does. The following comes from his 4PR mod and I highly recommend reading through that mod as it's mostly intended to be self-documenting: ```lua this.DamageParameter={ -- I'm trying to make sense of this mess. For now I gave up so yeah. -- {TppDamage.ATK_10001, -- D114/M1911 ATTACK -- 750,-- Displays Lethal Damage UI -- 500, -- ??? -- 40,-- ??? -- 0,-- ??? -- 0,-- ??? -- 300,-- ??? -- 90,-- ??? -- TppDamage.INJ_TYPE_BULLET, -- TppDamage.INJ_PART_ALL, -- 15,-- ??? -- 2,-- ??? -- 1,-- Projectile Hitting NPCs Boolean -- 0, -- 0,-- Vortex Ring Boolean? -- 0,-- Tranquilizer Boolean, Requires Non-Lethal Damage Value -- 0,-- Stun Damage Boolean, Requires Non-Lethal Damage Value -- 0, -- 0, -- 0, -- 0, -- Fire Boolean -- 0, -- 0,-- Gas Boolean? -- 0, -- 0, -- 0,-- Electric Boolean? -- 0, -- 0, -- TppDamage.DAM_SOURCE_Handgun, -- 400,-- Lethal Damage Value -- 0,-- Non-Lethal Damage Value -- 300},-- Impact Force ``` For the CQC in particular, we're most interested in the last 3rd-to-last and 2nd-to-last values so we can make various throws, punches, kicks, etc lethal or non-lethal. As Muffins notes, the damage table has to have the Stun damage boolean flipped to 1 so the NL damage will be applied. ##### **Damage lethality:** Enemies have roughly between 2500 and 3000 health by default. In terms of outright killing an enemy and putting them into an 'injured' state where they roll on the ground in agony before dying, the difference is about 500 points of damage or so. In layman's terms: **Injured state:** 2000 points of damage. **Kill:** 3000-4000 points of damage. ##### CQC notes for DamageParametersTables.lua: or what damage table gets applied when I throw or punch someone ###### Punches: These are damage modifiers and I believe they don't stack when comboing per se. i.e if atk_punch1 is set as a one hit kill, doing a atk_punch2 that's set as a non-lethal attack will knock out the target and totally bypass atk_punch1's damage values. **atk_punch:** Part of the front-facing 5 punch combo **atk_punch1:** Your standard single button melee punch. **atk_punch2:** Used as part of the "back facing 3 punch combo" cinematic combo and the 2 or 3 punch/kick combo where you stop and don't finish the full combo. **Kick:** Standing kick. **KickDown:** Kick when an enemy is down. A small amount of damage is applied, so the target wakes up, but the majority of damage is stun. ###### CQCHit types: **CQCHit:** "counter attack" hit when the player activates the cinematic combo to stop an enemy hitting them with the butt of their gun. **CQCHitFinish:** Used as part of the back facing 3 punch combo and the front facing 5 punch combo. **CQCFinish:** Used as part of the front facing 5 punch combo. ###### Throws: **CQCThrow:** Standard standing throw from the front, as well as the knife disarm cinematic throw when the enemy attempts to slash the player. **CQCHoldThrow:** Throw when you have an NPC grappled. **CqcThrowBehind:** Standard standing throw from behind. **CqcThrowLadder:** Throwing someone off a ladder using the 'grab' prompt. **CqcContinuous2nd:** Damage applied to the 2nd person in a CQC chain throw. **CqcContinousOver3Times:** Damage applied to the 3rd and 4th person (and so on) in a CQC chain throw. __FORCETOC__ ### `wiki:wiki/DataSet.md` DataSet / DataSet2 entities are represented as .fox2 files. It contains a list of every entity used in that particular dataset, presumably used as a table referenced by the editor to enumerate the various objects placed therein. ##### Usage Header: ```xml ``` The only header property known is *addr*. This header property indicates where in the .fox2 the beginning of the **DataSet** entity is located. *unknown1* and *unknown2* remain just that; their usage and importance remains a mystery. Following the header block are three property blocks: *name*, *dataSet*, and *dataList*. *name* follows the following convention and is usually left empty in a **DataSet**: ```xml ``` Following *name* is *dataSet*, a property common to all Fox entities. As a **DataSet** entity is necessarily not contained by itself or another **DataSet**, this field is usually zeroed, like so: ```xml 0x00000000 ``` The *value* subblock is a pointer to the **DataSet** entity, if this entity belongs to a **DataSet**. Typically you may acquire the value of this field by observing the *addr* property in the header block of the **DataSet**. It should be the same for all entities in the .fox2. Following *dataSet* is *dataList*, which is the property block that actually contains the list of entities used in a given .fox2. It has a format like the following: ```xml 0x02D7E010 0x0827ADC0 ``` Each value block contains one property, *key*, which is equivalent to the *name* static property of the given entity. The value itself is a pointer to that entity, given by the *addr** header block property of that given entity. The size of the **DataSet** is variable, depending on the number of entries listed in *dataList*. ### `wiki:wiki/EXE_Memory_Tags.md` Memory tags are used by various memory allocation functions, such as `BlockHeapAlloc`. These tags are used during garbage collection. ##### TPP (PS4) - Unnamed: 0x1 - String: 0x2 - JobTask: 0x3 - Kernel Core: 0x4 - Lua: 0x5 - Sound: 0x7 - Audio: 0x8 - Anim: 0x9 - Geo: 0xa - Cc: 0xb - Nav: 0xc - Fx: 0xd - Ui: 0xe - GrSystem: 0xf - GrResource: 0x10 - GrResource: 0x11 - FoxGameKit: 0x12 - Ph: 0x15 - Sim: 0x16 - Des: 0x17 - Network: 0x18 - Demo: 0x19 - Grx: 0x1b - Fs: 0x1c - Block: 0x1d - UiScene: 0x1e - GameCore: 0x20 - FoxQuark: 0x21 - GameService: 0x22 - TppSystemBase: 0x29 - tpp MotherBase: 0x2a - tpp MotherBaseStage: 0x2b - MotherBaseManagement: 0x2c - tpp System: 0x2d - TppSystem2: 0x2e - Uav: 0x32 - SecurityCamera: 0x33 - Buddy: 0x35 - Boss: 0x37 - Animal: 0x39 - Vehicle: 0x3d - MultiPlayer: 0x3f - TppNewCharacter: 0x41 - Soldier: 0x42 - Soldier: 0x43 - Soldier: 0x44 - Soldier: 0x45 - Soldier: 0x46 - Hostage: 0x47 - TppPlayer: 0x48 - Parasite: 0x49 - Heli: 0x4a - Corpse: 0x4b - Corpse: 0x4c - CommandPost2: 0x4d - MbQuiet: 0x4e - Equip: 0x58 - EquipPreview: 0x59 - Bullet: 0x5a - Pickable: 0x5b - Throwing: 0x5c - Shell: 0x5d - Placed: 0x5e - Collection: 0x5f - FultonBalloon: 0x60 - SupportAttack: 0x62 - RangeAttack: 0x63 - Decoy: 0x65 - Casing: 0x66 - Dung: 0x67 - tpp HighSpeedCamera: 0x6a - Gimmick: 0x6b - Gc Gimmick: 0x6c - Collectible: 0x6d - tpp Effect: 0x6e - Tpp Sound: 0x6f - tpp Ui: 0x70 - TppRadio: 0x71 - tpp Network: 0x73 - tpp Gk: 0x75 - POI Core: 0x78 - Ruleset Core: 0x79 - Script Util: 0x7a - Unnamed Object: 0x10001 - CString Data(String): 0x10002 - Job: 0x10003 - Kernel: 0x10004 - Sound Core System: 0x10007 - Audio System: 0x10008 - AnimControl: 0x10009 - Geo File: 0x1000a - CcControl: 0x1000b - NavSystem: 0x1000c - FxTempWork: 0x1000d - UiFile: 0x1000e - Gr Plugin: 0x1000f - Gr Resource: 0x10010 - Gr Model: 0x10011 - GkSystem: 0x10012 - Ph Core: 0x10015 - Sim Object: 0x10016 - Des Object: 0x10017 - Network System: 0x10018 - DemoEntity: 0x10019 - Grx System: 0x1001b - Fs File: 0x1001c - UiColorGrp: 0x1001e - GameCoreSystem: 0x10020 - FoxQuarkSystem: 0x10021 - GameService System: 0x10022 - MotherBaseManagement System: 0x1002c - TppSystem2Mission: 0x1002e - Uav System: 0x10032 - SecurityCamera System: 0x10033 - Buddy System: 0x10035 - Boss System: 0x10037 - Animal System: 0x10039 - Vehicle System: 0x1003d - NewChara System PassengerInfo: 0x10041 - Soldier System: 0x10042 - Soldier GameObject: 0x10043 - Soldier UnrealBasic: 0x10044 - Soldier UnrealCqc: 0x10045 - Hostage System: 0x10047 - Parasite System: 0x10049 - Heli System: 0x1004a - Corpse System: 0x1004b - Corpse Ai: 0x1004c - CommandPost2 GameObject: 0x1004d - MbQuiet System: 0x1004e - Equip System: 0x10058 - EquipPreview System: 0x10059 - Bullet System: 0x1005a - Pickable System: 0x1005b - Throwing System: 0x1005c - Shell System: 0x1005d - Placed System: 0x1005e - Collection System: 0x1005f - FultonBalloon System: 0x10060 - Casing System: 0x10066 - Gimmick Base: 0x1006b - Tpp Effect Uncategorized: 0x1006e - Tpp Sound System: 0x1006f - tpp Ui UnNamed: 0x10070 - Unnamed HashMap: 0x20001 - CString Data(Const String): 0x20002 - Task: 0x20003 - Log: 0x20004 - Sound Core Control: 0x20007 - Audio Object: 0x20008 - AnimFile: 0x20009 - Geo System: 0x2000a - CcModules: 0x2000b - NavPathfind: 0x2000c - FxJob: 0x2000d - UiGraphFile: 0x2000e - Gr PluginResource: 0x2000f - Gr Fmdl: 0x20010 - Gr ModelArray: 0x20011 - GkPartsData: 0x20012 - Ph World Memory: 0x20015 - Sim Work: 0x20016 - Des Util: 0x20017 - Network Debug: 0x20018 - DemoObject: 0x20019 - Grx Atmosphere: 0x2001b - Fs Path Resolver: 0x2001c - Block System: 0x2001d - UiCamera: 0x2001e - GameCoreObject: 0x20020 - GameService GsRoute: 0x20022 - tpp MBCoreUnNamed: 0x2002a - MotherBaseManagement Staff: 0x2002c - TppSystem2Location: 0x2002e - Uav Ai: 0x20032 - SecurityCamera Base: 0x20033 - Buddy Base: 0x20035 - Boss Controller: 0x20037 - Animal Base: 0x20039 - Vehicle Data: 0x2003d - MultiPlayer System: 0x2003f - NewChara System: 0x20041 - Soldier ParamTable: 0x20042 - Soldier Ai: 0x20043 - Soldier RealBasic: 0x20044 - Soldier RealCqc: 0x20045 - Hostage base: 0x20047 - Player System: 0x20048 - Parasite Base: 0x20049 - Heli Base: 0x2004a - Corpse Synchronizer: 0x2004b - Corpse CoreAi: 0x2004c - CommandPost2 Impl: 0x2004d - MbQuiet Ai: 0x2004e - Equip Base: 0x20058 - Bullet Base: 0x2005a - Pickable Base: 0x2005b - Throwing Base: 0x2005c - Shell Base: 0x2005d - Placed Base: 0x2005e - Collection Base: 0x2005f - FultonBalloon Base: 0x20060 - Casing Base: 0x20066 - Gimmick Save: 0x2006b - Tpp Effect Filter2D: 0x2006e - Tpp Sound Ambient: 0x2006f - tpp Ui System: 0x20070 - TppRadioSystem: 0x20071 - tpp Gk System: 0x20075 - POI Base: 0x20078 - Ruleset Base: 0x20079 - Script Util System: 0x2007a - Unnamed StringMap: 0x30001 - CString Data(Path): 0x30002 - Perf: 0x30003 - Hid: 0x30004 - Sound Core Debug: 0x30007 - Audio Object: 0x30008 - GraphControl: 0x30009 - Geo BVH: 0x3000a - NavNavigation: 0x3000c - FxEffectUser: 0x3000d - UiLayoutFile: 0x3000e - Gr ResourceWork: 0x3000f - Gr ModelResource: 0x30010 - Gr ModelCut: 0x30011 - GkPartsBuilder: 0x30012 - Ph Core Resource: 0x30015 - Sim Data: 0x30016 - Des File: 0x30017 - DemoFunctor: 0x30019 - Grx ColorCorrection: 0x3001b - Fs Debug: 0x3001c - Block Internal System: 0x3001d - UiCameraData: 0x3001e - GameCorePlugin: 0x30020 - GameService GsSightCheck: 0x30022 - tpp MBCoreConstruct: 0x3002a - MotherBaseStageSystem: 0x3002b - MotherBaseManagement EquipDevelop: 0x3002c - tpp MissionBlockSystem: 0x3002d - TppSystem2GameService: 0x3002e - Uav Action: 0x30032 - SecurityCamera Ai: 0x30033 - Boss Ai: 0x30037 - Animal Controller: 0x30039 - Vehicle GameObject: 0x3003d - NewChara System Anim: 0x30041 - Soldier FaceSystem: 0x30042 - Soldier DEBUG: 0x30043 - Soldier UnrealAttack: 0x30044 - Soldier UnrealLadder: 0x30045 - Hostage fova: 0x30047 - Player Avator: 0x30048 - Parasite Controller: 0x30049 - Heli Controller: 0x3004a - Corpse FovaResource: 0x3004b - Corpse CarriedAi: 0x3004c - CommandPost2 RoleController: 0x3004d - MbQuiet Action: 0x3004e - Equip Data: 0x30058 - Bullet Data: 0x3005a - Gimmick System: 0x3006b - Tpp Effect LensFlareData: 0x3006e - Tpp Sound Area: 0x3006f - tpp Ui CommonData: 0x30070 - Unnamed SharedObject: 0x40001 - KernelString: 0x40002 - Scratch: 0x40003 - Crypt: 0x40004 - Sound System: 0x40007 - Audio Object: 0x40008 - MotionGraph System: 0x40009 - Geo Collision: 0x4000a - NavNavigationFile: 0x4000c - FxUnnamedContainer: 0x4000d - UiModelFile: 0x4000e - Gr ResidentResourceWork: 0x4000f - Gr CloneResource: 0x40010 - Gr ModelVertexColor: 0x40011 - GkPartsDirector: 0x40012 - Ph Object: 0x40015 - Sim Param: 0x40016 - Des Job: 0x40017 - DemoEditor: 0x40019 - Grx FacialTexture: 0x4001b - Block Package System: 0x4001d - UiAnim: 0x4001e - GameCoreAgent: 0x40020 - GameService Debug: 0x40022 - tpp MBCoreNetwork: 0x4002a - tpp MotherBaseStageBlockSystem: 0x4002b - MotherBaseManagement WeaponPartsDevelop: 0x4002c - tpp SystemLocation: 0x4002d - TppSystem2Luxury: 0x4002e - Uav DEBUG: 0x40032 - SecurityCamera Plugin: 0x40033 - Buddy Controller: 0x40035 - Boss Plugin: 0x40037 - Animal Ai: 0x40039 - Vehicle UnrealInstance: 0x4003d - NewChara System Effect: 0x40041 - Soldier FovaSystem: 0x40042 - Soldier SysUtil: 0x40043 - Soldier RealAttack: 0x40044 - Soldier RealLadder: 0x40045 - Hostage Controller: 0x40047 - Parasite Ai: 0x40049 - Heli Ai: 0x4004a - Corpse Quark: 0x4004b - Corpse StandbyVehicleAi: 0x4004c - CommandPost2 RoleCoder: 0x4004d - MbQuiet DEBUG: 0x4004e - Gimmick Ladder: 0x4006b - Tpp Effect LensFlareInstance: 0x4006e - Tpp Sound Music: 0x4006f - tpp Ui MenuTermina;: 0x40070 - tpp Gk Marker: 0x40075 - Unnamed STL: 0x50001 - SharedString: 0x50002 - Debug: 0x50004 - Sound Action: 0x50007 - Audio Object: 0x50008 - GraphDataFile: 0x50009 - Geo Trap: 0x5000a - NavBounder: 0x5000c - FxFootPrint: 0x5000d - UiAnimFile: 0x5000e - Gr Font: 0x5000f - Gr MaterialResource: 0x50010 - Gr ModelDeform: 0x50011 - GkEnvironment: 0x50012 - Ph Data: 0x50015 - Sim Util: 0x50016 - Network Nt System: 0x50018 - DemoLocator: 0x50019 - Grx Fog: 0x5001b - Block Memory: 0x5001d - UiAnimData: 0x5001e - GameCoreSynchronizer: 0x50020 - MotherBaseManagement Base: 0x5002c - tpp SystemMission: 0x5002d - TppSystem2Script: 0x5002e - Uav DUMMY: 0x50032 - SecurityCamera DEBUG: 0x50033 - Buddy Ai: 0x50035 - Boss Action: 0x50037 - Animal Plugin: 0x50039 - Vehicle Constant: 0x5003d - NewChara System AiController: 0x50041 - Soldier FovaResource: 0x50042 - Soldier SysFace: 0x50043 - Soldier UnrealMeleelAttack: 0x50044 - Soldier UnrealStep: 0x50045 - Hostage Ai: 0x50047 - Parasite Plugin: 0x50049 - Heli Plugin: 0x5004a - Corpse Realizer: 0x5004b - Corpse DamageAi: 0x5004c - CommandPost2 RadioController: 0x5004d - MbQuiet DUMMY: 0x5004e - Equip Debug: 0x50058 - EquipPreview Debug: 0x50059 - Bullet Debug: 0x5005a - Pickable Debug: 0x5005b - Throwing Debug: 0x5005c - Shell Debug: 0x5005d - Placed Debug: 0x5005e - Collection Debug: 0x5005f - FultonBalloon Debug: 0x50060 - Casing Debug: 0x50066 - Gimmick Shared: 0x5006b - Tpp Effect BridgeFunctor: 0x5006e - Tpp Sound Music Player: 0x5006f - tpp Ui CustomNode: 0x50070 - tpp Gk CoverPoint: 0x50075 - Unnamed SPContainer: 0x60001 - SharedStringPool: 0x60002 - Core Entity: 0x60004 - Sound Anim: 0x60007 - Audio Frame: 0x60008 - MotionGraph File: 0x60009 - Geo TrapModule: 0x6000a - NavGeneration: 0x6000c - FxInstanceBlock: 0x6000d - UiEditData: 0x6000e - Gr StringBuffer: 0x6000f - Gr RenderStateResource: 0x60010 - Gr ModelExtMatrix: 0x60011 - GkWind: 0x60012 - Ph Param: 0x60015 - Sim Association: 0x60016 - DemoStreamAnim: 0x60019 - Grx Light: 0x6001b - Block Head Files: 0x6001d - UiModel: 0x6001e - GameCoreDebug: 0x60020 - MotherBaseManagement Resource: 0x6002c - tpp SystemGameSequence: 0x6002d - TppSystem2Misc: 0x6002e - SecurityCamera DUMMY: 0x60033 - Buddy Plugin: 0x60035 - Boss DEBUG: 0x60037 - Animal DEBUG: 0x60039 - Vehicle Realizer: 0x6003d - NewChara System AiNode: 0x60041 - Soldier Synchronizer: 0x60042 - Soldier BlockController: 0x60043 - Soldier RealMelleeAttack: 0x60044 - Soldier RealStep: 0x60045 - Hostage Plugin: 0x60047 - Parasite DEBUG: 0x60049 - Heli DEBUG: 0x6004a - Corpse Authorizer: 0x6004b - Corpse NormalAi: 0x6004c - CommandPost2 SpeechHandler: 0x6004d - Equip Todo Delete: 0x60058 - Gimmick Permanent: 0x6006b - Tpp Effect FxModule: 0x6006e - Tpp Sound Interference: 0x6006f - tpp Ui SaveData: 0x60070 - tpp Gk Bush: 0x60075 - Unnamed MemoryAnalyzer: 0x70001 - SharedPathPool: 0x70002 - Lua Entity: 0x70004 - Sound Area: 0x70007 - Audio Physical: 0x70008 - AnimSystem: 0x70009 - Geo Target: 0x7000a - NavDebug: 0x7000c - FxInstance: 0x7000d - UiFont: 0x7000e - Gr TextureStream: 0x7000f - Gr ShaderResource: 0x70010 - Gr ModelReader: 0x70011 - GkTerrain: 0x70012 - Ph Association: 0x70015 - Sim Cloth: 0x70016 - Network Ncl System: 0x70018 - DemoStreamLocator: 0x70019 - Grx LightAccessor: 0x7001b - Block Tail Files: 0x7001d - UiModelData: 0x7001e - MotherBaseManagement DataBase: 0x7002c - tpp SystemWeather: 0x7002d - TppSystem2Debug: 0x7002e - Buddy DEBUG: 0x70035 - Boss DUMMY: 0x70037 - Animal DUMMY Data: 0x70039 - Vehicle RealInstance: 0x7003d - NewChara System AiKnowLedge: 0x70041 - Soldier Quark: 0x70042 - Soldier BlockControllerImpl: 0x70043 - Soldier UnrealGrenade: 0x70044 - Soldier UnrealStdbyVehicle: 0x70045 - Hostage DEBUG: 0x70047 - Parasite DUMMY: 0x70049 - Heli DUMMY: 0x7004a - Corpse PlugCore: 0x7004b - Corpse DEBUG Ai: 0x7004c - CommandPost2 ActionController: 0x7004d - Gimmick Identifier: 0x7006b - Tpp Effect Weather: 0x7006e - tpp Ui Ending: 0x70070 - tpp Gk Grass: 0x70075 - Unnamed Others: 0x80001 - SharedPathPoolSub: 0x80002 - Entity Info: 0x80004 - Sound Physics: 0x80007 - Audio AllocHook: 0x80008 - GraphElementFile: 0x80009 - Geo Area: 0x8000a - NavWorld: 0x8000c - FxInstancePreData: 0x8000d - UiGraph: 0x8000e - Gr RenderBuffer: 0x8000f - Gr ShaderFileResource: 0x80010 - Gr OptCamModel: 0x80011 - GkPad: 0x80012 - Ph Association Data: 0x80015 - Sim Job: 0x80016 - DemoStreamParts: 0x80019 - Grx LightArray: 0x8001b - Block Stage Common: 0x8001d - UiModelNode: 0x8001e - tpp SystemWeatherWork: 0x8002d - Buddy DUMMY: 0x80035 - Animal DUMMY Instace: 0x80039 - Vehicle Body: 0x8003d - NewChara System Situation: 0x80041 - Soldier Realizer: 0x80042 - Soldier BlockGroup: 0x80043 - Soldier RealGrenade: 0x80044 - Soldier RealStdbyVehicle: 0x80045 - Hostage DUMMY: 0x80047 - Corpse PlugActionCore: 0x8004b - Corpse UnrealBasic: 0x8004c - CommandPost2 Core Ai: 0x8004d - Gimmick GameObject: 0x8006b - Tpp Effect DebugOnly: 0x8006e - tpp Ui Callback: 0x80070 - tpp Gk Grass Work: 0x80075 - Unnamed Entity: 0x90001 - SharedPathPoolBin: 0x90002 - Entity Dynamic Property: 0x90004 - Sound Source: 0x90007 - GraphRawFile: 0x90009 - Geo Path: 0x9000a - NavData: 0x9000c - FxData: 0x9000d - LangFile: 0x9000e - Gr RenderTarget: 0x9000f - Gr ShaderObjectResource: 0x90010 - Gr OverlayModel: 0x90011 - GkCollectible: 0x90012 - Ph Util: 0x90015 - Sim BinaryFile: 0x90016 - DemoStreamBonelessModel: 0x90019 - Grx LightArrayFile: 0x9001b - Block Stage Large: 0x9001d - UiModelMesh: 0x9001e - tpp SystemEvent: 0x9002d - Animal DUMMY Realize: 0x90039 - Vehicle Attachment: 0x9003d - NewChara System Sound: 0x90041 - Soldier Authorizer: 0x90042 - Soldier ParamTable: 0x90043 - Soldier UnrealCover: 0x90044 - Soldier UnrealSearchLight: 0x90045 - Corpse UnrealPlugCore: 0x9004b - Corpse RealBasic: 0x9004c - CommandPost2 Sneak Ai: 0x9004d - Gimmick Online: 0x9006b - Tpp Effect System: 0x9006e - tpp Ui PrefabCallFunc: 0x90070 - tpp Gk obr skl: 0x90075 - Unnamed Data: 0xa0001 - Core Entity Archive: 0xa0004 - Sound Stream: 0xa0007 - GraphEditorFile: 0xa0009 - Geo Search: 0xa000a - NavTactical: 0xa000c - FxLocator: 0xa000d - UiSound: 0xa000e - Gr Command: 0xa000f - Gr ShaderTechnique: 0xa0010 - Gr Clone: 0xa0011 - GkTargetData: 0xa0012 - Ph Job: 0xa0015 - DemoStreamOneMesh: 0xa0019 - Grx LightCapture: 0xa001b - Block Stage Small: 0xa001d - UiModelNull: 0xa001e - tpp SystemCheckPoint: 0xa002d - Bird Base: 0xa0039 - Vehicle Weapon: 0xa003d - NewChara System SightController: 0xa0041 - Soldier PlugCore: 0xa0042 - Soldier RealCover: 0xa0044 - Soldier RealSearchLight: 0xa0045 - Corpse StateCollector: 0xa004b - Corpse UnrealStdbyVehicle: 0xa004c - CommandPost2 Alert Ai: 0xa004d - Gimmick etc: 0xa006b - Tpp Effect ChPlugin: 0xa006e - tpp Gk SmartDevice: 0xa0075 - Unnamed Data Body: 0xb0001 - Core File: 0xb0004 - Sound Trap: 0xb0007 - AnimPlugin: 0xb0009 - Geo Geom: 0xb000a - DataChunk: 0xb000c - FxEdData: 0xb000d - UiWindow: 0xb000e - Gr CommandBuffer: 0xb000f - Gr IndexBufferResource: 0xb0010 - Gr Decal: 0xb0011 - GkObjectBrush: 0xb0012 - Ph Other: 0xb0015 - DemoStreamCamera: 0xb0019 - Grx LightProbe: 0xb001b - UiModelText: 0xb001e - tpp DefaultParameter: 0xb002d - Bird Controller: 0xb0039 - Vehicle AnimationController: 0xb003d - NewChara System SpeechController: 0xb0041 - Soldier PlugActionCore: 0xb0042 - Soldier UnrealDamage: 0xb0044 - Soldier UnrealMortar: 0xb0045 - Corpse DamageHandler: 0xb004b - Corpse RealStdbyVehicle: 0xb004c - CommandPost2 Caution Ai: 0xb004d - Gimmick Editor: 0xb006b - Tpp Effect Ocean: 0xb006e - tpp Gk DiscoverSensor: 0xb0075 - Unnamed File: 0xc0001 - Core Entity File: 0xc0004 - Sound File: 0xc0007 - AnimPlayControl: 0xc0009 - Geox Voxel: 0xc000a - NavmeshChunk: 0xc000c - FxSystem: 0xc000d - UiEd: 0xc000e - Gr CommandCluster: 0xc000f - Gr VertexBufferResource: 0xc0010 - Gr Terrain: 0xc0011 - GkGameScript: 0xc0012 - DemoStreamIndex: 0xc0019 - Grx ModelConvert: 0xc001b - UiModelStencil: 0xc001e - tpp EventSequenceManager: 0xc002d - Bird Ai: 0xc0039 - Vehicle ManeuverController: 0xc003d - NewChara System ResponseController: 0xc0041 - Soldier UnrealPlugCore: 0xc0042 - Soldier RealDamage: 0xc0044 - Soldier RealMortar: 0xc0045 - Corpse FlagInfo: 0xc004b - Corpse UnrealCarried: 0xc004c - CommandPost2 Evasion Ai: 0xc004d - Gimmick Debug: 0xc006b - Tpp Effect DirtyModel: 0xc006e - Unnamed Array: 0xd0001 - Core Raw File: 0xd0004 - GraphContainer: 0xd0009 - Geox Debug: 0xd000a - WorkInfo: 0xd000c - FxReservableObject: 0xd000d - UixPrefab: 0xd000e - Gr MacroPacket: 0xd000f - Gr VertexStreamResource: 0xd0010 - Gr Primitive: 0xd0011 - GkVoice: 0xd0012 - DemoStreamFova: 0xd0019 - Grx ModelCut: 0xd001b - tpp GameConfig: 0xd002d - Bird Plugin: 0xd0039 - Vehicle SkidmarksController: 0xd003d - NewChara System NaviController: 0xd0041 - Soldier InfoCollector: 0xd0042 - Soldier UnrealFulton: 0xd0044 - Soldier UnrealTurret: 0xd0045 - Corpse ParamCoder: 0xd004b - Corpse RealCarried: 0xd004c - CommandPost2 DEBUG: 0xd004d - Gimmick Old: 0xd006b - Tpp Effect VfxEffectCollect: 0xd006e - tpp Gk NoticeSensor: 0xd0075 - Unnamed List: 0xe0001 - Core Handle: 0xe0004 - MotionGraph Debug: 0xe0009 - Geo Material: 0xe000a - NavmeshWorkInfo: 0xe000c - FxFile: 0xe000d - UixSystem: 0xe000e - Gr SubComamndContext: 0xe000f - Gr InputLayoutResource: 0xe0010 - Gr Draw2D: 0xe0011 - GkEventTimer: 0xe0012 - DemoStreamControllerAnim: 0xe0019 - Grx ModelDeform: 0xe001b - UiModelVertex: 0xe001e - tpp PlayerInfo: 0xe002d - Bird DEBUG: 0xe0039 - Vehicle ReliefBlock: 0xe003d - NewChara System RouteController: 0xe0041 - Soldier AuthorityCollector: 0xe0042 - Soldier RealFulton: 0xe0044 - Soldier RealTurret: 0xe0045 - Corpse ResponseHandler: 0xe004b - Tpp Effect CigaretteSmoke: 0xe006e - tpp Gk Searchable Light: 0xe0075 - Unnamed Graph: 0xf0001 - Core Bvh: 0xf0004 - AnimJobPacket: 0xf0009 - Geo Col Resource: 0xf000a - NavigationGraphWorkInfo: 0xf000c - UixUtility: 0xf000e - Gr Instance: 0xf000f - Gr TextureResource: 0xf0010 - Gr ShLight: 0xf0011 - GkFacial: 0xf0012 - DemoStreamControllerNode: 0xf0019 - Grx Occluder: 0xf001b - UiLayout: 0xf001e - tpp Storage: 0xf002d - Bird DUMMY: 0xf0039 - Vehicle ProcedureController: 0xf003d - NewChara System DamageController: 0xf0041 - Soldier DamageHandler: 0xf0042 - Soldier UnrealHoldup: 0xf0044 - Soldier UnrealRideVehicle: 0xf0045 - Corpse ActionController: 0xf004b - Tpp Effect Atmosphere: 0xf006e - tpp Gk GZ: 0xf0075 - Unnamed GraphX: 0x100001 - Core Skeleton: 0x100004 - AnimDebug: 0x100009 - Geo Col Job: 0x10000a - SegmentChunk: 0x10000c - UiCtrl: 0x10000e - Gr Daemon: 0x10000f - Gr ModelTransform: 0x100010 - Gr Light: 0x100011 - GkSubtitles: 0x100012 - DemoStreamControllerModel: 0x100019 - Grx OccluderArray: 0x10001b - UiModelLayoutData: 0x10001e - tpp SystemDebug: 0x10002d - Vehicle Synchronizer: 0x10003d - NewChara System RailController: 0x100041 - Soldier Conversation: 0x100042 - Soldier RealHoldup: 0x100044 - Soldier RealRideVehicle: 0x100045 - Corpse UnrealActionController: 0x10004b - Tpp Effect LightProbe: 0x10006e - tpp Gk Route: 0x100075 - Connect Point File: 0x110004 - Geo Col Decal: 0x11000a - SegmentGraphWorkInfo: 0x11000c - UiTexture: 0x11000e - Gr GeTools: 0x11000f - Gr TextrueStream: 0x110010 - Gr LightSearch: 0x110011 - GkFx: 0x110012 - DemoStreamControllerLocator: 0x110019 - Grx OccluderArrayFile: 0x11001b - UiModelTexPrefetch: 0x11001e - tpp StoryFlag: 0x11002d - Vehicle VantagePointSystem: 0x11003d - NewChara System DemoAnimController: 0x110041 - Soldier FlagInfo: 0x110042 - Soldier UnrealNotice: 0x110044 - Soldier UnrealDown: 0x110045 - Corpse SoundController: 0x11004b - Tpp Effect Fire: 0x11006e - tpp Gk OldLight: 0x110075 - Core Serializer: 0x120004 - Geo Col Cache: 0x12000a - DynamicNavigationGraph: 0x12000c - UiTextUnit: 0x12000e - Gr DgInstance: 0x12000f - Gr TextrueStreamStatus: 0x120010 - Gr LightVolume: 0x120011 - GkFova: 0x120012 - DemoDesc: 0x120019 - Grx OccluderEx: 0x12001b - UiPlayControlPool: 0x12001e - tpp GzSaveData: 0x12002d - Vehicle DEPRECATED: 0x12003d - NewChara System GameObjectInfo: 0x120041 - Soldier ParamCoder: 0x120042 - Soldier RealNotice: 0x120044 - Soldier RealDown: 0x120045 - Corpse RealizedCorpse: 0x12004b - Tpp Effect Light: 0x12006e - tpp Gk Emblem: 0x120075 - Core Container: 0x130004 - Geo Col util: 0x13000a - DynamicSegmentGraph: 0x13000c - UiTextUnitText: 0x13000e - Gr ShrinkBuffer: 0x13000f - Gr TextrueRequest: 0x130010 - Gr ApproximatedLight: 0x130011 - GkSimpleCoverAndConnect: 0x130012 - DemoLocateObject: 0x130019 - Grx PeriodicActor: 0x13001b - UiAnimNode: 0x13001e - tpp GzSaveLoadManager: 0x13002d - Vehicle EDIT: 0x13003d - NewChara System GameObjectRealizer: 0x130041 - Soldier ResponseHandler: 0x130042 - Soldier UnrealSearch: 0x130044 - Tpp Effect FootPrint: 0x13006e - Core Data: 0x140004 - Geo Attach: 0x14000a - DynamicDataChunkBucket: 0x14000c - Gr GBuffer: 0x14000f - Gr Job: 0x140010 - Gr Bounding: 0x140011 - GkVoiceChat: 0x140012 - DemoPlaybackAddon: 0x140019 - Grx PluginSetting: 0x14001b - UiMeshParam: 0x14001e - tpp PlayRecord: 0x14002d - Vehicle DEBUG: 0x14003d - NewChara System FacialUtility: 0x140041 - Soldier DiscoverManager: 0x140042 - Soldier RealSearch: 0x140044 - Corpse GameObject: 0x14004b - Tpp Effect Skidmarks: 0x14006e - Core Data Body: 0x150004 - Geo Poly Cache: 0x15000a - DynamicArraySetContainer::Handle: 0x15000c - Gr MemoryObject: 0x15000f - Gr JobPascket: 0x150010 - Gr VisibilityTest: 0x150011 - GkLanguage: 0x150012 - DemoFunctorCollector: 0x150019 - Grx RainFilter: 0x15001b - UiStencilParam: 0x15001e - tpp Video: 0x15002d - Vehicle DUMMY: 0x15003d - NewChara System DirtyModelService: 0x150041 - Soldier Noiselistener: 0x150042 - Soldier UnrealActing: 0x150044 - Soldier UnrealRideHeli: 0x150045 - Corpse DEBUG: 0x15004b - Tpp Effect Fire Lights: 0x15006e - Core Save: 0x160004 - Geo Rail: 0x16000a - DynamicArraySetContainer::Header: 0x16000c - Gr DynamicVertexBuffer: 0x16000f - Gr JobSyncPacket: 0x160010 - Gr Material: 0x160011 - GkDebug: 0x160012 - DemoConstraint: 0x160019 - Grx Reflection: 0x16001b - NewChara System NoiseArea: 0x160041 - Soldier ActionController: 0x160042 - Soldier RealActing: 0x160044 - Soldier RealRideHeli: 0x160045 - Tpp Effect FxLocatorTppCustomWork: 0x16006e - Core Message: 0x170004 - Geo JobPacket: 0x17000a - DynamicArraySetContainer::Array: 0x17000c - Gr DynamicIndexBuffer: 0x17000f - Gr gd: 0x170010 - Gr Shader: 0x170011 - DemoCommand: 0x170019 - Grx ShMath: 0x17001b - NewChara System AuthorityState: 0x170041 - Soldier UnrealActionController: 0x170042 - Soldier UnrealRadio: 0x170044 - Tpp Effect Container: 0x17006e - Core Label: 0x180004 - Geo SweepMain: 0x18000a - FileUnit: 0x18000c - Gr ShadowBuffer: 0x18000f - Gr MappedMemory: 0x180010 - Gr Occluder: 0x180011 - DemoEventConText: 0x180019 - Grx SkyCapture: 0x18001b - NewChara System HumanLightSimModule: 0x180041 - Soldier CollisionController: 0x180042 - Soldier RealRadio: 0x180044 - Core Locator: 0x190004 - Geo SweepBlock: 0x19000a - Map: 0x19000c - Gr ShadowConstantRegister: 0x19000f - Gr Umbra: 0x190010 - Gr Texture: 0x190011 - DemoEventParameter: 0x190019 - Grx SSAO: 0x19001b - Soldier DiscoveryController: 0x190042 - Soldier UnrealReload: 0x190044 - Soldier UnrealOthers: 0x190045 - Misc System: 0x1a0004 - Geo CheckControl: 0x1a000a - PriorityQueueDesc: 0x1a000c - Gr Render: 0x1a000f - Gr Scene: 0x1a0011 - DemoBuffer: 0x1a0019 - Grx TextureConverter: 0x1a001b - Soldier EquipController: 0x1a0042 - Soldier RealReload: 0x1a0044 - Soldier RealOthers: 0x1a0045 - TppRadioEspionage: 0x1a0071 - Core Temp: 0x1b0004 - Geo JobTiny: 0x1b000a - Gr RenderStateResource: 0x1b000f - Gr SceneObject: 0x1b0011 - DemoCallback: 0x1b0019 - Grx TmpActor: 0x1b001b - NewChara System Base: 0x1b0041 - Soldier LifeController: 0x1b0042 - Soldier UnrealUnholster: 0x1b0044 - Soldier RealDemo: 0x1b0045 - Player Base: 0x1b0048 - Debug: 0x1c0004 - Geo JobMulti: 0x1c000a - Gr ModelBuffer: 0x1c000f - Gr Viewport: 0x1c0011 - DemoParameter: 0x1c0019 - Grx Utility: 0x1c001b - Soldier NoticeController: 0x1c0042 - Soldier RealUnholster: 0x1c0044 - Player Plugin: 0x1c0048 - Core Test: 0x1d0004 - Geo JobMultiWork: 0x1d000a - Gr Camera: 0x1d0011 - DemoPacketPlugin: 0x1d0019 - Grx JobSyncPacket: 0x1d001b - Soldier SoundController: 0x1d0042 - Soldier UnrealCarried: 0x1d0044 - Player Component: 0x1d0048 - Gr Temporary: 0x1e0011 - DemoJob: 0x1e0019 - Grx Debug: 0x1e001b - Soldier RealizedSoldier: 0x1e0042 - Soldier RealCarried: 0x1e0044 - Player Data: 0x1e0048 - Gr Debug: 0x1f0011 - DemoOther: 0x1f0019 - Grx Temporary: 0x1f001b - NewChara System Debug: 0x1f0041 - Player Debug: 0x1f0048 ### `wiki:wiki/Emblem.md` Player emblem is a texture that is displayed on different player-owned entities such as camouflage, Motherbase, containers, vehicles, mission prep screen etc. ![Custom emblem on player right shouder, Motherbase exterior, flag and helicopter](/assets/Emblem/heli_motherbase.jpg){:.thumb .center} It is composed of two shape textures (back/front) and two word textures. Player can unlock different shapes and words by playing the game. Shapes and words are tied to specific missions and free-roam outposts; you can check them in `./00.dat/Assets/tpp/script/lib/TppEmblem.lua`. They are saved in `vars.emblemFlag` lua variable. Textures can be found in `master\texture0.dat\Assets\tpp\ui\texture\Emblem\`. On FOBs emblem assignment is inconsistent. If defender is a supporter of attacked FOB and has a different emblem, it will be replaced with FOB emblem from attackers point of view. Defender cannot see attackers emblem, default "DD" emblem is used instead (depends on master server response). ![Default emblem, editor](/assets/Emblem/default_emblem.jpg){:.thumb .center} ###### Texture composition All emblems (player and FOB opponent) are created dynamically by `tpp::ui::emblem::impl::EmblemEditorSystemImpl` class. First, `tpp::ui::emblem::impl::EmblemEditorSystemImpl::CreateEmblemParameters` is called with variables from save file (local) or master server response (FOB). Save file variables: | Name | Value | Example | | --- | --- | --- | | emblemTextureTag | strcode32 hash | base5,fd776fc4 | | emblemColorL | RGBA value | 0x00b4b4b4 | | emblemColorH | RGBA value | 0x00b4b4b4 | | emblemX | signed byte | -90 | | emblemY | signed byte | -80 | | emblemScale | signed byte | 5 | | emblemRotate | signed byte | 10 | Each variable is a 4-value array indexed from 0 to 3, example: `vars.emblemY[0]`. After successfully creating parameters, they are fed to `tpp::ui::emblem::impl::EmblemEditorSystemImpl::CreateEmblem`, which makes **2** named textures: regular and small one (with what dimensions?). Small texture gets `_S` suffix. To create the texture, words and shapes are blend together by an instance of `fox::gr::TextureBlender` (created during object initialization, `tpp::ui::emblem::impl::EmblemEditorSystemImpl::CreateBlender`). Emblem can be recreated anywhere except during online session after both players are connected and in the mission - game will crash in `tpp::gk::'anonymous_namespace'::EmblemManagerImplJob::UpdateRendering (0x14055ac0c)`. Player emblem is created on game start from lua in `0/00.dat/Assets/tpp/pack/mission2/init/init_fpkd/Assets/tpp/level/mission2/init/init_sequence.lua`: ```lua TppUiCommand.CreateEmblem("MyEmblem") -- creates MyEmblem and MyEmblem_S ``` On FOBs another pair of textures is made: `OpponentEmblem` and `OpponentEmblem_S`. These names are hardcoded in the exe and not referenced in lua; they are encoded using `strcode64` (HashWrangler) (`fox::FoxStrHash32`) | Name | Hash | | --- | --- | | OpponentEmblem | 90bb6285c23c | | OpponentEmblem_S | d2ee491abe8f | | MyEmblem | 2ad823030e6b | | MyEmblem_S | d7e35d0e4c8 | For attacker opponent emblem is created on FOB selection list after selecting the attack target. ### `wiki:wiki/Enabling_CS_Weapons.md` In this article I'll explain how to enable CS guns, which are guns the game has and uses but are not available to the player. One of these guns, for example, is the XOF Hospital SMG. Enabling these guns is rather simple. One must simply find the correct line of code in EquipDevelopFlowSetting.lua and change "p69=2" to "p69=0" Now, finding the right line of code that pertains to the correct weapon is the tricky part. Each line of code in EquipDevelopFlowSetting.lua is a developable item in the iDroid and finding the right one is needed in order to enable the weapon. Fortunately I have labeled many of the lines with their weapon ID's in [this deminified version of EquipDevelopFlowSetting.lua](https://github.com/Your401kPlan/Misc-Lua/blob/main/EquipDevelopFlowSetting%20Labeled.lua). So now you have most of the CS guns in the game labeled , it's a matter of finding the right the corresponding weapon ID. ![All](/assets/XOF%20Hospital%20SMG%20Info.png){:.thumb} weapon ID's in the game can be found at Lets take the XOF hospital SMG for example. Here is it's info: From here we can see that the weapon ID is "WP_East_sm_030" so we can simply use ctrl+f to search this on the labeled lua file from github. In this case it's on line p50=310, so we simply scroll to the right to p69=2 and change it to p69=0. Save the file as EquipDevelopFlowSetting.lua and use fileproliferator and makebite to save it as a .mgsv. ### `wiki:wiki/Entity.md` **Entity** is a type of object used in the Fox Engine. It is believed that Entity lies at the top of the hierarchy of entity classes, due in part to its name and the fact that none are actually placed anywhere in .fox2 files, but referenced as an included class in the `` block. ##### Format Serialized representation - [010 Editor template](https://github.com/kapuragu/FoxEngineTemplates/blob/c40c5d4e5cf556a0fed14b57d3f2a5653cbd0ecc/fox2.bt#L21). Entity is supposedly serializable into xml via built-in method `fox::EntitySerializationFormatterV2::Save`. All attempts to invoke that function without errors were unsuccessful. ##### Usage The **Entity** is not an object directly placed in a level, but rather, it is the super class that all entities in the Fox Engine derive basic properties from. As such, it is not advisable to place one directly in a .fox2, and its properties and associated values are unknown at this time (if any such exist). The only known usage of the entity of type **Entity** is as a reference in the `` header block. ###### Example ```xml ``` ### `wiki:wiki/Entity_Reference.md` ##### Introduction This page will serve as a hub for documenting the properties and nature of entities in the Fox Engine. Specific documentation will be written regarding MGSV:TPP and MGSV:GZ entity types and data structures first and foremost, with information regarding Survive coming at a later date. Click a link below (when those exist) to learn more about that entity or subject. For the full, unsorted list, check the [bottom of the page](#all-tpp-entities-unsorted). > **New:** Each entity now has its own page. These can be navigated by hierarchy in the sidebar, accessed via a search, or by viewing the complete linked list [here](/Reference#entity-reference). This page will be revised over time to reflect this. ##### Common Entities - [Entity](/Entity "wikilink") - EntityPtrArrayEntity - [DataSet](/DataSet "wikilink") - Data - DataIdentifier - FoxDataLinkCollectorData - Group - TransformEntity - ShearTransformEntity - PivotTransformEntity - TppTextureLoader - TexturePackLoadConditioner ##### Terrain - TerrainRender - TerrainDecalPack - TerrainMaterialConfigration - DecalArray - Material - ObjectBrush - ObjectBrushPluginClone - TppObjectBrushPluginSkeletonModel - TppObjectBrushPluginBush - ObjectBrushPluginBushDataElement - TppObjectBrushPluginFlutteringGrass ##### Geometry and Models - BoxShape - FoxTargetDescription - GeoModuleCondition - GeoTrap - GeomSkeletonDescription - GeoxBoundingVolumeFileParameter - GeoxBoundingVolumeFileParameterLarge - GeoxCollisionPyraidFreeShape - GeoxGeomSetLoader - GeoxTargetDesc - GeoxTextureMaterialRegister - LuxuryBlockControllerData - ModelDescription - OccluderArray - SphereShape - StaticModel - StaticModelArray - StaticModelArrayLinkTarget - StaticModelArrayPathFilter - TppFourierOcean - TppOcean - TppPermeableStaticModel - TppPrimRiverModelParam - TppThermalStaticModel - ViewGroupControlCondition ##### Lighting - PointLight (the flags of lightFlags uint32 value in this and similar light entities seem to correspond to: 0x1 - Enable, 0x2 - castShadow, 0x4 - useAutoDimmer?, 0x8 - hasSpecular) - SpotLight - TppLightProbe - TppLightProbeSHCoefficients - LightArray - TppLightProbeArray - GrReflectionSetting ##### Special Effects - EffectDescription - FxLocatorArrayData - FxLocatorData - FxLocatorGroup - TppVfxFileLoader - TppSunLightFlare - TppHeatHaze - TppWaterRippleViewport - TppFloorRainSplashData - TppRainFilter - TppRainFilterInterruptTrans - TppWeatherRainData - TppDroplets - TppWeatherParasiteUnitParam - TppStar - TppSky - TppWeatherSandStormData - GraphxSpatialGraphDataNode - GraphxSpatialGraphDataEdge - WindGlobal - WindParameter ##### Gimmicks - TppLadderData - TppLadderEntryPointData - TppLadderManagerData - TppGimmickImmediateStateData - TppPermanentGimmickBank - TppPermanentGimmickData - TppGimmickElectricCableLinkSetData - TppGimmickBrokenElectricCableBank - TppGimmickPowerCutAreaData - TppObjectBrushSkeletonModelDestructionResource - TppGimmickBrokenCandleBank - TppPermanentGimmickMortarParameter - TppPermanentGimmickImportantBreakableParameter - TppPermanentGimmickMachineGunParameter - TppPermanentGimmickSearchLightParameter - TppPermanentGimmickGatlingGunParameter - TppPermanentGimmickDoorParameter (the attribute uint32 is a bitfield; bit 0x20 is the flag that makes the player and NPCs unable to interact with the door, bit 0x40 is the Locked flag, bit 0x80 makes the door fall and break on explosion) - TppSharedGimmickData ##### Navigation - NavxWorldGenerateParameter - NavxNavigableParameter - NavxFillNavVolume - NavxAttributePathVolume - NavxAttributeInfo - NavxKeepNavLocator - NavxHoleSimplificationParameterVolume - NavxNavBlock - NavxSquareGraphBounderData - Locator - GeoxPathPack - GeoxPathWall - GeoxPath2 - GeoxPathNode - GeoxPathEdge - TppLocationData - MotherBaseConstructLocator - GameObjectLocator ##### Scripting and Mission - StageBlockControllerData - TppSimpleMissionBlockControllerData - ScriptBlockScript - GameObject - TppBossQuiet2Parameter - TppBossQuiet2LocatorParameter - TppHostage2LocatorParameter - TppHostage2Parameter - TppMarker2LocatorParameter - TppTrapCheckIsHostageCallbackDataElement - TppTrapExecLostHostageCallbackDataElement - TppTrapCheckIsPlayerCallbackDataElement - TppRequestWeatherTagTrapDataElement - TppTrapCheckIsInCameraCallbackDataElement - FoxTrapExecViewGroupControlCallbackDataElement - TppVehicle2LocatorParameter - TppVehicle2BodyData (vehicleTypeIndex: *1 = west lv, 2 = east lv, 3 = west truck, 4 = east truck, 5 = west wav, 6 = east wav, 7 = west tank, 8 = east tank, 9 = reinforce*, proxyVehicleTypeIndex: *1 = west lv, 2 = east lv, 3 = west truck, 4 = east truck, 5 = west wav, 6 = east wav, 7 = west tank, 8 = east tank*, bodyImplTypeIndex: *1 = lv, 2 = truck, 3 = east wav , 4 = west wav, 5 = tank*) - [TppVehicle2WeaponParameter](/TppVehicle2WeaponParameter "wikilink") - TppVehicle2AttachmentData (vehicleTypeCode: *49 = west truck item box, 50 = west truck container, 51 = west truck cistern, 52 = west truck hood, 65 = east truck ammunition, 66 = east truck material, 67 = east truck drum, 68 = east truck generator, 81 = west wav machine gun, 82 = west wav cannon, 97 = east wav rocket, 145 = reinforce west wav machine gun, 146 = reinforce west wav cannon*) ##### Audio - TppSoundWorld - TppAreaEdgeParameter - TppMusicParameter - TppAmbientParameter - TppAmbientSoundSource - TppNoiseArea2 - SoundSource - SoundAreaGroup - SoundAreaParameter - SoundAreaMember - SoundAreaGlobal - SoundAreaEdge - SoundDataFileInfo - SoundDescription - SoundPackage - SoundPhysicsParameter - SoundAreaMember ##### UI - UiGraphEntry - UiInstanceData ##### Physics - PhAssociationParam - PhObjectDesc - PhPrimitiveShapeParam - PhRigidBodyParam - [PhVehicleNormalEngineParam](/PhVehicleNormalEngineParam "wikilink") - PhxAssociation - PhxAssociationUnitElement - [PhxVehicleAxis](/PhxVehicleAxis "wikilink") - [PhxVehicleNormalEngine](/PhxVehicleNormalEngine "wikilink") - PhysicsDescription - VehicleDescription ##### **All TPP Entities (Unsorted)** - Rotation - TransformRT - Transform - ShearTransform - PivotTransform - Sphere - Capsule - BoundingBox - OrientedBoundingBox - RandomNumberGenerator - Entity - Data - DataElement - TransformData - Actor - ComponentSet - PointComponentSet - LineSegmentComponentSet - TransformComponentSet - ComponentInsertionInfo - Scene - Application - Game - Script - SafeScript - Bucket - BucketCollector - EntityClassDictionary - PropertyValueEntity - Int8Entity - UInt8Entity - Int16Entity - UInt16Entity - Int32Entity - UInt32Entity - Int64Entity - UInt64Entity - FloatEntity - DoubleEntity - BoolEntity - StringEntity - PathEntity - EntityPtrEntity - Vector3Entity - Vector4Entity - QuatEntity - Matrix3Entity - Matrix4Entity - ColorEntity - FilePtrEntity - EntityHandleEntity - EntityLinkEntity - WideVector3Entity - UInt32ArrayEntity - StringArrayEntity - EntityPtrArrayEntity - EntityHandleArrayEntity - UInt32ListEntity - StringListEntity - EntityPtrListEntity - EntityHandleListEntity - StringStringMapEntity - EntityPtrStringMapEntity - TagContainerEntity - File - RawFile - DataSet - DataBody - CallbackProcedureDataBody - TransformDataBody - CallbackProcedureTransformDataBody - DataBodySet - DataIdentifier - ShapeData - ShapeDataBody - SphereShape - SphereShapeBody - BoxShape - BoxShapeBody - CapsuleShape - CapsuleShapeBody - TransformRTEntity - TransformEntity - ShearTransformEntity - PivotTransformEntity - StageBlockControllerData - StageBlockControllerDataBody - PassiveBlockControllerData - PassiveBlockController - BlockGroupData - BlockGroup - EditableBlockPackageBase - EntityFile - DataSetFile - DataSetFile2 - ScriptFile - StageBlockFile - Group - Project - BucketArchive - Material - MaterialBody - PathMapper - PropertyDifference - Int8ArrayPropertyDifference - UInt8ArrayPropertyDifference - Int16ArrayPropertyDifference - UInt16ArrayPropertyDifference - Int32ArrayPropertyDifference - UInt32ArrayPropertyDifference - Int64ArrayPropertyDifference - UInt64ArrayPropertyDifference - FloatArrayPropertyDifference - DoubleArrayPropertyDifference - BoolArrayPropertyDifference - StringArrayPropertyDifference - PathArrayPropertyDifference - EntityPtrArrayPropertyDifference - Vector3ArrayPropertyDifference - Vector4ArrayPropertyDifference - QuatArrayPropertyDifference - Matrix3ArrayPropertyDifference - Matrix4ArrayPropertyDifference - ColorArrayPropertyDifference - FilePtrArrayPropertyDifference - EntityHandleArrayPropertyDifference - EntityLinkArrayPropertyDifference - WideVector3ArrayPropertyDifference - Int8StringMapPropertyDifference - UInt8StringMapPropertyDifference - Int16StringMapPropertyDifference - UInt16StringMapPropertyDifference - Int32StringMapPropertyDifference - UInt32StringMapPropertyDifference - Int64StringMapPropertyDifference - UInt64StringMapPropertyDifference - FloatStringMapPropertyDifference - DoubleStringMapPropertyDifference - BoolStringMapPropertyDifference - StringStringMapPropertyDifference - PathStringMapPropertyDifference - EntityPtrStringMapPropertyDifference - Vector3StringMapPropertyDifference - Vector4StringMapPropertyDifference - QuatStringMapPropertyDifference - Matrix3StringMapPropertyDifference - Matrix4StringMapPropertyDifference - ColorStringMapPropertyDifference - FilePtrStringMapPropertyDifference - EntityHandleStringMapPropertyDifference - EntityLinkStringMapPropertyDifference - WideVector3StringMapPropertyDifference - EntityDifference - DataSetDifference - DataSetReference - DataSetReferenceBody - FoxFlagContainer - Locator - LocatorBody - LabelObject - ConnectPointFile - FoxDataLinkCollectorData - FoxDataLinkCollectorDataBody - FoxDataLinkCollector - ScriptBlockScript - ScriptBlockData - SyncUniqueId - SyncInstance - SyncFactory2 - Replay - NtMemberSyncInstance - RigFile - GaniBaseFile - MtFile - EvbFile - EvfFile - MtarFile - CaarFile - SandFile - TimeSection - EventDataUnit - ParameterMaskElement - FacialMaskElement - FacialSettingData - MaterialInfoBase - MaterialInfo - ColorInfo - GeoMaterialCache - GeoShape - GeoShapeBody - GeoGeomFile - GeoGsklFile - GeoTrapFile - GeoBoundingVolumeFile - CollisionObject - CollisionPoly - CollisionReference - CollisionReferenceSet - CollisionGeomSet - CollisionSkeleton - CollisionSkeletonCreater - GeoCollisionTerrain2 - GeoCollisionTerrainMap - GeoCollisionPrimitiveBase - GeoCollisionCircle - GeoCollisionRect - GeoCollisionFreeShape - GeoCollisionPyramidFreeShape - GeoPathUnit - GeoPathUnitBody - GeoPathGeomHeader - GeoPathFixedPackFile - GeoPathService - GeoSearchObject - GeoSearchService - GeoSearchPoint - GeoSearchAABB - GeoSearchOBB - GeoSearchSphere - GeoSearchLine - GeoSearchSegment - GeoSearchCapsule - GeoSearchDynamic - TargetExtensionData - GeoTrapCondition - GeoTrapConditionBody - GeoTrapScriptCondition - GeoTrapScriptConditionBody - GeoTrapScriptModuleCondition - GeoTrapScriptModuleConditionBody - GeoTrapInfo - GeoTrap - GeoTrapBody - GeoTriggerTrap - GeoTrapGeomHeader - GeoTrapModuleCallbackDataElement - GeoCheckModuleCondition - GeoCheckModuleConditionBody - GeoModuleCondition - GeoModuleConditionBody - GeoTrapExecScriptCondition - GeoTrapExecScriptConditionBody - GeoTrapScriptCallbackDataElement - RailFile - RailUniqueIdFile - GrDaemon - GrCamera - GrTools - TerrainMaterialConfigration - GrViewport - TerrainTileFile - TerrainFile - FmdlFile - GrGraphicsSettingManager - GrRenderPlugin - GrPlugin2D - GrPlugin2DFrontmost - GrPlugin2DShrink - GrPluginAlphaModel - GrPluginClone - GrPluginCloneDeferred - GrPluginCloneWireframe - GrPluginColorCorrection - GrPluginDecal - GrPluginRawDecal - GrPluginDeferredGeometry - GrPluginDeferredGeometryOpaque - GrPluginDeferredGeometryDecal - GrPluginDeferredGeometryMasked - GrPluginMaterialLayer - GrPluginDeferredRendering - GrPluginDeferredShading - GrPluginDepthOfField - GrPluginExtendFxModel - GrPluginForwardRendering - GrPluginOverlayModel - GrPluginGlobalVolumetricFog - GrPluginLightAccumulateLayer - GrPluginLineIntegralSSAO - GrPluginLocalLight - GrPluginModel - GrPluginModelSetup - GrPluginMotionBlur - GrPluginOccluder - GrPluginOpticalCamouflage - GrPluginPostFilter - GrPluginPrecomputeSky - GrPluginPrimitive - GrPluginPrimitiveUnfiltered - GrPluginScreenCapture - GrPluginScreenSpaceAmbientOcclusion - GrPluginShadow - GrPluginSphericalHarmonics - GrPluginSky - GrPluginSunlight - GrPluginSubSurfaceScatter - GrPluginAmbientObscuranceSSAO - GrPluginTerrain - GrPluginSeflShadowOfTerrain - GrPluginTerrainDepth - GrPluginThermography - GrPluginTonemap - GrPluginViewCallback - GrPluginFxaa - GrPluginWormhole - GrPluginLocelReflection - GrPluginPrimitiveDebug - GrViewportParameter - GrFilmicTonemapParameter - GrSkyParameter - GrViewportRenderingParameters - GrViewportLightingParameters - GrViewportColorCorrectionParameters - GrFilmicTonemap - FilmicTonemapBody - NavCurrentNavigationDesc - NavNavFile - NavWorldDesc - NavUnitHandleEntity - NavNavigationGraphHandleEntity - NavEdgeHandleEntity - NavWorldDaemon - NavNavigationParameter - NavNavigationParameterHolder - NavVehicleNavigationParameter - NclDaemon - NclTransactionCallback - GameObject - GameObjectDataBody - GameObjectLocator - GameObjectLocatorBody - BlockScript - BlockScriptBody - GrxShape - LightUtility - PointLightBody - PointLight - DirectionalLightBody - DirectionalLight - SpotLightBody - SpotLight - HorizonBody - Horizon - LightArray - LightArrayBody - LightArrayFile - PeriodicActor - PluginSettingsBody - GrPluginSettings - ColorCorrectionData - ColorCorrection - GlobalCameraSettings - GlobalCameraSettingsBody - GrxLineSSAOParameters - GrxAreaSSAOParameters - AmbientOcclusionSettings - AmbientOcclusionSettingsBody - GrxUtil - Occluder - GrxOccluderBody - OccluderEx - GrxOccluderExBody - OccluderArray - OccluderArrayBody - OccluderArrayFile - GrReflectionSetting - ReflectionSettingBody - PhDaemon - PhMaterialInfo - PhMaterialManager - PhObjectParam - PhObject - PhSubObject - PhObjectDesc - PhRigidBodyParam - PhRigidBody - PhShapeParam - PhShape - PhPrimitiveShapeParam - PhPrimitiveShape - PhPolyhedronShapeParam - PhConstraintParam - PhConstraint - PhBallsocketConstraintParam - PhBallsocketConstraint - PhHingeConstraintParam - PhHingeConstraint - PhShoulderConstraintParam - PhShoulderConstraint - PhMultiShoulderConstraintParam - PhMultiShoulderConstraint - PhMultiHingeConstraintParam - PhMultiHingeConstraint - PhStiffConstraintParam - PhStiffConstraint - PhClothHConstraintParam - PhClothVConstraintParam - PhCylinderConstraintParam - PhCylinderConstraint - PhActionParam - PhWindActionParam - MogFile - MotionGraphEnterNodeCallback - MotionGraphBlendValueConverter - MotionGraphBlendValueStringConverter - GkTacticalObject - GkTacticalObjectDesc - GkTacticalPoint - GkTacticalPointBody - GkTacticalActionEdge - GkTacticalActionWaypoint - GkTacticalAction - GkTacticalActionBody - UiDaemon - UiManager - UiObjControl - ModelNodeConnection - UiModelNodeElement - UiModelData - UiModelDataBody - UiLayoutData - UiLayoutDataBody - UiCameraData - UiCameraDataBody - UiAnimData - UiAnimDataBody - UiPaletteData - UiPaletteDataBody - UiReplaceTextureData - UiAnimWorkMemoryData - UiAnimWorkMemoryDataBody - UiFontData - UiFontDataBody - UiFontGroupData - UiFontGroupDataBody - UiFontDataElement - UiInstanceData - UiGraphEntry - UiGraphEntryBody - UiNodeData - UiNodeDataBody - UiEventNode - UiEventNodeBody - UiActionNode - UiActionNodeBody - UiOperationNode - UiOperationNodeBody - UiEdgeData - UiEdgeDataBody - TexListFile - LangDaemon - LangFile - LangData - LangDataBody - GraphxSpatialGraph - GraphxSpatialGraphData - GraphxSpatialGraphDataNode - GraphxSpatialGraphDataEdge - GraphxPath - GraphxPathData - GraphxPathVolume - GraphxPathVolumeBody - GraphxPathVertexInsertionInfo - FxVfxFile - FxVfxBinaryFile - FxLocatorData - FxLocator - FxLocatorGroup - LocatorGroupBody - FxLocatorArrayData - FxLocatorArrayDataBody - SoundPackage - SoundPackageBody - SoundDataFile - SoundDataFileInfo - SoundSource - SoundSourceBody - SoundAreaGlobal - SoundAreaGlobalBody - SoundAreaGroup - SoundAreaGroupBody - SoundAreaMember - SoundAreaMemberBody - SoundAreaParameter - SoundAreaEdge - SoundAreaEdgeBody - SoundAreaEdgeParameter - SoundSourceTrapParameter - SoundPhysicsParameter - PhxAssociationUnitElement - PhAssociationParam - PhxAssociation - PhVehicleNormalEngineParam - PhxVehicleNormalEngine - PhxVehicleTransmission - PhVehicleAxisParam - PhxVehicleAxis - PhxWheelConstraintParam - PhxWheelAssociationUnitParam - GeoxPath - GeoxPathBody - GeoxPath2 - GeoxPath2Body - GeoxPathNode - GeoxPathEdge - GeoxPathPack - GeoxPathPackBody - GeoxTrapAreaPath - GeoxTrapAreaPathBody - GeoxTextureMaterialRegister - GeoxTextureMaterialRegisterBody - GeoxPartsTargetObject - GeoxPartsTargetObjectBody - GeoxPartsTargetDefenseObject - GeoxPartsTargetDefenseObjectBody - GeoxPartsTargetOffenseObject - GeoxPartsTargetOffenseObjectBody - GeoxPartsTargetUnit - GeoxPartsTargetUnitBody - GeoxPartsTargetExtension - GeoxPartsTargetExtensionBody - GeoxTargetDesc - GeoxTargetModifyCallbackBase - GeoxTargetApplicationData - GeoxPartsTargetFollowSkeleton - GeoxPartsTargetFollowSkeletonBody - GeoxPathWall - GeoxPathWallBody - GeoxPolygonMarker - GeoxPolygonMarkerBody - GeoxDynamicPolygon - GeoxDynamicPolygonBody - GeoxBoundingVolumeFileParameter - GeoxBoundingVolumeFileParameterLarge - GeoxDynamicBoundingVolumeArea - GeoxDynamicBoundingVolumeActivator - GeoxCollisionPrimitive - GeoxCollisionPrimitiveBody - CollisionLocator - GeoxGeomSetLoader - GeoxGeomSetLoaderBody - GeoxCollisionFreeShape - See [Collision Attributes](/Collision_Attributes "wikilink"). - GeoxCollisionFreeShapeBody - GeoxCollisionPyraidFreeShape - GeoxCollisionPyraidFreeShapeBody - NavxNavBlock - NavxNavBlockBody - NavxNavigableParameter - NavxWorldGenerateParameter - NavxWorldGenerateParameterBody - NavxBounderData - NavxBounderDataBody - NavxSwitchBounderData - NavxSwitchBounderDataBody - NavxSquareGraphBounderData - NavxSquareGraphBounderDataBody - NavxBounderLocator - NavxBounderLocatorBody - NavxNavFileLocator - NavxNavFileLocatorBody - NavxNavFilter - NavxNavFilterBody - NavxNavFilterVolume - NavxNavFilterVolumeBody - NavxKeepNavLocator - NavxKeepNavLocatorBody - NavxAttributeInfo - NavxAttributePathVolume - NavxAttributePathVolumeBody - NavxHoleSimplificationParameterVolume - NavxHoleSimplificationParameterVolumeBody - NavxFillNavVolume - NavxFillNavVolumeBody - NavxNavFileConnector - NavxNavFileConnectorBody - PluginAngleLimit - HelpBoneFile - SimDaemon - SimObjectParam - SimEngineParam - SimEngineOnPhysicsParam - SimEngineOnPhysicsDefaultInfo - SimObject - SimOnPhysics - SimAssociationUnitParam - SimAssociationUnit - SimControlElement - SimWindControl - SimGravityControl - SimInertialControl - SimDirectionControl - SimClothControl - SimClothControlUnit - SimHitGroupControl - SimControlParam - SimWindControlParam - SimGravityControlParam - SimInertialControlParam - SimDirectionControlParam - SimClothControlParam - SimClothControlUnitParam - SimHitGroupControlParam - SimClothSettingData - DesDaemon - DesParamData - DesEffectData - DesFixData - DemoModelDataNode - PartsDesc - ClipData - FxBaseLocator - BaseLocatorBody - DemoBlockPositionSetter - DemoBlockPositionSetterBody - DemoParameter - DemoControlCharacterDesc - DemoFileProxy - DemoFileProxyBody - ProceduralDemoData - Pad - Pad2 - PadMapping - CameraPriority - Camera - CameraSelector - AimCamera - OrthogonalCamera - OrthogonalAimCamera - GkPathLineTarget - GkPathLineTargetBody - GkTargetData - GkOffenseTargetData - GkDefenseTargetData - GkTargetHitInfo - TargetHitInfoCollector - StaticModel - StaticModelBody - StaticModelArray - StaticModelArrayBody - StaticModelArrayLinkTarget - StaticModelArrayLinkTargetBody - StaticModelArrayLocator - StaticModelArrayLocatorBody - StaticModelArrayPathFilter - StageModel - StageModelBody - Decal - DecalBody - DecalArray - DecalArrayBody - OpticalCamo - OpticalCamoBody - OverlayModel - OverlayModelBody - PauseController - TerrainRender - TerrainRenderBody - TerrainBody - Terrain - LevelingTerrain - LevelingTerrainBody - TerrainHole - TerrainHoleBody - TerrainDecal - TerrainDecalBody - TerrainDecalPack - TerrainDecalPackBody - FoxTerrainDecalPackFile - TerrainBlock - TerrainBlockBody - ObjectBrush - ObjectBrushBody - ObjectBrushBlock - ObjectBrushPlugin - ObjectBrushPluginBody - ObjectBrushPluginStaticModel - ObjectBrushPluginStaticModelBody - ObjectBrushPluginClone - ObjectBrushPluginCloneBody - ViewGroupControlCondition - FoxTrapExecViewGroupControlCallbackDataElement - GkSightCheckParam - GkSightCheckParamContainer - GkConeSightCheckParam - GkSmartObject - GkSmartObjectBody - GkSmartObjectSet - GkSmartObjectSetBody - FoxFadeIo - LadbFile - SubtitlesDaemon - SubtitlesGenerator - SubtitlesGeneratorBody - SubtitlesPackage - SubtitlesPackageBody - SubtitlesPackageFile - SubtitlesBlockControllerData - SubtitlesBlockControllerDataBody - SubtitlesOptionBlockControllerData - SubtitlesOptionBlockControllerDataBody - SubtitlesTrapCondition - SubtitlesTrapConditionBody - EvSubtitlesNodeBody - EvSubtitlesNode - EvControlSubtitlesNodeBody - EvControlSubtitlesNode - Checkpoint - CheckpointDaemon - CheckpointContainer - CheckpointUnit - CheckpointObserver - CheckpointData - CheckpointTrapScriptModuleCondition - CheckpointTrapScriptModuleConditionBody - GameSequenceController - EnvironmentDaemon - EnvironmentManager - EnvironmentGlobal - EnvironmentGlobalBody - EnvironmentArea - EnvironmentAreaBody - EnvironmentParameter - EnvironmentObject - WindManager - WindGlobal - WindGlobalBody - WindArea - WindAreaBody - WindParameter - WindObject - GameScript - GameScriptBody - GameScriptCheckpointObserver - GkEventTimerData - GkEventTimer - GkEventTimerManager - Watermark - WatermarkBody - IntervalRegulator - StageBlockLowModel - StageBlockLowModelBody - StageLightFadeData - StageLightFadeDataBody - TexturePackLoadConditioner - TexturePackLoadConditionerBody - PartDescription - ModelDescription - DestructionModelDescription - ConnectModelDescription - CoverModelDescription - FoxOffsetModelDescription - EffectDescription - BounderDescription - GeomDescription - GeomSkeletonDescription - FoxTargetDescription - PhysicsDescription - SimDescription - SoundDescription - ClothDescription - VehicleDescription - FileResourceDescription - FormVariationFile2 - TppDefaultParameterElement - TppDefaultParameterContainer - TppDefaultParameter - TppLocationInformationData - TppLocationData - TppWeatherManager - TppRequestWeatherTagTrapExecDataElement - TppSystemUtility - TppOffenseTargetData - TppBlastOffenseTargetData - TppCheckPointTrapExecDataElement - TppCheckPointLocator - ParametersFile - TppPauseMenu - TppTrapChangeEventSequenceCallbackDataElement - TppTrapLockEventSequenceCallbackDataElement - VideoPlayerMemoryBlock - DemoData - DemoDataBody - DemoDynamicFileChangeModel - DemoFv2ResourceMemory - DemoStreamAnimation - DemoStreamAnimationBody - DemoResource - DemoResourceBody - DemoRelativePlayParameter - DemoxEffectMemoryPoolData - DemoxEffectMemoryPoolDataBody - TppSoundDaemon - TppSoundWorld - TppSoundWorldBody - TppAmbientFile - TppAmbientParameter - TppAmbientSoundSource - TppAmbientSourceBody - TppMusicManager - TppMusicParameter - MusicFader - MusicFaderBody - TppAreaEdgeParameter - TppEffectUtility - TppEffectCallbackFunction - TppWeatherEffectBase - TppMuddledFilterParam - TppMuddledFilter - TppMuddledFilter2Param - TppMuddledFilter2 - TppMarshModelPrimitive - TppMarshModelPrimitiveBody - TppPrimRiverModel - TppPrimRiverModelParam - TppPrimRiverModelParamBody - TppPrimRiverModelTwoLayer - TppPrimRiverModelParamTwoLayer - TppPrimRiverModelParamTwoLayerBody - TppPrimRiverModelOverlay - TppPrimRiverModelParamOverlay - TppPrimRiverModelParamOverlayBody - TppWaterBounding - TppWaterRippleViewport - TppDemoIntelligenceObject - TppFocusBokehFilterData - TppFocusBokehFilterDataBody - TppEyelidFilterData - TppEyelidFilterDataBody - TppWeatherParasiteUnit - TppWeatherParasiteUnitParam - TppWeatherSandStormData - TppEyelidFilterStateManager - TppHeatHaze - TppHeatHazeDataBody - TppDroplets - TppDropletsDataBody - TppFireLights - TppFireLightsDataBody - TppFirePropagationLights - TppFirePropagationLightsDataBody - TppGrenadeShock - TppGrenadeShockDataBody - TppSandWind - TppSandWindDataBody - TppFourierOcean - TppFourierOceanDataBody - TppCigaretteSmokeGlobalManager - TppHiSpeedDustActor - TppHighSpeedFilter - TppBrainDamagedFilter - TppOcean - TppWaterDropsOnCameraLens - TppSubViewport - TppVfxFileLoader - TppTextureLoader - TppNvgFilterNoise - TppModelMarkerFilterSettings - TppDamageFilterParam - TppDamageFilterExposure - TppCollectibleIndicationParam - TppSkySimTimeUpdater - TppSkyEffectControler - TppWeatherCloudShadow - TppWeatherCloudShadowSettings - TppStar - TppWeatherClimateUpdator - TppWeatherRain - TppWeatherRainData - TppWeatherRainDataBody - TppWeatherThunderEffect - TppWeatherThunder - TppWeatherThunderBody - TppSkyClouds3 - TppSkyClouds3Param - TppSky - TppDirtyModelManager - TppDirtyModelController - TppDirtyModelData - TppFootPrint - TppFootPrintBody - TppRainFilter - TppRainFilterBody - TppRainFilterInterrupt - TppRainFilterInterruptBody - TppRainFilterInterruptTrans - TppRainFilterInterruptTransBody - TppRainFilterInterruptManager - TppFloorRainSplashData - TppFloorRainSplashDataBody - TppLensFlareRootBase - TppLensFlareRoot - TppLensFlareRootBody - TppHandLightLensFlareRoot - TppHandLightLensFlareRootBody - TppLensFlareShape - TppLensFlareShapeBody - TppLensFlareShapeArray - TppLensFlareShapeCircle - TppLensFlareShapeCircleBody - TppLensFlareMaterial - TppLensFlareMaterialBody - TppLensFlareField - TppLensFlareAsymmetricField - TppLensFlareRateGraph - TppLensFlareMultipleShapeManager - TppSunLightFlare - TppImplEffectParam - TppFadeOutEffectHolder - TppTonemap - TppVolumetricFogManager - TppGlobalVolumetricFogParam - TppGlobalVolumetricFog - TppAreaVolumetricFogParam (This and TppAreaVolumetricFog are used only in PT, but can still work in TPP) - TppAreaVolumetricFog - TppAreaVolumetricFogBody - TppSprintBlur - TppSprintBlurData - TppLightProbe - TppLightProbeBody - TppLightProbeSHCoefficients - TppLightProbeSHCoefficientsBody - TppLightProbeUtility - TppLightProbeArray - TppLightProbeArrayBody - TppPointLight - TppPointLightBody - TppSpotLight - TppSpotLightBody - PrecomputeSkyFile - TppAtmosphere - TppAtmosphereBody - TppTrapExecChangeGlobalWindCallbackDataElement - TppReflectionSettingTrapCallbackDataElement - TppTrapExecThunderLightningCallbackDataElement - TppTrapExecChangeVolumetricFogCallbackDataElement - TppTrapExecOnOffVolumetricFogCallbackDataElement - TppTrapRainFilterCallbackDataElement - TppOutOfMissionRangeEffect - TppNightVision - TppNightVisionParam - NetworkInfo - MbdvcBootData - MbdvcBootBody - HudBootData - HudBootBody - UiCommonDataManager - HudCommonDataManager - UiSupport - GetRoomListReceive - GetSoldierlistReceive - SetSoldierlistReceive - FultonSoldierReceive - GetWormholeListReceive - GetWormholeAreaListReceive - EndingSettingFile - TppLadderManagerData - TppLadderData - TppLadderDataBody - TppLadderEntryPointData - TppSharedGimmickData - TppGimmickLightLinkSetData - TppGimmickPowerCutAreaData - TppGimmickElectricCableLinkSetData - TppGimmickBrokenElectricCableBank - TppGimmickBrokenCandleBank - TppGimmickLightGroupingLinkSetData - TppPermanentGimmickData - TppPermanentGimmickBank - TppPermanentGimmickSearchLightParameter - TppPermanentGimmickGatlingGunParameter - TppPermanentGimmickFultonableContainerParameter - TppPermanentGimmickImportantBreakableParameter - TppPermanentGimmickMortarParameter - TppPermanentGimmickMachineGunParameter - TppPermanentGimmickDoorParameter - TppPermanentGimmickInfraredSensorParameter - TppPermanentGimmickEventAnimationParameter - TppPermanentGimmickBridgeParameter - TppPermanentGimmickWaterTowerParameter - TppGimmickImmediateStateData - TppPermeableStaticModel - TppThermalStaticModel - BushOffenseTargetData - BushLodParameter - ObjectBrushPluginBushDataElement - TppObjectBrushPluginBush - TppObjectBrushPluginBushBody - TppBushManager - TppObjectBrushPluginBushData - TppObjectBrushPluginSkeletonModel - ObjectBrushPluginSkeletonModelBody - TppObjectBrushSkeletonModelDestructionResource - TppObjectBrushSkeletonModelReserveResource - TppTrapCheckIsInViewCallbackDataElement - TppTrapCheckIsInCameraCallbackDataElement - TppTrapExecEnvironmentMotionCallbackDataElement - TppTrapExecDamageCallbackDataElement - TppTrapCheckIsCharacterCallbackDataElement - TppTrapCheckIsCharacterWithIdCallbackDataElement - TppTrapCheckIsPlayerCallbackDataElement - TppTrapCheckCanSaveAsCheckPointCallbackDataElement - TppTrapCheckIsEnemyCallbackDataElement - TppTrapCheckIsHostageCallbackDataElement - TppTrapCheckIsPushPadCallbackDataElement - TppTrapCheckIsPlayerAndHostCallbackDataElement - TppTrapCheckIsPlayerAndLocalCallbackDataElement - TrapCheckCharacterFilterParam - TppTrapCheckIsPlayerAliveCallbackDataElement - TrapExecChangeLodSkeletonModelParam - TppCoverPoint - TppCoverPointBody - TppCoverPointProvider - CoverPointFile - TppCoverPointFileTransform - TppCombatLocatorSetData - TppCombatLocatorSetDataBody - TppCombatLocatorData - TppCombatLocatorDataBody - TppGuardTargetData - TppGuardTargetDataBody - TppCyprusBlockControl - CyprusBlockControllerData - CyprusBlockControllerDataBody - CyprusBlockLoadFileData - CyprusBlockLoadPointDataBody - CyprusMissionControllerData - TppDemoParameter - TppInGameDemoParameter - TppDemoPlayerResourceParameter - TppFuneralDemoParameter - TppTakePictureParameter - TppObjectBrushPluginFlutteringGrass - ObjectBrushPluginFlutteringGrassBody - TppAdditionalSearchableLightData - EmblemBlender - MotherBaseConstructData - MotherBaseConstructDataBody - MotherBaseConstructConnectionData - MotherBaseConstructConnector - MotherBaseConstructLocator - MotherBaseConstructLocatorBody - MotherBaseConstructDivisionLocator - MotherBaseConstructDivisionLocatorBody - MotherBaseConstructConnectLocator - MotherBaseConstructConnectLocatorBody - MotherBaseReplaceTextureData - MotherBaseLayoutFile - TppSampleGameObjectParameter - TppSampleGameObjectLocatorParameter - LuxuryBlockControllerData - TppPlayer2Parameter - TppPlayer2LocatorParameter - TppPlayer2InstanceSettings - TppPlayer2BlockControllerConfiguration - TppPlayer2BlockControllerData - TppPlayer2BlockControllerDataBody - TppPlayer2AdditionalMotionBlockData - TppPlayer2AdditionalMtarData - TppPlayer2AdditionalPartsBlockData - TppHorse2Parameter - TppHorse2LocatorParameter - TppSoldier2Parameter - TppSoldier2LocatorParameter - TppHostage2Parameter - TppHostage2LocatorParameter - TppVehicle2Parameter - TppVehicle2LocatorParameter - TppVehicle2BodyData - TppVehicle2AttachmentData - TppVehicle2WeaponParameter - TppVehicle2ReliefData - TppHeli2Parameter - TppHeli2LocatorParameter - TppLandingZoneData - TppLandingZoneDataBody - TppBuddy2BlockControllerData - TppBuddyQuiet2Parameter - TppBuddyQuiet2LocatorParameter - TppSnipePoint2Data - TppSnipePoint2DataBody - TppBossQuiet2Parameter - TppBossQuiet2LocatorParameter - TppBuddyDog2Parameter - TppBuddyDog2LocatorParameter - TppBuddyPuppyParameter - TppBuddyPuppyLocatorParameter - TppUavParameter - TppUavLocatorParameter - TppSahelan2Parameter - TppSahelan2LocatorParameter - TppSearchMissilePointData - TppSearchMissilePointDataBody - TppHidePointData - TppHidePointDataBody - TppParasite2Parameter - TppParasite2LocatorParameter - TppLiquid2Parameter - TppLiquid2LocatorParameter - TppVolgin2Parameter - TppVolgin2LocatorParameter - TppSecurityCamera2Parameter - TppSecurityCamera2LocatorParameter - TppCorpseParameter - TppCorpseLocatorParameter - TppMbQuietParameter - TppMbQuietLocatorParameter - TppWalkerGear2Parameter - TppWalkerGear2LocatorParameter - TppAnimalParameter - TppAnimalLocatorParameter - TppBirdParameter2 - TppBirdLocatorParameter2 - TppRat2Parameter - TppRat2LocatorParameter - TppWolfParameter - TppWolfLocatorParameter - TppBearParameter - TppBearLocatorParameter - TppHorse2forVrParameter - TppHorse2forVrLocatorParameter - TppVolgin2forVrParameter - TppVolgin2forVrLocatorParameter - TppPickableLocatorParameter - TppCollectionLocatorArray - TppPlacedLocatorParameter - TppDecoyAssetsLoader - TppNoiseArea2 - TppNoiseAreaBody2 - ChildrenIdConvertParameter - AvatarPhotoTextureLoadParameter - AvatarEditorSetupData - TppSimpleMissionData - TppSimpleMissionBlockControllerData - TppSimpleMissionBlockControllerDataBody - TppSimpleGameSequenceSystem - TppMarker2LocatorSystemParameter - TppMarker2LocatorParameter - RadioDaemon - RadioData - RadioDataBody - TppEspionageRadioSystemParameter - TppEspionageRadioLocatorParameter - TppTrapExecLostHostageCallbackDataElement - TppTrapExecCombatLocatorCallbackDataElement - TppSpeechFile - TppSpeechData - TppMotherBaseStageBlockControllerData - TppMotherBaseStageBlockControllerDataBody - TppMotherBaseStageClusterParameterData - TppMotherBaseStageClusterParameterDataBody - MotherBaseStageSetupFile - TppMotherBaseContainerParameter - TppMotherBaseContainerLocatorParameter ### `wiki:wiki/EquipDevelopSetting.md` ##### EquipDevelopSetting These files are responsible for setting up the item development requirements. Includes EquipDevelopConstSetting.lua and EquipDevelopFlowSetting.lua. In MGO's chunk0.dat there is also a file named just EquipDevelopSetting.lua that appears to be a combination of both of these files with the original variable names intact. However, it does lack variables for p34, p35 and p36.

Minified Variable Name

Real Variable Name

Additional Info

p00

equipDevelopID

Integer ID. I.e. 1e3

p01

equipID

TppEquip class ID. I.e. TppEquip.EQP_WP_10101

p02

equipDevelopTypeID

Item type. I.e. TppMbDev.EQP_DEV_TYPE_Handgun

p03

baseEquipDevelopId

Parent equipDevelopID.

p04

skill

Staff skill requirement. I.e. "SuppressorEngineer." 0 if not required.

p05

bluePrintId

Blue print requirement. I.e. TppMotherBaseManagementConst.DESIGN_2000. 65535 if not required.

p06

langEquipName

p07

langEquipInfo

p08

ftexPath

UI image path.

p09

equipDevelopGroupID

p10

langPowerUpInfo0

p11

langPowerUpInfo1

p12

langPowerUpInfo2

p13

langPowerUpInfo3

p14

langPowerUpInfo4

p15

langPowerUpInfo5

p16

langPowerUpInfo6

p17

langPowerUpInfo7

langPowerUpInfo8

Unused.

langPowerUpInfo9

Unused.

langPowerUpInfo10

Unused.

langPowerUpInfo11

Unused.

p30

langEquipRealName

p31

isResultRankLimited

1 if item will restrict rank.

p32

isCustomEnable

p33

isColorChangeEnable

p34

Unknown.

p35

1 if equippable by Security Team staff.

p36

Unknown. Includes all DLC and unusable items. As well as some other seemingly random items.

p50

N/A

Index for relative EquipDevelopConstSetting.

p51

derivationIndex

p52

developRank

Equipment grade.

p53

developGmpCost

p54

usageGmpCost

p55

developSectionLv

R&D Team level requirement.

p56

sectionIDForDevelop

Other Team ID.

p57

SectionLvForDevelop

Other Team level requirement.

p58

resourceType1

p59

resourceType1Count

p60

resourceType2

p61

resourceType2Count

p62

initialAvailable

p63

sectionID2ForDevelop

p64

sectionLv2ForDevelop

p65

resourceUsageType1

p66

resourceUsageType1Count

p67

resourceUsageType2

p68

resourceUsageType2Count

p69

displayInfo

Under what conditions should this item be shown in the development screen.

0: Always.

1: After staff level requirement has been met. (Actual level requirement is unknown.)

2: Never show.

3: Never show. Only used on EQP_IT_Fulton_WormHole entries.

p70

developLevel

Always 0.

p71

developTimeMinute

p72

isValidMbCoin

1 if it's an online item.

p73

intimacyPoint

Buddy bond requirement.

p74

isFobAvailable

Can be used during FOB missions.

### `wiki:wiki/EquipParameters.md` This page documents the weapon parameter tables inside [EquipParameters.lua](https://github.com/kapuragu/InfiniteHeaven/blob/master/tpp/data1_dat-lua/Assets/tpp/level_asset/weapon/ParameterTables/parts/EquipParameters.lua). When the game equips a weapon it resolves the equip ID to a weapon ID, reads that weapon's part IDs, follows each part ID into its parameter buffer, and folds everything into a single `GunInfo` struct that gameplay reads from. All stats a weapon has - fire rate, spread, damage, range, ammo, sounds - live in these tables. All addresses on this page are for **EN 1.0.15.4** (`tpp_steam_mst_en_day3800`). ##### The pipeline ```text equipId -> weaponId (equip table object, vtable call) -> gunBasic row (11 part ids + grade) -> part rows (receiver, barrel, magazine, bullet, ...) -> pool rows (receiver base/wobbling/system/sound, falloff curves) -> GunInfo (0x90-byte struct gameplay reads) ``` The assembly happens in `tpp::gm::impl::equip::EquipSystemImpl::SetUpGunInfoFromGunPartsDesc` (`0x140DC3850`). Its input is a **GunPartsDesc**: 11 bytes, one part ID per byte, in exactly the same order as a gunBasic row (see below). For a normal weapon the desc is copied from the gunBasic table; for the six custom-weapon slots it comes from `ChimeraPartsSetWork` instead. The tables are (re)built from the game's Lua parameter files by `ReloadEquipParameterTables2` (`0x140A41AE0`). ##### The buffer directory `0x142A711F0` holds the parameter-tables instance. It is a directory of pointers - each offset below holds a pointer to one buffer. Two indexing conventions apply. **Part buffers are 1-based**: row for id N sits at `base + (N - 1) * stride`, and id 0 means "no part". **Pool buffers are 0-based**: row for index N sits at `base + N * stride`. | Offset | Buffer | Row stride | Vanilla rows | Indexed by | |---|---|---:|---:|---| | +0x08 | gunBasic | 12 | 514 | weaponId (1-based) | | +0x10 | receiver | 6 | 233 | receiverId (1-based) | | +0x18 | barrel | 2 | 114 | barrelId (1-based) | | +0x20 | magazine | 8 | 191 | ammoId (1-based) | | +0x28 | muzzle option | 3 | 39 | muzzleOptionId (1-based) | | +0x30 | option (laser/light) | 1 | 9 | optionId (1-based) | | +0x38 | sight | 5 | 24 | scopeId (1-based) | | +0x40 | stock | 2 | 42 | stockId (1-based) | | +0x48 | underbarrel | 3 | 22 | underBarrelId (1-based) | | +0x50 | bullet | 14 | 112 | bulletId (1-based) | | +0x58 | receiverParamSetsBase pool | 12 | 96 | pool index (0-based) | | +0x60 | receiverParamSetsWobbling pool | 14 | 127 | pool index (0-based) | | +0x68 | receiverParamSetsSystem pool | 3 | 66 | pool index (0-based) | | +0x70 | receiverParamSetsSound pool | 8 | 40 | pool index (0-based) | | +0x78 | barrelParamSetsBase pool | 7 | - | pool index (0-based) | | +0x80 | bulletParamSetsBase pool (falloff) | 22 | - | pool index (0-based) | The gunBasic buffer is a static block at `0x142C25C50`. ##### equipId to weaponId Weapon equip IDs do **not** carry their weapon ID in the equip-ID table's type words. The mapping lives in a separate equip table object reached through the quark system table: ```text obj = *( *( *(GetQuarkSystemTable() + 0x98) + 0x1E8 ) + 8 ) type = obj->vtbl[0](obj, equipId) // 1..8 = gun categories weaponId = obj->vtbl[2](obj, equipId) // vtbl offset 0x10 ``` `GetQuarkSystemTable` = `0x140BFF050`. A reference consumer of this exact chain is `EquipParameterTablesImpl::GetAttackIdByEquipId` (`0x140A3BCD0`), which resolves `equipId -> weaponId -> receiver -> attackId`. Weapon IDs are effectively capped at **0x3FF** because the equip-ID table packs them into a 10-bit field (see below). ##### gunBasic row (stride 12) One row per weaponId. Each part ID is a single byte, which is why every part ID space is capped at 255. | Byte | Part | |---:|---| | 0 | receiverId | | 1 | barrelId | | 2 | ammoId (magazine) | | 3 | stockId | | 4 | muzzleId (barrel-muzzle model) | | 5 | muzzleOptionId (suppressor/compensator) | | 6 | scope1Id | | 7 | scope2Id | | 8 | laserFlash1Id | | 9 | laserFlash2Id | | 10 | underBarrelId | | 11 | weaponGrade (1-15) | The 11-byte **GunPartsDesc** used at realize time is bytes 0-10 of this row. ##### Receiver row (stride 6) The receiver is the weapon's core: it selects the attack (damage row) and points at four pool rows that carry the actual numbers. | Offset | Size | Field | |---:|---:|---| | +0 | u16 | attackId (damage table row) | | +2 | u8 | receiverParamSetsBase pool index | | +3 | u8 | receiverParamSetsWobbling pool index | | +4 | u8 | receiverParamSetsSystem pool index | | +5 | u8 | receiverParamSetsSound pool index | A separate byte table (`0x142349A90`, one byte per receiverId, read through `0x140DB6CB0`) selects the receiver's **motion/animation family** - which set of handling animations (draw, reload, idle pose) the weapon plays. ###### receiverParamSetsBase pool row (stride 12) | Offset | Size | Field | Stored as | |---:|---:|---|---| | +0x0 | u16 | fireRate | value x 10 | | +0x2 | u8 | aimAssistDist | meters | | +0x3 | u8 | gunAimAdjust | value x 200 | | +0x4 | u8 | effectiveRange | meters (runtime falloff anchor) | | +0x5 | u8 | effectiveRangeUI | meters (menu stat bar only) | | +0x6 | u16 | adsZoom | value x 1000 | | +0x8 | u16 | adsFov | value x 100 | | +0xA | u8 | reloadSpeed | multiplier x 100 | ###### receiverParamSetsWobbling pool row (stride 14) Seven consecutive u16 values, each stored as value x 1000: | # | Field | |---:|---| | 0 | spreadPerShot | | 1 | unk2 | | 2 | spreadRecovery | | 3 | spreadMin | | 4 | spreadMax | | 5 | shotKick | | 6 | shotKick2 | ###### receiverParamSetsSystem pool row (stride 3) Bit-packed: | Byte | Bits | Field | |---:|---|---| | 0 | 0-4 | eqpType (weapon family, 1-8) | | 0 | 5 | showMagazineMesh | | 0 | 6 | plusOneChamber | | 0 | 7 | missileMeshVariant | | 1 | 0-4 | reticleUiId | | 1 | 5-7 | triggerId (cock / semi / burst / full-auto) | | 2 | 0 | modelDedupExclude | | 2 | 1 | flag5 | | 2 | 2 | sightMountMesh | | 2 | 3 | railMountMesh | | 2 | 4 | railMountMesh2 | | 2 | 5 | altMagazineSocket | `plusOneChamber` is the only flag here with a gameplay effect: during GunInfo assembly it adds +1 to the magazine capacity. The rest drive model meshes, HUD reticle choice and trigger behavior. `eqpType` also picks the fire-sound template (below). ###### receiverParamSetsSound pool row (stride 8) An inline `char[8]` string: the weapon's **fire-sound name root**, up to 7 characters plus a terminator (`"ar01"`, `"hg00"`, ...). Not a hash - the raw text lives in the row. ##### Fire-sound name construction `DefineWeaponFireSound` (`0x140DC03A0`) wraps the root into full Wwise event names at weapon-init time: ```text sfx_w_p_[_m][_sup]_(active|nonact) player-fired sfx_w_e_[_m][_sup]_(active|nonact) NPC-fired ``` Whether the `_m` segment is inserted - and whether a sound is produced at all - follows the receiver's `eqpType`: | eqpType | Template | |---|---| | 1, 3, 4, 5, 6, 7 | `sfx_w_p__m_active` (with `_m`) | | 2, 8 | `sfx_w_p__active` (no `_m`) | The finished names are hashed through the sound system's own hasher and the 32-bit hashes are stored into the weapon work slots, so anything resolvable by the loaded soundbanks can be produced by pointing the root (and family) at it. ##### Barrel row (stride 2) | Byte | Bits | Field | |---:|---|---| | 0 | 0-3 | barrelLength (BarrelLengthType) | | 0 | 4 | hasUnderMount | | 0 | 5 | hasScopeMount | | 0 | 6 | unk | | 0 | 7 | hasSideMount | | 1 | all | barrelParamSetsBase pool index | ###### barrelParamSetsBase pool row (stride 7) Seven u8 multipliers, each stored as value x 100 (100 = 1.0 = neutral): | # | Field | |---:|---| | 0 | fireRate | | 1 | unk2 (no consumer found - dead) | | 2 | gunAimAdjust | | 3 | range (aim assist) | | 4 | rangeUI (menu stat bar) | | 5 | spreadMax | | 6 | percentOverride | ##### Magazine row (stride 8) A magazine's parameter set is `ammoId, equipAmmoId, capacity, totalCarry, bulletId` - but `ammoId` is the **row index**, not a stored field. The row holds the remaining four: | Offset | Size | Field | |---:|---:|---| | +0 | u16 | equipAmmoId (the ammo equip used for resupply) | | +2 | u16 | capacity (clamped to 10 bits) | | +4 | u16 | totalCarry (0x3FFF acts as the unlimited sentinel) | | +6 | u8 | bulletId | | +7 | u8 | padding | The same convention holds for every part buffer on this page: the part's own id (receiverId, barrelId, stockId, ...) selects the row and is never stored inside it. ##### Bullet row (stride 14) | Offset | Size | Field | |---:|---:|---| | +0x0 | u16 | bulletSpeed (m/s, player-fired) | | +0x2 | u16 | npcBulletSpeed (m/s, NPC-fired) | | +0x4 | u16 | dropRate (player bullet drop; NPC rounds fly flat) | | +0x6 | u8 | bulletParamSetsBase index (Player) | | +0x7 | u8 | bulletParamSetsBase index (NPC) | | +0x8 | u8 | trail-effect index | | +0x9 | u8 | unk | | +0xA | u8 | bulletType (normal / spread / blast / shell / water / airshock) | | +0xB | u8 | ricochetSize | | +0xC | u8 | blastId | | +0xD | u8 | bit 0 = lethal flag, bits 1-5 = eqpType | Both falloff indices matter: the player curve drives the player's damage model, the NPC curve drives soldiers firing the same weapon. NPC ballistics ignore `dropRate` entirely - NPC rounds have zero drop. `bulletType` spread (buckshot) is engine-handled: the fire routine spawns a hardcoded 8 pellets in a 2-degree cone for that type. ###### bulletParamSetsBase (falloff) pool row (stride 22) Three damage channels, each "full strength until near, fades to far, then a residual floor", plus penetration: | Offset | Size | Field | Stored as | |---:|---:|---|---| | +0x00 | u16 | tranqNear | meters x 10 | | +0x02 | u16 | tranqFar | meters x 10 | | +0x04 | u16 | tranqResidual | fraction x 100 | | +0x06 | u16 | damageNear | meters x 10 | | +0x08 | u16 | damageFar | meters x 10 | | +0x0A | u16 | damageResidual | fraction x 100 | | +0x0C | u16 | impactNear | meters x 10 | | +0x0E | u16 | impactFar | meters x 10 | | +0x10 | u16 | impactResidual | fraction x 100 | | +0x12 | u8 | penetrateLevel near | MINIMUM < TRANQ < HANDGUN < RIFLE < SNIPER < AMRIFLE | | +0x13 | u8 | penetrateLevel far | | | +0x14 | u16 | penSwitchDistance | meters x 10 | ##### Stock row (stride 2) | Byte | Field | Stored as | |---:|---|---| | 0 | spreadRecovery multiplier | value x 100 | | 1 | movementSway multiplier | value x 100 | ##### Muzzle option row (stride 3) | Byte | Field | |---:|---| | 0 | grouping multiplier (value x 100) | | 1 | durability in shots (255 = infinite) | | 2 | bit 0 = suppressor (0 = brake/compensator) | The HUD suppressor gauge derives its segment count from durability: 255 = 4 segments (infinite), under 16 = 1, up to 30 = 2, above = 3. ##### Sight row (stride 5) | Byte | Field | |---:|---| | 0 | zoom1 | | 1 | zoom2 | | 2 | zoom3 | | 3 | scopeUiId | | 4 | flags: bit 0 booster, bit 1 nvg, bit 2 builtIn, bit 3 rangeFinder, bit 4 rangeFinderBulletDrop | ##### Option row (stride 1) | Bit | Field | |---:|---| | 0 | isLight (flashlight) | | 1 | isLaser | ##### Underbarrel row (stride 3) An underbarrel is a sub-weapon: it borrows a receiver for firing behavior and a magazine for ammunition. During GunInfo assembly the underbarrel's receiver and pools are re-read into a secondary block of the same GunInfo. | Byte | Field | |---:|---| | 0 | receiverId | | 1 | ammoId (magazine) | | 2 | weaponGrade | ##### Custom-weapon slots (Chimera) The six saveable custom-weapon builds occupy fixed equip IDs `0x367-0x36C`. Their parts do not come from gunBasic - each slot stores its own GunPartsDesc in the `ChimeraPartsSetWork` block at `0x142C934A0` (returned by `tpp::gm::GetChimeraPartsSetWork`, `0x141E03790`): | Offset | Contents | |---|---| | +0x00 | u16 x 6: the base equipId each custom build was created from | | +0x12 + slot * 0xE | 14 bytes per slot: the 11-byte parts desc + 3 extra bytes | Weapon-init and `GetAttackIdByEquipId` both special-case this equip ID range and read the desc from here instead of resolving a weaponId. ##### Damage parameter table Damage rows live in a separate table, keyed by **attackId** (the u16 in the receiver row). Instance pointer at `0x142BDCFF0`; the row array starts at instance + 8. Rows are **0-based**: row for attackId N at `base + N * 0x1A`. 489 rows. Rebuilt by `ReloadDamageParameter` (`0x1405CE160`), read through `GetDamageParameter` (`0x1405C9E30`). Row layout (stride 0x1A): | Offset | Size | Field | |---:|---:|---| | +0x00 | u16 | lethalDamage | | +0x02 | u16 | staminaDamage | | +0x04 | u16 | impactForce | | +0x06 | u16 | lethalDamageUI (menu stat bar) | | +0x08 | u16 | unk3 | | +0x0A | u16 | unk4 | | +0x0C | u16 | unk5 | | +0x0E | u16 | unk6 | | +0x10 | u16 | unk7 | | +0x12 | u16 | unk8 | | +0x14 | u16 | flags (see below) | | +0x16 | u8 | damageSource | | +0x17 | u8 | bits 0-3 injureType, bits 4-7 injurePart | | +0x18 | u8 | unk11 | | +0x19 | u8 | unk12 | Flag bits at +0x14: | Bit | Flag | |---:|---| | 0 | hitNPC | | 1 | isSniper | | 2 | isShotgun | | 3 | isTranq | | 4 | isStun | | 5 | isExplosive | | 6 | isMelee | | 7 | isBlade | | 8 | isFire | | 9 | isWater | | 10 | isElectric | | 11 | isParasite | | 12 | isGas | | 13 | isVehicleHit | | 14 | unk | | 15 | isPenetrating | ##### Equip-ID table (model and package) Separate from the parameter tables: every equipId maps to its model and package through a compressed-index table. The equipId is first compressed to a slot index (649 slots), then: - **Info list** (`0x142C20FD0`, stride 0x18): +0x00 u64 `.parts` path hash, +0x08 u64 `.fpk` path hash, +0x10 block byte. - **Type words** (`0x142A70928`, u16 per slot): `(equipType & 0x3F) | (subId << 6)`. The 10-bit subId field is what caps weapon IDs at 0x3FF. For gun equips the subId here is not used for parameter resolution - the equip table object above is authoritative. ##### Address summary (EN 1.0.15.4) | Address | What | |---|---| | 0x142A711F0 | parameter-tables buffer directory | | 0x142C25C50 | gunBasic buffer (514 rows) | | 0x142BDCFF0 | damage table instance pointer | | 0x142C934A0 | ChimeraPartsSetWork (custom-weapon descs) | | 0x142C20FD0 | equip-ID info list | | 0x142A70928 | equip-ID type words | | 0x142349A90 | receiver motion-type table | | 0x140DC3850 | SetUpGunInfoFromGunPartsDesc | | 0x140DC03A0 | DefineWeaponFireSound | | 0x140A3BCD0 | GetAttackIdByEquipId | | 0x140A41AE0 | ReloadEquipParameterTables2 | | 0x1405CE160 | ReloadDamageParameter | | 0x1405C9E30 | GetDamageParameter | | 0x140DB6CB0 | GetReceiverType (motion family) | | 0x141E03790 | GetChimeraPartsSetWork | | 0x140BFF050 | GetQuarkSystemTable | ### `wiki:wiki/Export_Symbols.md` ###### Fox.ExportSymbols Game shipped with some debug functions still in the exe, locked behind debug flags. One of them is `Fox.ExportSymbols`. To enable it, patch the exe (version 1.0.15.3, md5 7cc5f282b068f741adda2bb1076fb721): - at 0x1431779CA change `0x74,0x17` to `0xEB,0x17` - at 0x143177A29 change `0x75,0x47` to `0x48,0x90` Call `Fox.ExportSymbols("")` in lua, check "modules.txt" contents (same directory as exe). According to code, there should be "symbols.txt" with entity info, but file is missing. ###### Fox.ExportSerializeInfo You can also dump xml-serialized info without any patches: Create directory `tmp` in same directory as exe and call `Fox.ExportSerializeInfo()` from lua. Output is in `tmp/Tpp_edb_win64.xml`. Sample data: - [Tpp_edb_win64.xml](/assets/Export_Symbols/Tpp_edb_win64.xml) - [modules.txt](/assets/Export_Symbols/modules.txt) ### `wiki:wiki/External_modding_resources.md` Links to assorted MGSV modding references. See also: [External Guides](/Guides#external-guides). ##### Forums/Threads | [Modders' Heaven Discord Server](https://discord.gg/moddersheaven) | Active community modding, research and discussions | | [xentax.com](https://web.archive.org/web/20230513141950/https://forum.xentax.com/viewtopic.php?f=10&t=12407) | Early foundational Ground Zeroes/Phantom Pain modding thread | | [/r/moddergearsolid](https://www.reddit.com/r/moddergearsolid/) | Subreddit | {:.stretch} ##### Resources/Notes | [Collection of MGSV links](https://github.com/unknown321/mgsv_wiki) | Including to specific xentax posts | | [unknown321s MGSV research](https://unknown321.github.io/mgsv_research/) | | | [mgswaifus](https://unknown321.github.io/mgswaifus/) | Unique staff info | | [Monster guns](https://unknown321.github.io/mgsmonsterguns/) | Weapon Info | | [Cosmetics](https://unknown321.github.io/mgsv_research/cosmetics.html) | Research into methods of applying cosmetic models | | [FV2/Fmdl](https://unknown321.github.io/mgsv_research/fv2.html) | Research into FV2/Fmdl | | [Player motions](https://unknown321.github.io/mgsv_research/motions.html) | Research into player motions | | [mgsvdump](https://github.com/unknown321/mgsvdump) | Dump of MGSV lua globals | | [MGSV-deminified-lua](https://github.com/TinManTex/mgsv-deminified-lua) | De-minified data1 luas | | [MockFox](https://github.com/TinManTex/MockFox) | Framework to load MGSV TPP lua scripts outside of mgstpp | | [mgsv-lookup-strings](https://github.com/TinManTex/mgsv-lookup-strings) | Strings scraped and manually gathered from mgsv, useful for trying to match against hashes | | [Nuke watcher](https://unknown321.github.io/mgsv_nuke_watcher/) | | | [fuse](https://github.com/unknown321/fuse) | TPP master server implementation | | [dynamite](https://github.com/unknown321/dynamite) | Co-op mod | | [tpp-tracking](https://github.com/unknown321/tpp-tracking) | 00.dat lua changes in git | | [BobDoleOwndU's MGSV documentation](https://bobdoleowndu.github.io/mgsv/documentation/index.html) | Including: [EquipDevelopFlowSetting.lua Information](https://bobdoleowndu.github.io/mgsv/documentation/equipdevelopflowsetting.html), [Getting FMDLs to Load Custom Texture Names](https://bobdoleowndu.github.io/mgsv/documentation/customtexturenames.html) | | [Poster modding resource](https://drive.google.com/file/d/0B4HIOk1QhmKAZnBSUVZ5bnY5SzA/view?usp=sharing) | For those interested in editing the 6 collectible posters and their cardboard box cutouts | {:.stretch} ### `wiki:wiki/FCLO.md` The .fclo format is a binary format used to set up cloth physics for the Fox Engine's physics engine to simulate. ##### Usage Cloth physics. Specific usage unknown. ##### Format ###### Header - 0x0 - 0x3 (char\[4\]): 'OLCF' Backwards format signature. - 0x4 - 0x7 (unint32): Section 0 count.\[1\]\[2\] - 0x8 - 0xB (uint32): Section 1 count.\[1\]\[2\] - 0xC - 0xF (uint32): Section 3 count. - 0x10 - 0x13 (uint32): Section 4 count. - 0x14 - 0x17 (uint32): Section 5 count. \[1\]The the format for sections 0 and 1 are identical. These two could be one section with two sizes that are added together. However, tests in-game revealed that shifting all value from the section 1 count to the section 0 count (for example, if there were 20 entries in section 0 and 8 in section 1 pre-shift, there would be 28 in section 0 and 0 in section 1 post-shift) and the other way around did affect (break) the function of the .fclo in-game. This would, however, explain why the indices in sections 3 and 4 can and often are higher than the counts of sectiosn 0 and 1 but not higher than the counts of sections 0 and 1 combined. The values are too large too often and without a pattern to suggest that they're simply indices into section 2. This is the last part of the format that needs to be reversed - the meaning of the indices of sections 3 and 4. \[2\]The amount of entries in section 2 is the sum of the section 0 and 1 entries. This may not be true; it could also be two sections with the same format, just like sections 0 and 1. This would make the indices problem even stranger, however. ###### Sections 0 and 1 - 0x0 - 0x11 (Vector3): Appears to be some form of transform, though it could be three unrelated floats, as there is no fourth float for padding for SIMD reading as most transforms in most formats have.\[1\] - 0x12 - 0x15 (StrCode32Hash): A cloth sim bone name. For example, "SKL_700_CLTH_SIM". These sections appear to define cloth sim bones. The bones themselves are defined in the FMDL, however. Confusingly, and contrary to the findings of the test conducted in-game described above, there seems to be no logical split between the two sections based off of the bone names and their position in the cloth sim bone hierarchies defined in cloth-sim-using models. \[1\]It is impossible that this vector represents a rotation as it is missing a w component and also impossible that it represents a scale as some values have been observed to be negative. ###### Section 2 - 0x0 - 0x3 (uint32): Collision bone hash index 0. - 0x4 - 0x7 (uint32): Collision bone hash index 1. - 0x8 - 0xB (uint32): Collision bone hash index 2. - 0xC - 0xF (uint32): Collision bone hash index 3. - 0x10 - 0x25 (Quaternion): A rotation with an unknown purpose. It could also be four individual floats. Entries in this section appear to be connected in a 1:1 relationship with a cloth sim bone, though how this is accomplished is unknown, aside from the fact that it is likely done via either section 3 or 4. This section seems to describe how the sim bone it is linked with interacts with up to four other bones. It appears that if a bone is listed here it the sim bone will collide with it rather than clip through it. Basically, this section sets up collision for its corresponding sim bone. The use of the Quaternion is unknown. ###### Section 3 - 0x0 - 0x3 (uint32): Unknown index 0. - 0x4 - 0x7 (uint32): Unknown index 1. What these indices index and how is uncertain. Values in both index 0 and 1 have been observed exceeding the range of the counts of sections 0 and 1, though never the total of the two combined (which is also the entry count of section 2). This would suggest that sections 0 and 1 are actually one section, but the effects observed in-game of shifting the entry counts to one side or the other contradict this, as does the mere presence of two count variables in the header. ###### Section 4 - 0x0 - 0x3 (uint32): Unknown index 0. - 0x0 - 0x3 (uint32): Unknown index 1. - 0x0 - 0x3 (uint32): Unknown index 2. - 0x0 - 0x3 (uint32): Unknown index 3. The purpose of these indices is also unknown. ###### Section 5 - 0x0 - 0x4 (StrCode32 hash): Bone hash. This section is a list of hashed bone names that section 2 uses to define collision. For example, a cloth sim file for a coat might list and use "SKL_000_WAIST" here as collision, and not clipping, should occur between that bone and the simulated cloth. ### `wiki:wiki/FCNP.md` The .fcnp format is used to define connection points for models in Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain. ###### Resources [010 Editor Template](https://github.com/kapuragu/FoxEngineTemplates/blob/main/fcnp.bt) [FcnpTool](https://github.com/BobDoleOwndU/FcnpTool) ### `wiki:wiki/FILTERLUT_TEXTURE_GUIDE.md` ![](/assets/FILTERLUT_TEXTURE_GUIDE/Screenshot_texture_exporter.png) *This guide was written a long time ago for an inquisitive user who wanted to learn more about the steps for creating [I Can't Believe It's Not ReShade](https://www.nexusmods.com/metalgearsolidvtpp/mods/406). It touches on the different lookup tables that are in the base game, their interactions (stacking) with each other, and how to save the changes with Photoshop's DDS Plugin. FILTERLUT files use a special format: 8.8.8.8 ARGB 32 bpp | unsigned / BC7. This format is unsupported in GIMP (as of 2.10.38), thus the Adobe Photoshop Plugin is recommended for editing lookup tables.* ##### What They Do, Where to Find Them LUTs are the in-game color processing. For example, Night Vision Goggles turn everything green, fixing a critical injury de-saturates red colors, the FOXDIE gimmick in Ground Zeroes makes the colors go crazy — that's handled using LUTs. These filters can be modified to make mods like ICBINR and the [OniVision Goggles](https://www.nexusmods.com/metalgearsolidvtpp/mods/402), but the process is a bit different from conventional texture modding. Most of TPP's filters are found in: ``` Assets\tpp\pack\resident\resident.pftxs ``` After unpacking `resident00.pftxs`, navigate to: ``` resident00_pftxs\Assets\tpp\effect\gr_pic\lut\ ``` You'll find 6 filter lookup tables. FILTERLUTs don't have mipmaps, so there's only going to be a `.ftex` and a `.1.ftexs` file for each of them. Convert them with [ftex tool](https://github.com/Atvaark/FtexTool/releases) (note: ftextool versions before v0.3.3 did not support A8R8G8B8. v0.3.3 specifically fixed FILTERLUT modding) and open up the `.dds` texture with Photoshop. It'll look like 16 tiles ranging from black/green/red to white/blue/purple. ![](/assets/FILTERLUT_TEXTURE_GUIDE/Common_base_a_FILTERLUT.dds.png) ##### In-Game Effects Here's my current understanding of how the filters are set up: 1. Filters behave like layers. Most areas in TPP will have multiple filters stacked on top of one another. In this sense, the final filter is the one that determines the final colors you see in-game for that particular area. 2. `common_base_a_FILTERLUT` is the base filter for TPP — typically used as a preliminary layer. Daytime Afghanistan, the sortie prep/customization menus, and Mother Base(?) use this as a first-pass filter. - In particular, the Sortie Prep menu and nighttime Afghanistan only use `common_base`. These two places use `common_base` as their final layer. 3. `common_clearSky_a_FILTERLUT` is the final filter for daytime Afghanistan — the "piss filter," as people liked to call it. This filter is also used in the mission Pitch Dark, Episode 13. For that mission, the filter is applied throughout the day and night cycle in Africa. 4. `mtbs_2014E3_a_FILTERLUT` appears to be the final filter for Mother Base, both daytime and nighttime. 5. `common_dmg_a_FILTERLUT`, `common_dmg_b_FILTERLUT`, and `common_outarea_a_FILTERLUT` affect the low-health, post-severe injury treatment, and out of AO colors respectively. 6. `mafr_clearSky_a_FILTERLUT` is the final filter for Africa, both daytime and nighttime. 7. `mafr_lab_tgs_FILTERLUT` is the final filter for the Lufwa Valley Jungle area. *Note: `mafr_clearSky_a_FILTERLUT` and `mafr_lab_tgs_FILTERLUT` are not originally packed within `resident00.pftxs`. To grab the originals, you'll need to check inside:* ``` Assets\tpp\pack\location\mafr\pack_common\mafr_common.pftxs ``` ###### In Summary: - **Afghanistan Day**: Pre-filtered Render → `common_base_a_FILTERLUT` → `common_clearSky_a_FILTERLUT` → End Result - **Afghanistan Night**: Pre-filtered Render → `common_base_a_FILTERLUT` → End Result - **Africa Day + Night**: Pre-filtered Render → `mafr_clearSky_a_FILTERLUT` → End Result - **Pitch Dark (Episode 13) Day + Night**: Pre-filtered Render → `common_clearSky_a_FILTERLUT` → End Result - **Lufwa Valley**: Pre-filtered Render → `mafr_clearSky_a_FILTERLUT` → `mafr_lab_tgs_FILTERLUT` → End Result - **Sortie Prep / Customization Menus**: Pre-filtered Render → `common_base_a_FILTERLUT` → End Result - **Mother Base**: Pre-filtered Render → `common_base_a_FILTERLUT` → `mtbs_2014E3_a_FILTERLUT` → End Result ###### Misc. Filters & Speculation: - Filters like the Night Vision Goggles (`common_nvg_a_FILTERLUT`) and the Shining Lights "Wolbachia(?) Vision Goggles" (`common_wvg_a_FILTERLUT`) are appended to the end of these filter pass-throughs to achieve their visuals. - Cyprus has its own set of filters: - `cypr_saturation_m80_FILTERLUT` - `CyFilm_noRed_FILTERLUT` - `CyFilm_FILTERLUT` - `CyFilm_Day_FILTERLUT` - `CyFilm_Day_FILTERLUT` is likely the filter applied to the game's final cutscene (Cyprus morning), but I have not tested with it. `CyFilm_noRed` is likely the filter that's applied when Snake is blown back by The Man On Fire when crawling towards the elevator. - I've also found `TFGreenFinal_DD10_FILTERLUT`, `TFGreenFinal_DD30_FILTERLUT`, and `TFGreenFinal_FILTERLUT` in the textures, though I haven't confirmed how/where they are used, if at all. ##### Modding LUTs If you plan on reworking multiple LUTs, my approach was to edit `common_base_a_FILTERLUT` first, until I was happy with how the sortie prep and Afghanistan night looked, and then move onto the other filters. When tweaking a lookup table, I would: 1. Take screenshots from in-game that used the LUT I wanted to edit. 2. Bring those screenshots into Photoshop. 3. Use the **Selective Color** adjustment and **Hue/Saturation** adjustments to get the colors the way I liked. Example: ![](/assets/FILTERLUT_TEXTURE_GUIDE/AFGH_DAY_1.png) Once I had the changes, I would drag and drop the adjustment layer from the screenshot onto the LUT texture: ![](/assets/FILTERLUT_TEXTURE_GUIDE/Afgh_filter_2.png) When you're finished with an edit: - Save the `.dds` as "8.8.8.8 ARGB 32 bpp | unsigned" - Save it as a **Volume Texture** and **No MIP maps**. Example: ![](/assets/FILTERLUT_TEXTURE_GUIDE/Dds_format.png) Then: - Repack the `.pftxs` - Build a mod file - Install it - Take more screenshots - Re-tweak the adjustment layer until you're satisfied with the results. **Remember to work on one filter at a time** — if you want to make changes to Afghanistan during the day and the night: - Take nighttime screenshots first. - Fine-tune your `common_base_a_FILTERLUT`. - Then take your daytime screenshots with your modified `common_base_a_FILTERLUT` applied. - That way, the daytime screenshots will accurately convey how the `common_clearSky_a_FILTERLUT` will look when layered on top. Keep in mind: - `common_clearSky_a_FILTERLUT` is also featured in **Pitch Dark**, even at nighttime, so you'll want to take some screenshots from that mission as well. ### `wiki:wiki/FMDL_Studio_V2.md` FMDL Studio V2 is a Unity project that is designed to be a one-stop shop for importing and exporting Fox Engine models. You can find more information on its [wiki page](https://github.com/BobDoleOwndU/FMDL-Studio-v2/wiki). ###### Resources [Using FMDL Studio with Blender](/Using_FMDL_Studio_with_Blender/) ### `wiki:wiki/FMTT.md` The file type .fmtt is a reference for the material ID maps for models, shaders load the material ID texture and use it to load the fmtt. A condensed definition of this format would be an array of code similar to the reference below: ``` csharp type public MaterialPreset = { F0 : float32 RoughnessThreshold : float32 ReflectionDependDiffuse : float32 AnisotropicRoughness : float32 SpecularColor : ColorRGB Translucency : float32 } ``` It should be noted that MatParamIndex_\# parameters allow one material to have multiple presets assigned to it. The codeblock above is a parameter for all materials. Most notably SpecularColor. The location of these files can be found in data1.dat. There can only be 256 material presets assigned to this array. ### `wiki:wiki/FRIG.md` The .frig or Fox Rig format is believed to be used to set up IK groups for .fmdl files. ##### Header - 0x0 - 0x3 (uint32): Signature. - 0x4 - 0x7 (uint32): Header length. - 0x8 - 0xB (uint32): Unknown. - 0xC - 0xF (uint32): Num Entries? - 0x10 - 0x13 (uint32): Unknown. - 0x14 - 0x17 (uint32): File length. - 0x18 - 0x1B (uint32): Offset for bone hash section. - 0x1C - 0x1F (uint32): Offset for unknown section. ##### Unknown Section Info - 0x0 - 0x3 (uint32): Unknown. - 0x4 - 0x7 (uint32): Num entries. - 0x8 - (0x8 + 0x4 \* num entries - 1) (uint32\[\]): Entry offsets. ##### Unknown Section Data - 0x0 - 0x3 (uint32): Unknown - 0x4 - 0x11 (string): Name. - 0x12 - 0x57 (binary32\[\]): Unknown. ##### Bone Hash Section Info - 0x0 - 0x3 (uint32): Num entries. ##### Bone Hash Section Data - 0x0 - 0x3 (uint32): Unknown. - 0x4 - 0x7 (uint32): Truncated bone hash. ### `wiki:wiki/FRT.md` The .frt format is a binary file format used in GZ and TPP to store an AI route set. A route set contains a number of [routes](/Route), which dictate AI movement and behavior. There is a file format implementation in [FoxLib](/FoxLib). frt files can be opened and created with [FoxKit](/FoxKit). Further info [here](https://github.com/youarebritish/FoxKit/wiki/Working-with-Route-Builder). ##### Usage Each quest and each mission can load a single frt file at a time. Some missions have more than one frt, but in different fpks, so only one of them is loaded at a time. A given AI agent is assigned a number of routes, and which one it's currently using is dependent upon the alert state: - Sneak route: Used when the agent's CP is unaware of the player. - Caution route: Used when the encampment is on alert. - Alert route: Used during combat alert. Combat AI usually uses a unique system, however, so having an alert route defined is rare. You can change an agent's sneak route in Lua by calling: `GameObject.SendCommand(gameObjectId, { id="SetSneakRoute", route=routeId })` where gameObjectId is the GameObject's ID (obtained through calling GameObject.GetGameObjectId) and routeId is the name of the desired route, for instance, rts_ptr_e_citadel_W_0000. The caution and alert routes can be changed the same way, using "SetCautionRoute" and "SetAlertRoute" respectively. For a detailed description of the route system, see the article on [routes](/Route). ##### Format There are two known frt formats: one used in GZ and one used in TPP. The GZ format uses a packed World Space Vector3 in a uint64 with an origin point in the header. ###### Header - 0x0 - 0x3 (string): 'ROUT' format signature. - 0x4 - 0x5 (uint16): Version number. 3 for TPP, 2 for GZ. - 0x6 - 0x7 (uint16): Route count. If version is GZ: - 0x0 - 0x7: Skipped. - 0x8 - 0x13 (Vector3Float): World space origin point. - 0x14 - 0x17: Skipped. If end. - 0x0 - 0x3 (uint32): Route IDs offset. - 0x4 - 0x7 (uint32): Route definitions offset. - 0x8 - 0xB (uint32): Route node positions offset. - 0xC - 0xF (uint32): Route node event tables offset. - 0x10 - 0x13 (uint32): Events offset. If version is GZ: - 0x0 - 0x7: Skipped. If end. The header is followed by the route IDs, of which there is one for each route. A route ID is a StrCode32 hash, and is the name the route is referred to by in Lua or route event parameters. ###### Route definitions After the route IDs are the route definitions, of which there is one for each route. The offsets listed in each entry are relative to the entry's own offset. In other words, add the offset for the route definition to its component offsets in order to find the data that they point to. ###### Route definition struct - 0x0 - 0x3 (uint32): Initial node offset. - 0x4 - 0x7 (uint32): Initial node event table offset. - 0x8 - 0xB (uint32): Initial node event offset. - 0xC - 0xD (uint16): Number of nodes. - 0xE - 0xF (uint16): Number of events. ###### Node positions This section contains the node positions in sequential order. The first route's node positions are stored here, then the second route's node positions, and so on. The GZ version packs its node positions into uint64. ###### Node position struct If version is GZ: - 0x0 - 0x7 (uint64): A packed Vector3 added onto the origin point. The first 21 bits are the x coordinate, with the most significant bit, 21, serving as the sign. The same follows for the next 19 bits for for the y coordinate and the rest of the 21 bits for the z coordinate. Finally, each are divided by 1024, and added onto the origin point Vector3 world position. If version is TPP: - 0x0 - 0x3 (float): World space position, x coordinate. - 0x4 - 0x7 (float): World space position, y coordinate. - 0x8 - 0xB (float): World space position, z coordinate. ###### Node event tables This section contains metadata for each node linking it to its events. There is one entry for each node. ###### Node event table struct - 0x0 - 0x1 (uint16): Event count. - 0x2 - 0x3 (uint16): Edge event index. This is the index of the node's initial event (which is also its edge event), from the start of the route's event list. Contrary to what you might expect, the edge event index is an index into the *route*'s event list, not the *routeset*'s. In other words, it will always be 0 for the first node in a route, and will increment for each subsequent node by its event count. ###### Events This section contains all of the events in sequential order. The first node's events are stored here, then the second node's events, and so on. The first event in each node's event list is its edge event. ###### Event struct - 0x0 - 0x3 (uint32): StrCode32 hash of the event type. - 0x4 (uint8): Node Bool. 1 if Node event, 0 if Edge event. - 0x5 (uint8): Aim Point Enum. - 0x6: Empty. - 0x7 (uint8): Loop Bool. 1 if the agent should loop on this event. - 0x8 - 0x9 (uint16): Wait time, in frames, minus one. 0 on Edge events. - 0xA - 0xB (int16): Facing direction. 0 on Edge events. If version is GZ: - 0x0 (uint8): Inverse of the Node Bool: 255 if Node event, 0 if Edge event. If end. - 0x0 - 0x3 - Aim Point param 1. - 0x4 - 0x7 - Aim Point param 2. - 0x8 - 0xB - Aim Point param 3. - 0xC - 0xF - Aim Point param 4. - 0x10 - 0x13 - Event Type param 1. - 0x14 - 0x17 - Event Type param 2. - 0x18 - 0x1B - Event Type param 3. - 0x1C - 0x1F - Event Type param 4. If version is TPP: - 0x0 - 0x3 (string): Memory leak string on PC, skipped. If end. ###### Aim Point param types One of the following Aim Point Param sets will be used based on the Aim Point Enum. ###### No Target (0) All params are zero. The route agent has no aim target. ###### Static Point (1) The route agent uses a world space point as an aim target. - Param 1 (float): World space x coordinate. - Param 2 (float): World space y coordinate. - Param 3 (float): World space z coordinate. ###### Character (2) The route agent uses a character id as an aim target. Examples of the strings hashed here include "Player" for the player, and GameObjectLocator entity names, like "SupportHeli" or "hos_quest_0000". - Param 1 (uint32): StrCode32 hash of the character id. - Param 2: Skipped, but a 64-bit leftover of the hash is often written here. ###### Route as Sight Move Path (3) The route agent uses a special route as an aim target. If the hash is of an empty string, "", it will be skipped. - Param 1 (uint32): StrCode32 hash of the route name. - Param 2 (uint32): StrCode32 hash of the route name. - Param 3 (uint32): StrCode32 hash of the route name. - Param 4 (uint32): StrCode32 hash of the route name. ###### Route as Object (4) Very rare, and seems to be structurally identical to Route as Sight Move Path (3). Not much is known about it. ###### Event Type params One of the following Event Type Param sets will be used based on the Event Type hash. Here are some of the discovered event types and their known parameters: ###### Edge events ##### Common Vehicle Used by VehicleBackFast, VehicleBackNormal, VehicleBackSlow, VehicleMoveFast, VehicleMoveNormal, VehicleMoveSlow and VehicleDir in TPP. - Param 1 (uint32): StrCode32 hash of the rail name found in .frld files. - Param 2 (int32): Usually zero, but may sometimes be a speed measurement in RPM. ###### Node events ##### IdleAct Used by RelaxedIdleAct and CautionIdleAct in TPP. - Param 1 (uint32): StrCode32 hash of an animation act type. - Param 2: Unknown, rare, definitely not a 64 bit leftover. Not zero in s10030.frt. ##### Conversation Used in GZ. - Param 1 (uint32): StrCode32 hash of the name of the "conversation list" found in EnemyConversationList .json files. - Param 2: Skipped, but a 64-bit leftover of the hash is often written here. - Param 3 (uint32): StrCode32 hash of the name of the "friend" conversation partner to the route agent. - Param 4: Skipped, but a 64-bit leftover of the hash is often written here. ##### ConversationIdle Used in TPP. - Param 1 (uint32): StrCode32 hash of the "conversation label" found in .spch files. - Param 2 (uint32): StrCode32 hash of the name of the "friend" conversation partner to the route agent. - Param 3: Skipped, but a 64-bit leftover of the hash is often written here. - Param 4 (int32): Range integer, in world space units/meters. ##### SendMessage Used by SendMessage, and strangely by PutHostageInVehicle and TakeHostageOutOfVehicle, in TPP. - Param 1: Unknown. - Param 2 (uint32): StrCode32 hash of the message string received in Lua messages. - Param 3 (uint32): StrCode32 hash of a route's name for some reason. - Param 4: Skipped, but a 64-bit leftover of the hash is often written here. ##### SwitchRoute Used in TPP. If a route agent triggers this event, a designated Lua function will be called with the "function name" and "argument" hashes, and if it returns true, the route agent will change to the specified route. This function can be found in [TppEnemy.lua](https://github.com/TinManTex/mgsv-deminified-lua/blob/master/data1/Assets/tpp/script/lib/TppEnemy.lua). The game's default vanilla functions only include "IsGimmickBroken", "IsNotGimmickBroken", "CanUseSearchLight" and "CanNotUseSearchLight". If the function name is not one of these four, this function will return true. "IsGimmickBroken" checks if the argument hash is a broken gimmick with TppGimmick.IsBroken, and returns true if so, allowing the route agent to switch routes. Naturally, "IsNotGimmickBroken" simply returns the opposite. "CanUseSearchLight" similarly checks if the gimmick in the argument is not broken, and if it's currently nighttime with TppClock.GetTimeOfDay, returning true only if both are correct. "CanNotUseSearchLight" also returns the opposite here. - Param 1 (uint32): StrCode32 hash of the name of the route to switch to. - Param 2 (uint32): StrCode32 hash of the function name. - Param 3 (uint32): StrCode32 hash of an argument to use in the function. ##### SyncRoute Used in TPP. Used in conjunction with [the mission's syncRouteTable](https://mgsvmoddingwiki.github.io/Mission_Table_Subscripts/#syncroutetable). - Param 1 (uint32): Sync table index. - Param 2 (int32): Sync route step index. ##### Resources - [010 Editor template](https://gist.github.com/youarebritish/014633a757f8647d03e5861b3182f27c) - [Some research notes and data dumps](https://github.com/TinManTex/mgsv-lookup-strings/tree/master/RouteTool/Research) ### `wiki:wiki/FSM.md` The .fsm format, or **F**ox **S**ystem **M**ovie, is the format used for Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain's in-game rendered cutscenes. The .fsm files are made up of two different kinds of data chunks. DEMO chunks, which are likely animation data, and SND chunks, which are Wwise audio files that have been split into multiple pieces. The .fsm format is Little-Endian, meaning bytes are written in reverse order of significance. ##### FSM Header The .fsm format's header is always the same; but there are cases where a .fsm file may not have a header at all. - 0x0 - 0x3 (string): Signature. Always "SYS ". - 0x4 - 0x7 (int): Unknown. Always 0x10. - 0x8 - 0xF: Padding. ##### First SND Header The first SND header differs from all of the other chunk headers, which all follow the same format. The first SND header follows this pattern: - 0x0 - 0x3 (string): Signature. Always "SND ". - 0x4 - 0x7 (int): Chunk length. - 0x8 - 0xF (double): Time for chunk to start playing. - 0x10 - 0x13 (int): Complete Wwise file's length. - 0x14 - 0x1F: Unknown. ##### Chunk Header All other chunks follow the exact same pattern. - 0x0 - 0x3 (string): Signature. Always either "SND " or "DEMO" - 0x4 - 0x7 (int): Chunk length. - 0x8 - 0xF (double): Time for chunk to start playing. For END, it's the length of the whole demo. ##### DEMO Chunk DEMO chunks use three (or more) different types. 0 can contain motion data and events, 1 is usually used for the first DEMO chunk of GZ .fsm files (with TPP having one unused .fsm that uses it as well) and seem to function like the .sand files in TPP, and 2 are motionless and event only DEMO chunks. ###### Demo Data Section - 0x0 - 0x3 (int) - DEMO Chunk Type, so far only 0, 1 and 2 have been identified. ###### The following are only applied in the 0 chunk type: - 0x0 - 0x3 (int) - Unknown, but the Root Vector is completely omitted if this value isn't 0x0A. - 0x4 - 0x7 (int) - Unknown - 0x8 - 0xB (int) - Unknown - 0xC - 0xF (int) - Motion segment count. ###### The following are only applied in the 0 and 2 chunk types: - 0x0 - 0x3 (int) - Size of the DEMO chunk starting from the DEMO Chunk Type value, so 0x10 of the file, without the DEMO chunk header. - 0x4 - 0x7 (int) - Offset to the Event section. If this value is empty or bigger than the chunk size (referring to the next DEMO chunk in the .fsm?), the file will not have events. ###### Motion Section This section only exists in 0 type DEMO chunk types. ###### Segment Offsets - 0x0 - 0x3 (int) - An offset to the segment start from the Segment Motion Data section. These are counted by the Motion Segment Count from the Demo Data section. ###### Root Vector This is the root Vector3 of the DEMO chunk, using decimal-less coordinates. This only exists if the Demo Data section's 0 DEMO chunk type 0's first unknown isn't 0x0A. - 0x0 - 0x3 (float) - X translation - 0x4 - 0x7 (float) - Y translation - 0x8 - 0xC (float) - Z translation ###### Motion Segment Type Indices The use of these is not exactly known, but they might relate to the sizes or data types of the Motion Data section. - 0x0 - 0x1 (short) - A short of usually small size, if not just empty, per Motion Segment Count from the Demo Data section. ###### Motion Data Section This is just a big list of shorts that most likely keep the motion data compressed to shorts. They don't seem like half floats. - 0x0 - 0x1 (short) - A short of wildly differing sizes. These shorts continue either til the Event Section starts, or if the Event Section doesn't exist, til the end of the file. Sometimes there's extra empty space before the Event Section starts, never longer than 0xF, so it's possible something in the file measures the Segments of the Motion Data here, possibly the Motion Segment Type indices. ###### Event Section Events contain data on certain kinds of operations in the DEMO chunk aside from just motion. Examples include managing lights, effects (creating them with parameters, but still having to use a motion section object as a root), messages interceptable by Lua, mesh visibility on objects, etc. What all of them are exactly isn't known yet, but a general way of parsing them without reading much into their contents seems to be consistent. The Event Section is only present if the DEMO Chunk Type is 2, or if the DEMO Chunk Type is 1 and the Offset to Event Section is bigger than 0 and less than the DEMO chunk size in the Demo Data Section. If the DEMO Chunk Type is 2, it will start at 0x2C, which will also offset the "start at the next line" padding size of the events themselves, starting it at the 0xC of the current line. ###### Event Offsets - 0x0 - 0x3 (int) - A StrCode32 hash of "Normal" - 0x4 - 0x5 (short) - Event count - 0x6 - 0x7 (short) - Usually empty, but there could possibly be cases where it could be another count - 0x8 - 0xC (int) - Offset to event start, starting from the Demo Data Section. Repeated by the Event Count The events themselves start at the start of the next 0x10-long line, but if the DEMO chunk type in the Demo Data Section is 2, you'll have to start parsing events 4 bytes before the start of the next line, since the Event Offsets start 4 bytes before the start of the next line too, so at 0xC of the current line. ###### Event Data Events include the event type name hash and the event's parameters. Their function is not yet known, but this should parse them. Very similar data is stored in some .evf DataSets. - 0x0 - 0x3 (int) - Event type hash. 595181585 is common, and it's a StrCode32 hash of "ExecCommand" - 0x4 - (byte enum) - Time Section count - 0x5 - (byte enum) - Param Int count - 0x6 - (byte enum) - Param Float count - 0x7 - (byte enum) - Param String Hash count ###### Time Section - 0x0 - 0x3 - (int) The frame when the event starts - 0x4 - 0x7 - (int) The frame when the event ends (could be split into two shorts, as some FF FF + some hex entries exist) ###### Param Int - 0x0 - 0x3 - (int) Some parameter ###### Param Float - 0x0 - 0x3 - (float) Some parameter ###### Param String - 0x0 - 0x3 - (uint) Param String hash. These could vary a lot, and it still has to be identified what they are - 0x4 - 0x7 - (int) Unknown The event should end after filling in the rest of the 0xF line with padding. ##### Additional Notes - The first SND chunk is always 0x200020 bytes. All following SND chunks are 0x200010 bytes. ### `wiki:wiki/FV2.md` The FV2, or Form Variation (also sometimes called fova), is a format used to make in-game changes to models in Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain. Some of the functionality available to fv2 files is the ability to change a model's textures, show and hide a model's meshes, and attach two or more models together. The complete functionality available to fv2 files is unknown. The format is Little-Endian, meaning bytes are written in reverse order of significance. You can use [FvTwool](/FvTwool) to edit files using gui. ##### Format ###### Header ``` 0x0 - 0x7 (string): "FOV2win.". 0x8 - 0x9 (uint16): Variable data section offset. 0xA - 0xB (uint16): External file section offset. 0xC - 0XD (uint16): Number of variable data section entries. 0xE - 0xF (uint16): Number of external file section entries. 0x10 - 0x13 (uint32): Length of static data section and variable data section combined. 0x14 - 0x17: Padding. 0x18 - 0x19 (uint16): Number of textures used. 0x1A - 0x1F: Padding. 0x20 (uint8): Number of mesh groups to hide. 0x21 (uint8): Number of mesh groups to show. 0x22 (uint8): Number of material instance references. 0x23 (uint8): Unknown. 0x24 (uint8): Number of models to attach by bones. 0x25 (uint8): Number of models to attach by connection point. 0x26 - 0x27 (uint16): Unknown. Possibly padding. ``` ###### Static Data Section The static data section of .fv2 files begins at 0x28. The data listed in this section can vary greatly. Most of the data contained in the section is made up of StrCode32 hashes (StrCode64 hashes that have had their first four bytes truncated). The hashes are references to data from the model they are changing. Entries in the static data section are guaranteed to execute as opposed to the variable data section, where execution is conditional. The static data section also has priority over the variable data section, meaning that if an entry appears in both sections, the entry in the variable data section will be ignored. Different types of entries have priority for appearing in the list. The priority of entries takes the following order. 1. Hide mesh group entries. 2. Show mesh group entries. 3. Texture swap entries. 4. Attach model by bones entries. 5. Attach model by connection point entries. ###### Hiding/Showing Mesh Groups ![Example of how showing/hiding meshes works in form variation files.](/assets/Hide-show-mesh-group-entries.png){:.thumb .legacy-small width="220px"} Hiding and showing mesh groups requires a single parameter: the hash of the mesh group to show or hide. `0x0 - 0x3 (uint32): Hash (StrCode32) of mesh group to hide or show.` The fv2 will hide the number of mesh groups listed at 0x20 starting at the first entry. It will show the number of mesh groups list at 0x21 starting at the entry after the last mesh group to be hidden. ###### Swapping Textures ![Example of how swapping textures works in form variation files.](/assets/Swap-texture-entries.png){:.thumb .legacy-small width="220px"} Swapping textures requires four parameters: the hash of the material instance the texture is applied to, the hash of the texture type for the texture which is being swapped, the index of the texture in the external file list, and a uint16 with a value of 0xFFFF (purpose is unknown). ``` 0x0 - 0x3 (uint32): Material instance hash (StrCode32). 0x4 - 0x7 (uint32): Texture type hash (StrCode32). 0x8 - 0x9 (uint16): External file index. 0xA - 0xB (uint16): Unknown. Always 0xFFFF. ``` If the fv2 is swapping the textures of multiple material instances, the values will not appear in the order above. The fv2 will list all of the material instance hashes, then all of the texture type hashes, then all of the external file indices, then all of the unknown 0xFFFF entries. ###### Attaching Models by Bones ![Example of how attaching models by bones works in form variation files.](/assets/Attach-model-by-bones-entries.png){:.thumb .legacy-small width="220px"} Fv2s can attach two or more models together by matching bones that exist in both models. This will allow the attached model to deform to the target model's bone movements. Attaching models by bones requires six parameters: the index of the model in the external file section, and five optional indices into the external file section for additional files used by the attached model. If the optional parameters aren't used, a value of 0xFFFF (-1) is given to the parameter. ``` 0x0 - 0x1 (uint16): External file index. 0x2 - 0x3 (int16): External file index for frdv file. 0xFFFF if file is not used. 0x4 - 0x5 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x6 - 0x7 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x8 - 0x9 (int16): External file index for sim file. 0xFFFF if file is not used. 0xA - 0xB (int16): External file index for unknown file. 0xFFFF if file is not used. ``` ###### Attaching Models by Connection Point ![Example of how attaching models by connection point works in form variation files.](/assets/Attach-model-by-connection-point-entries.png){:.thumb .legacy-small width="220px"} Fv2s can also attach two or more models together by using a target model's connection points. Attaching models this way will prevent them from deforming when the target model's bones move. This also allows models without bones to be attached to a target model. Attaching models by connection point requires eight parameters: the hash of the connection point it is being attached to, the hash for "" (an empty string), the index of the model in the external file section, and five optional indices into the external file section for additional files used by the attached model. ``` 0x0 - 0x3 (uint32): Connection point hash (StrCode32). 0x4 - 0x7 (uint32): "" (empty string) hash (StrCode32). 0x8 - 0x9 (uint16): External file index. 0xA - 0xB (int16): External file index for frdv file. 0xFFFF if file is not used. 0xC - 0xD (int16): External file index for unknown file. 0xFFFF if file is not used. 0xE - 0xF (int16): External file index for unknown file. 0xFFFF if file is not used. 0x10 - 0x11 (int16): External file index for sim file. 0xFFFF if file is not used. 0x12 - 0x13 (int16): External file index for unknown file. 0xFFFF if file is not used. ``` ###### Variable Data Section The variable data section works very similarly to the static data section with the difference that all data in the variable data section is conditional. This allows an fv2 to do things such as show and hide meshes based on random number generation, apply a skin colour texture based on the currently selected character, and apply an eye colour texture based on the currently selected character. Unlike the static data section, types of entries can appear in any order as specified by the fv2. ###### Entry Definition ``` 0x0 (uint8): Type Enum. 0x1 (uint8): Unknown. Note: Changing this doesn't seem to have any effect. 0x2 (uint8): Number of sub-entries. 0x3 (uint8): Number of mesh groups per sub-entry. 0x4 (uint8): Number of material instances per sub-entry. 0x5 (uint8): Unknown. 0x6 (uint8): Number of model attachments by bones per sub-entry. 0x7 (uint8): Number of model attachments by connection point per sub-entry. 0x8 - 0xB (uint32): Unknown. Possibly padding. 0xC - 0xF (uint32): Offset. ``` ###### Type Enums The following is a list of known type enums and what they appear to be used for. It should be noted that other than the known special usage cases, it does not appear to matter if the correct enum is used. ``` 0x1: Body meshes. 0x2: Hand meshes. 0x3: Leg meshes. 0x4: Pants meshes. 0x6: Multiple observed uses. Waist and belt meshes on pfs, top color on svs. 0x7: Multiple observed uses. Bottom color on svs. 0x8: Rubber gloves on the XOF soldier model. Holsters and other hip equipment. 0x9: Stun grenade on the XOF soldier model. 0xA: Multiple observed uses. 0xB: Medal on pfs. Goggles on ddr. 0xC: Short sleeve shirt textures on pfs, PF_A. 0xD: Short sleeve shirt textures on pfs, PF_B. 0xE: Pants textures on pfs. 0xF: Body equipment textures on pfs. 0x10: Long sleeve PF_C shirt textures on pfs. 0x11: Boots textures on pfs. 0x12: Leather jacket textures on pfs. 0x64*: Skin colour texture. 0x6E*: Eye colour texture. 0xC8*: Hats and berets on pfs and svs. 0xC9*: Headset on the XOF soldier model. Helmets on pfs, svs and chd. 0xCA*: Night vision goggle meshes on pfs and svs. 0xCB*: Gas masks on pfs and svs. 0xCD: Throat parasites on ddr. 0xD2*: Chest equipment on pfs and svs. 0xD3*: Soft armor on pfs and svs. ``` \* indicates that the enum is a special usage case. ###### Special Usage Cases Special usage cases get their data from the currently selected character rather than at random. **Skin Colour:** Entries contain five sub-entries starting at the lightest skin tone and ending with the darkest skin tone. They sometimes also include the parasite zombie skin texture at the very end. **Eye Colour:** Entries Contain five sub-entries for males and four sub-entries for females. The entries for both males and females follow the same order and use the same textures with the exception that females don't use the last texture used by males. The order is: 1. cm_iris0_c00_bsm (blue), 2. cm_iris2_c00_bsm (amber), 3. cm_iris7_c00_bsm (white). 4. cm_iris3_c00_bsm (grey), 5. cm_iris5_c00_bsm (green), **Hats and Berets:** Meshes that should not conflict with other headwear. **Helmets:** Meshes that should not conflict with other headwear. Also related to the HELMET power setting. **Night Vision Goggles:** Meshes that should not conflict with other headwear. Related to the NVG power setting. **Gas Masks:** Meshes that should not conflict with other headwear. Related to the GAS_MASK power setting. **Chest Equipment:** Meshes that should not conflict with Soft Armor. **Soft Armor:** Meshes that should not conflict with Chest Equipment. Related to the SOFT_ARMOR power setting. ###### Showing/Hiding Mesh Groups If an entry contains at least two sub-entries and each sub-entry contains at least one mesh group, one of the sub-entries will be shown randomly while the others are hidden. `0x0 - 0x3 (uint32): Mesh group hash (StrCode32).` Entries with more than one mesh group per sub-entry will contain extra, optional mesh group hashes. The following is an example of an entry with two mesh groups per sub-entry. ``` 0x0 - 0x3 (uint32): Mesh group hash (StrCode32). 0x4 - 0x7 (uint32): Optional mesh group hash (StrCode32). (0x0 if not used.) ``` ###### Swapping Textures If an entry contains at least two sub-entries and each sub-entry contains at least one material instance, one of the sub-entries will have its texture applied to the specified material instance randomly while the others are ignored. ``` 0x0 - 0x3 (uint32): Material instance name hash (StrCode32). 0x4 - 0x7 (uint32): Texture type hash (StrCode32). 0x8 - 0x9 (uint16): External file section index. 0xA - 0xB (uint16): Unknown. Always 0xFFFF. ``` Entries with more than one material instance per entry will contain extra, optional parameters. The following is an example of an entry with two material instances per sub-entry. ``` 0x0 - 0x3 (uint32): Material instance name hash (StrCode32). 0x4 - 0x7 (uint32): Optional material instance name hash (StrCode32). (0x0 if not present.) 0x8 - 0xB (uint32): Texture type hash (StrCode32). 0xC - 0xF (uint32): Optional texture type hash (StrCode32). (0x0 if not present.) 0x10 - 0x11 (uint16): External file section index. 0x12 - 0x13 (uint16): Optional external file section index. (0xFFFF if not present.) 0x14 - 0x15 (uint16): Unknown. (0xFFFF.) 0x16 - 0x17 (uint16): Unknown. (0xFFFF.) ``` ###### Attaching Models by Bones If an entry contains at least two sub-entries and each sub-entry contains at least one model attachment by bones, one of the sub-entries will have its model attached randomly while the others are ignored. ``` 0x0 - 0x1 (uint16): External file index. 0x2 - 0x3 (int16): External file index for frdv file. 0xFFFF if file is not used. 0x4 - 0x5 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x6 - 0x7 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x8 - 0x9 (int16): External file index for sim file. 0xFFFF if file is not used. 0xA - 0xB (int16): External file index for unknown file. 0xFFFF if file is not used. ``` While there are no known variable data section entries that contain even a single model attachment by bones per sub-entry, it is likely that the following pattern can be used for an entry with two model attachments by bones per sub-entry. ``` 0x0 - 0x1 (uint16): External file index. 0x2 - 0x3 (int16): External file index for frdv file. 0xFFFF if file is not used. 0x4 - 0x5 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x6 - 0x7 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x8 - 0x9 (int16): External file index for sim file. 0xFFFF if file is not used. 0xA - 0xB (int16): External file index for unknown file. 0xFFFF if file is not used. 0xC - 0xD (uint16): Optional external file index. 0xFFFF if file is not used. 0xE - 0xF (int16): External file index for frdv file. 0xFFFF if file is not used. 0x10 - 0x11 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x12 - 0x13 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x14 - 0x15 (int16): External file index for sim file. 0xFFFF if file is not used. 0x16 - 0x17 (int16): External file index for unknown file. 0xFFFF if file is not used. ``` ###### Attaching Models by Connection Point If an entry contains at least two sub-entries and each sub-entry contains at least one model attachment by connection point, one of the sub-entries will have its model attached randomly while the others are ignored. ``` 0x0 - 0x3 (uint32): Connection point hash (StrCode32). 0x4 - 0x7 (uint32): "" (empty string) hash (StrCode32). 0x8 - 0x9 (uint16): External file index. 0xA - 0xB (int16): External file index for frdv file. 0xFFFF if file is not used. 0xC - 0xD (int16): External file index for unknown file. 0xFFFF if file is not used. 0xE - 0xF (int16): External file index for unknown file. 0xFFFF if file is not used. 0x10 - 0x11 (int16): External file index for sim file. 0xFFFF if file is not used. 0x12 - 0x13 (int16): External file index for unknown file. 0xFFFF if file is not used. ``` While there are no known variable data section entries that contain more than one model attachment per sub-entry, it is likely that the following pattern can be used for an entry with two model attachments by connection point per sub-entry. ``` 0x0 - 0x3 (uint32): Connection point hash (StrCode32). 0x4 - 0x7 (uint32): "" (empty string) hash (StrCode32). 0x8 - 0x9 (uint16): External file index. 0xA - 0xB (int16): External file index for frdv file. 0xFFFF if file is not used. 0xC - 0xD (int16): External file index for unknown file. 0xFFFF if file is not used. 0xE - 0xF (int16): External file index for unknown file. 0xFFFF if file is not used. 0x10 - 0x11 (int16): External file index for sim file. 0xFFFF if file is not used. 0x12 - 0x13 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x14 - 0x17 (uint32): Connection point hash (StrCode32). 0x18 - 0x1B (uint32): "" (empty string) hash (StrCode32). 0x1C - 0x1D (uint16): Optional external file index. 0xFFFF if file is not used. 0x1E - 0x1F (int16): External file index for frdv file. 0xFFFF if file is not used. 0x20 - 0x21 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x22 - 0x23 (int16): External file index for unknown file. 0xFFFF if file is not used. 0x24 - 0x25 (int16): External file index for sim file. 0xFFFF if file is not used. 0x26 - 0x27 (int16): External file index for unknown file. 0xFFFF if file is not used ``` ###### External File Section This section contains a list of hashes (PathCode64) for external files used by the fv2. This list can include fmdl files, frdv files, ftex files, and sim files. This allows the fv2 to attach models together, change the texture that's applied to the model, and apply physics simulations to the model. `0x0 - 0x7 (uint64): File hash (PathCode64).` ##### Ground Zeroes .FOVA .FOVA, or Form Variation, is a format used to make in-game changes to models in Metal Gear Solid V: Ground Zeroes. The known functionality available to it is the ability to change a model's textures and show and hide a model's meshes via mesh groups. It is a predecessor to .FV2, and shares similar functionalities with it. The complete functionality of .FOVA is also unknown. The format is Little-Endian, meaning bytes are written in reverse order of significance. ###### Header ``` 0x00-0x06 - String "FOVAwin" (PS3 is "FOVAps3") 0x07 - Version 0x08-0x0b - Offset to Entry Definitions (so always 0x14) 0x0c-Ox0d - Entry count 0x10-0x13 - Unknown, always 0x07 ``` ###### Entry Definition Entries may contain only texture swaps, only mesh showing or hiding, or even both. ``` 0x00 - Type enum. 0x01 - Visibility enum. 0x02 - Amount of meshes to hide or show. 0x03 - Amount of texture swaps. ``` Entries are sorted by ascension of the type enum. ###### Sub-Entry Definitions Mesh group, an sub-entry per mesh count. `0x00-0x03 - StrCode32 hash of the mesh group.` Texture swaps, a sub-entry per texture swap count. ``` 0x00-0x03 - Material instance name StrCode32 hash. 0x04-0x07 - Texture type StrCode32 hash. 0x08 - The .ftex texture path begins. Unknown. ``` Mesh groups are always listed before texture swaps in the sub-entries, if the entry requires sub-entries for both types of sub-entries. If the amount of meshes to hide or show is 0x00, no mesh group hashes will be listed in the sub-entry. If there are more than one, they will be listed one after the other. The same applies to texture swaps, and with every swap, the material instance, texture type and, of course, the .ftex texture path hashes are listed again as well. If Visibility enum in the entry is 0x00, the .FOVA will hide the mesh groups in its sub-entries, 0x01 - show and apply the texture swaps in the sub-entries, 0x02 - it will apply only the sub-entries in this entry and not the other entries in the same Type enum, and 0x03 - it will apply its sub-entries at complete random, regardless of entries with the same Type enum. ###### Hashed Texture Path ``` 0x00 - Length of the texture path, including this byte and the last null. 0x01 - 0x04 - string - "/as/" 0x05 - Always 0x07, unknown 0x06 - 0x0E - Unknown (Hash?) 0x0F - 0x10 - Always 0x510B 0x11 - 0x19 - Unknown (Hash?) 0x1A - 0x1C - Always 0x0B0B0B 0x1D - length varies - Unknown (Hash?) Last 6 bytes: string - ".ftex" and one null ``` It is unknown how exactly .FOVA stores texture paths, but it does start with a byte representing the length of the hash and a four-byte string "/as/", and ends with the string ".ftex" and a null byte. The third unknown hash changes length depending on the length of the texture path it's supposed to represent. The reason is unknown. All three hashes completely change even if one symbol in the unhashed texture path changes. The length of the third part of the hash varies depending on the length of the path and file name, being as long as the file name, plus four bytes. In Big Endian PS3 files, texture paths here are not hashed and are presented as the real texture paths: ``` 0x00 - Length of the texture path, including this byte and the last null. Texture path. One null byte. ``` ### `wiki:wiki/FfntTool.md` FfntTool is part of Atvaark's FoxEngine.TranslationTool collection of tools for modifying Lang files. FfntTool allows you to modify FFNT font files by exporting the glyphs to PNG files and creating a corresponding control XML to edit font attributes. ### `wiki:wiki/File_Formats.md` This article lists the presumed names of extensions used in MGSV, as well as some basic descriptions. The full list of up-to-date templates can be found [here](https://github.com/kapuragu/FoxEngineTemplates). {:.small} > **Tip:** tables can be more comfortably viewed on widescreen monitors by pressing the *Expand Page Width* button at the top of the page. | Extension | Full Name | Location(count)[^count-explained] | Tool | Description | |---|---|---|---|---| | adm | fpk(5258), gz fpk(1) | Mentioned in exe in with other extensions: vpc,twss,tmss,adm,tetl,tmsl, tlsp,tmsu,tmsf,twpf,cani. Related to ambient sound somehow. | | | | atsh | Atmosphere Spherical Harmonics | fpk(1), gz fpk(9) | Defines ambient sky lighting, or more specifically, it defines the bounce lighting from the sky. reference in: resident_common_sky.fox2 | | | bnk | [Wwise SoundBank](https://www.audiokinetic.com/library/edge/?source=WwiseFundamentalApproach&id=understanding_soundbanks_understanding_soundbanks) | data1(1), sbp(214) | [Ravioli Game Tools](https://github.com/themeldingwars/Documentation/wiki/Ravioli-Game-Tools) | [Soundswapping](https://bobdoleowndu.github.io/mgsv/documentation/soundswapping.html) for sound swaps, and to replace sounds with new ones, use this tool instead: [Sound Replacement Tool](https://www.nexusmods.com/metalgearsolidvtpp/mods/826) | | bnd | Bounder (fox2) | fpkd(19) gz fpkd(30) | [FoxTool](/FoxTool) | NavxSquareGraphBounderData , on vehicles. Only used in GZ. | | caar | Camera Animation Archive | fpk(9) | Contains .cani? Likely similar to mtar for camera animations. | | | cani | Camera Animation | gz fpk(92) | Likely similar to .gani for camera animations. | | | chnk | mtar(251) | A chunk of data with an unknown purpose belonging to an Mtar Type 2 file. Extension named by MtarTool author | | | | clo | Cloth Configuration File (fox2) | fpkd(25) | [FoxTool](/FoxTool) | SimClothSettingData | | dat | QAR Archive | master | [QAR Tool](https://web.archive.org/web/20230516145600/https://forum.xentax.com/viewtopic.php?t=12407&start=1440#p124477), [GzsTool](/GzsTool) | Main file archives Quark Archive? | | dat | fox file system data XML | Chunk0(1), \0\00(1) | Any text editor | Plain XML with extension .dat. In the root of some Qar files. | | [dat](/WMV) | WMV | master | Video | | | des | Destruction data (fox2) | fpkd(32) | [FoxTool](/FoxTool) | Destruction data set file. | | [dfrm](/DFRM) | Deformation | fpk(16) | Deformation data related to avatar customization. | | | ends | EndingSettingsFile | fpk(21), gz fpk(6) | UiGraphEntry rawfiles, ending settings. ending_nuke.fox2,ending_okb.fox2... | | | enchnk | mtar(6099) | A chunk of animation at the bottom of an Mtar Type 2 file. Tied to a .gani file. Should be brought along with a swapped .gani file. Extension named by MtarTool author. | | | | evf | EvfFile (fox2) | fpkd(1), gz fpkd(45) | [FoxTool](/FoxTool) | Event data p51_010300_000_snd_000.evf sole example for some demo. lots of prefixes in exe .ag.evf,.cc.evf,.fx.evf,.sd.evf,.vo.evf | | exchnk | mtar(4748) | An extra chunk of animation tied to a .gani file from an Mtar Type 2 file. If the .gani file is swapped this should be brought along with it. Extension named by MtarTool author. | | | | [fclo](/FCLO) | fpk(49) | Variant/relation of cloth settings? mentioned in exe in section along with .sim,.clo | | | | [fcnp](/FCNP) | ConnectPointFile | fpk(1785) | [FcnpTool](https://github.com/BobDoleOwndU/FcnpTool) | Defines positions on a model where meshes and effects can be attached. | | fdes | FoxDestruction | fpk(44) | Solid body data file (Binary destruction settings. Relation to.des) | | | ffnt | Fox Font | data1(6) | FfntTool | | | [fmdl](/FMDL) | FmdlFile | fpk(14384) | [Fmdl Studio v2](https://github.com/BobDoleOwndU/FMDL-Studio-v2) | Model, includes mesh, bone, and material data. | | [fmtt](https://mgsvmoddingwiki.github.io/FMTT) | Material parameters | data1(2) | [FoxKit](https://github.com/youarebritish/FoxKit/) | GrTools.SetMaterialParamBinary | | fnt | Font | fpk(7) | UiFontDataElement entity, fontFile common_art.fox2,*_art.fox2 In exe section with uil,uif,uia,fnt,utxl | | | [fox2](/FOX2) | DataSetFile2 | fpkd(75167), gz fpkd(450) | [FoxTool](/FoxTool) | Translated comment in pc init.lua 'Object arrangement / property data file' | | fpk | Fox Package / fox::PackFile | Chunks(16637) | [FPK Tool](https://web.archive.org/web/20230517070053/https://forum.xentax.com/viewtopic.php?t=12407&start=690#p110644), [GzsTool](/GzsTool) | Usually contains compiled files that have no associated editing tools. Must have a matching fpkd (which may be empty) | | fpkd | Fox Package Data | Chunks(16637) | [FPK Tool](https://web.archive.org/web/20230517070053/https://forum.xentax.com/viewtopic.php?t=12407&start=690#p110644), [GzsTool](/GzsTool) | Archive that allows changes to physics or sound associations; data archive. Must have a matching fpk (which may be empty) | | fpkl | Fox Package Link | fpk(1), gz fpk(3) | Any text editor | Only one instance in chunk0 col_common_tpp.fpk Seems to define required files to load. | | frdv | HelpBoneFile | fpk(664) | Related to helper bone rotations. | | | [frig](/FRIG) | RigFile | fpk(233) gz fpk(1) | [FoxLib](https://github.com/youarebritish/FoxLib) | Defines bone groups for IK and animations. | | frl | RailFile | fpk(496) | Similar to routes, used for vehicle travel plans and long-range reconnaissance patrols (LRRP). | | | frld | RailUniqueIdFile | fpkd(496) | Defines hashed IDs for rails in .frl files. | | | [frt](/FRT) | TppRouteSet | fpk(476) | [FoxKit](https://github.com/youarebritish/FoxKit/) | Defines AI navigation route and events. | | fsd | Facial Setting Data | fpkd(212) | [FoxTool](/FoxTool) | | | [fsm](/FSM) | Fox Stream Movie | Chunks(235), fpk(1) | [FsmTool](https://github.com/BobDoleOwndU/FsmTool) (currently only extracts sounds) | Demo / Cutscene raw animation tracks and events. | | fsop | Fox Shader Object(?) Pack | data1(4) | Shader source code in HLSL format. | | | fstb | StageBlockFile | fpk(3) | Specifies fpks to load in a level and which small block indices they correspond to. | | | ftdp | FoxTerrainDecalPackFile | fpk(732) | Defines decals used by the terrain. | | | [ftex](/FTEXS) | Fox Texture | Textures, pftxs(88957), fpk(2) | [FtexTool](/FtexTool) | | | [ftexs](/FTEXS) | Fox Sub-texture | Textures, pftxs(89005) | [FtexTool](/FtexTool) | Includes .1.ftexs,....6.ftexs | | [fv2](/FV2) | FormVariationFile2 | fpk(2280) | [FvTwool](https://github.com/BobDoleOwndU/FvTwool) | Defines an appearance variation, including texture swaps and attachable meshes. | | [gani](/GANI) | AnimFile | mtar(7933), gz fpk(260) | Generic animation file (in-game characters, environment, etc.) | | | geobv | GeoBoundingVolumeFile | fpk(26) | Level collision grid set | | | geom | GeoGeomFile | fpk(9818) | Generic collision data. Includes definition of fulton ceilings. | | | geoms | GeoxGeomSetFile | fpk(3464) | Level collision data. .geom but not specific to a model. | | | gpfp | GeoPathFixedPackFile | fpk(2270) | Player obstacle traversal arrays (climbing, jumping, taking cover, etc.) | | | [grxla](/GRXLA) | LightArrayFile, TppLightProbeArray | fpk(8880) | [GrxArrayTool](https://github.com/kapuragu/GrxArrayTool) | Binary light array. They can contain either an array of light probes, or arrays of Point Lights and/or Spot Lights. | | [grxoc](/GRXLA) | OccluderArrayFile | fpk(95) | [GrxArrayTool](https://github.com/kapuragu/GrxArrayTool) | Binary occluder array file. Technically a .grxla file with occluder entries. | | gskl | GeoGsklFile | fpk(394) | Rigged skeletal collision (for mechs) | | | htre | TerrainTileFile | fpk(8305) | [FoxKit](https://github.com/youarebritish/FoxKit/) | Terrain tile data, including heightmap, material select map, and material ID map. | | json | json | data1(1), data_02.g0s(38) | Any text editor | | | lad | Lip Adjust Data (fox2) | gz fpkd(12) | [FoxTool](/FoxTool) | In-game dialogue lip sync sound definition data. | | ladb | LadbFile | fpk(241) | Binary version of .lad | | | las | gz fpk(1) | [FoxTool](/FoxTool) | Seems to be alias for .fox2 Other references to .las files are via entityLinks in same manner as fox2 And references to .las seem to be to equivalent named .fox2 The single GZ .las is just a .fox file. | | | [lba](/LBA) | Locator Binary Array | fpk(14622), gz fpk(4) | [FoxLib](https://github.com/youarebritish/FoxLib) | Location data used to place gimmicks. | | [lng](/Lang_Files) | LangFile | fpkd(64) | [LangTool](https://mgsvmoddingwiki.github.io/LangTool)
[datfpk](https://github.com/unknown321/datfpk) | Localized text.
TPP includes language prefix (ex `.eng.lng`), GZ suffix (`.lng#eng`)
(GZ uses `deu` instead of `ger`)| | [lng2](/Lang_Files) | LangFile2 | fpk(240) | [LangTool](https://mgsvmoddingwiki.github.io/LangTool)
[datfpk](https://github.com/unknown321/datfpk) | See lng table entry. | | lpsh | Light Probe Spherical Harmonics | fpk(8245) | Ambient light data encoded into second-order spherical harmonics. | | | ls | Lip Sync | .sab, .stp | Lip sync track file. In the .sab for embedded sounds, in the .stp for streamed sounds in TPP, only in the .sab in GZ for all sounds. The .sab version is slightly different. | | | [lua](/Lua) | Lua | data1(120), fpkd(1081) | Any text editor | Open source scripting language used by the game. For more info check the [Lua documentation page](https://www.lua.org/docs.html). | | mbl | Mother Base Layout | fpk(47) | Layout of the UI iDroid map of Mother Base. | | | mog | MotionGraphFile | fpk(184) | Motion graph Handles animation states and blending | | | [mtar](/MTAR) | Motion Archive | fpk(910), gz fpk(18) | [MtarTool](https://mgsvmoddingwiki.github.io/MtarTool) | Contains .gani,.chnk,.enchnk,.exchnk,.trk (All extensions except for .gani named by MtarTool author). | | mtard | Motion Archive Data? | fpk(16) | | | | [nav2](/NAV2) | NavNavigationFile | fpk(1634) | [Nav2Parser](https://github.com/BobDoleOwndU/Nav2Parser) | NavxNavBlock entity, filePath .1.nav2 (exe) | | [nta](/NTA) | NavTacticalAction | fpk(163) | Navigation related. Indicates points and actions of traversal, such as ladders and steps. Used by NPCs. In exe section with classes or entities with Navigation in name. | | | [obr](/OBR) | Object Brush | fpk(18) | Positions for grass, shrubs, pebbles, and other miscellaneous terrain decorations. | | | [obrb](/OBRB) | Object Brush Block | fpk(8192) | Positions for grass, shrubs, pebbles, and other miscellaneous terrain tile decorations. | | | parts | Model Description data (fox2) | fpkd(3784) | [FoxTool](/FoxTool) | Character, gimmick, mecha, item etc. model and additional file assembler | | pcsp | PrecomputeSkyFile | fpk(1) | [FoxKit](https://github.com/youarebritish/FoxKit/) | Related to TppAtmosphere entity, reference in: resident_common_sky.fox2 Contains look-up table of precomputed atmospheric scattering coefficients. | | [pftxs](/PFTXS) | Packed Fox Textures | Chunks(3068) | [GzsTool](/GzsTool) | Contains .ftex,ftexs Must match an fpk (but not all fpks have pftxs) | | ph | Physics | fpkd(609) | [FoxTool](/FoxTool) | Physics hitbox definition data. | | phsd | Physics Sound Data | fpkd(591) | [FoxTool](/FoxTool) | Physics sound definition data. | | [rdf](/RDF) | Radio Data File | fpk(199) | [RdfTool](https://github.com/kapuragu/RdfTool) | Defines real-time support radio dialogue data. ("Subject onboard") | | sab | Sound Additional Binaries? | sbp(39) | [StpTool](https://github.com/kapuragu/StpTool) | In GZ, has .st (subtitle id string) and .ls (lip sync) files for both embedded and streamed voice clips. In TPP. has .ls files for embedded voice clips only. | | sand | SandFile | fpk(223) | Stream animation node data. Assigns tracks from .fsm Fox Stream Movie to bones and objects in a node tree. | | | sani | Stream Animation | fpk(1), data_02.g0s(4) gz fpk(38) | [FsmTool](https://github.com/BobDoleOwndU/FsmTool) (currently only divides into chunks) | GZ includes .sani#eng,.sani#jpn .fsm-alias, in GZ used for subtitle timing. | | sbp | Sound Bank Package | Chunks(212) | [GzsTool](/GzsTool) | Contains .bnk,.sab,.stp | | sdf | SoundDataFile (fox2) | fpkd(484) | [FoxTool](/FoxTool) | DataSet that loads .sbp soundbanks. | | sim | SimBinaryFile | fpkd(493) | [FoxTool](/FoxTool) | Simulation physics data | | [spch](/SPCH) | TppSpeechFile | fpk(46) | [SpchTool](https://github.com/kapuragu/SpchTool) | Defines in-game world scriptable gameobject dialogue. (Enemy conversations, prisoner monolgues, etc.) | | st | SubTitle | .sab(GZ only) | Contains the subtitle id string for the sound file with the embedded string that matches the hash of the .st file name. | | | stp | Streamed Package | sbp(187) | [StpTool](https://github.com/kapuragu/StpTool) | Contains the streamed audio files for the soundbank. In TPP, .wem sound files are also paired with newer versions of .ls files from .sab. | | subp | SubtitlesPackageFile | data1(489), fpk(89) | [SubpTool](https://mgsvmoddingwiki.github.io/SubpTool) | Defines subtitle data. | | tcvp | CoverPointFile | fpk(232) | [TcvpTool](https://github.com/kapuragu/TcvpTool) | TppCoverPointFileTransform entity on MB, defines positions of cover points. DataSet equivalent entity is TppCoverPoint. | | tgt | Target | fpkd(2151) | [FoxTool](/FoxTool) | Defines hitboxes for characters and props .parts. | | [trap](/TRAP) | GeoTrapFile | fpk(617) | [TrapTool](https://github.com/kapuragu/TrapTool) | Level trigger definition file. Includes camera modes, death zones and mission area boundaries. | | tre2 | TerrainFile | fpk(3) | Low-resolution LOD data for a level's terrain. | | | trk | Animation Track | mtar(251) | Description of all main animation tracks for an Mtar Type 2 file. Extension named by MtarTool author | | | twpf | ParametersFile | fpk(5) | TppLocationData entity, weatherParametersFile | | | uia | UiAnimFile | fpk(3755), gz fpk(1813) | UI model asset image transition data? | | | uif | UiFile | fpk(1979) gzfpk(600) | UI model asset base image? | | | [uigb](/UIGB) | UiGraphFile | fpk(289) | UI graph asset? | | | [uilb](/UILB) | UiLayoutFile | fpk(1904) | Based on vehicle .fox2 DataSet entries.[^uilb-source] | | | veh | Vehicle | fpkd(87) | [FoxTool](/FoxTool) | | | [vfx](/VFX) | FxVfxFile | fpkd(6378) | [VfxTool](https://github.com/youarebritish/VfxTool) | Visual effect graph. | | [vfxlb](/VFXLB) | fpkd(133) | FxLocatorArrayData entity, vfxlbFile lba for vfx? | | | | vfxlf | VFX Lens Flare (fox2) | fpkd(846) | | | | wem | Wwise Encoded Media | Chunks(255) | | | ##### Unique to GZ? | Extension | Full Name | Location(count) | Tool | Description | |---|---|---|---|---| | fagx | Motion graph / layer definition file (fox) | gz fpks(1) | GZ RegisterPackageExtensionInfo | | | fdmg | (fox) | gz fpkd(2) | GZ only, Damage related | | | [fova](/FV2) | Form Variation | gz fpk(110) | GZ, superceded in TPP by fv2 | | | fox | data_02.g0s(3) | Any text editor | XML, GZ only, superceded in TPP by fox2 | | | [g0s](/WMV) | Qar Archive Gz format | data_01.g0s, data_02.g0s files | [GzsTool 0.2](/GzsTool) | | | g0s | WMV | data_00.g0s file | | | | lani | LaniFile | gz fpk(456) | Lip animation Reference in init.lua RegisterPackageExtensionInfo Reference in .lad files | | | tlsp | gz fpk(2) | GZ | | | | tmsp | gz fpk(2) | GZ | | | | tmsf | gz fpk(1) | GZ | | | | tmsl | gz fpk(1) | GZ | | | | tmsu | gz fpk(1) | GZ | | | | vdp | Vehicle Driving Parameter | gz fpkd(20) | [FoxTool](/FoxTool) | GZ | | vfxdb | gz fpk(30) | GZ, .vfx class database? | | | | vpc | data_02.g0s(3) | GZ | | | | Other[^gz-filetypes] | | | | | | ag | exe ag.evf | | | | | aia | exe | | | | | aib | AI behavior / definition file | Reference in init.lua RegisterPackageExtensionInfo Translated from comment in PT init.lua | | | | aibc | AI behavior category file | Reference in init.lua RegisterPackageExtensionInfo Translated from comment in PT init.lua | | | | aig | exe | | | | | aigc | exe | | | | | aim | exe AimCamera? | | | | | aip | exe | | | | | ait | exe | | | | | cc | exe cc.evf | | | | | col | RegisterExtensionInfo
categories={"Target"} | | | | | csnav | exe | | | | | demo | Editor format? RegisterExtensionInfo
categories={"Target"} | | | | | demox | RegisterExtensionInfo categories={"Target"} | | | | | dnav | exe | | | | | dnav2 | exe | | | | | ese | exe | | | | | evb | RegisterExtensionInfo
categories={"Target"} RegisterPackageExtensionInfo | | | | | fag | RegisterPackageExtensionInfo | | | | | fage | Motion graph / graph piece file | RegisterPackageExtensionInfo Translated from comment in PT init.lua | | | | fago | Motion Chart | RegisterPackageExtensionInfo Translated from comment in PT init.lua | | | | fagp | Motion graph / route graph file | exe Translated from comment in PT init.lua | | | | fcnpx | Parts Builder · Extended Connect Point File | EditableBlockPackage. RegisterPackageExtensionInfo Translated from comment in PT init.lua | | | | fmdlb | RegisterExtensionInfo
categories={"Target"} | | | | | fox_export | exe | | | | | fsml | Reference in init.lua RegisterPackageExtensionInfo | | | | | fx | exe fx.evf | | | | | fxp | Fox Project | Fox Editor | | | | info | RegisterExtensionInfo
categories={"Target"} | | | | | path | exe | | | | | mas | SetLanguageGroupExtention{
group={"Sound"}

RegisterExtensionInfo{
categories={"Target","Language"} | | | | | mtl | exe | | | | | nav | RegisterExtensionInfo
categories={"Target"} | | | | | phep | exe | | | | | qar | exe | | | | | rbs | exe | | | | | rdb | exe | | | | | rnav | exe | | | | | sad | SetLanguageGroupExtention{
group={"Sound"}

RegisterExtensionInfo{
categories={"Language"} | | | | | sd | exe sd.evf | | | | | sh | exe (but no in alphabetical with the others in the section) | | | | | simep | exe | | | | | snav | exe | | | | | stm | SetLanguageGroupExtention{
group={"Sound"}

RegisterExtensionInfo{
categories={"Target","Language"} | | | | | sub | exe | | | | | tetl | RegisterExtensionInfo | | | | | tevt | | | | | | tmss | RegisterExtensionInfo | | | | | trmtl | exe, near TerrainRender | | | | | txt | exe | | | | | uig | UI Graph | EditableBlockPackage. RegisterPackageExtensionInfo | | | | uil | UI Layout | EditableBlockPackage. RegisterPackageExtensionInfo | | | | utxl | exe next to uil,uif,uia,fnt | | | | | vfxbin | exe FxVfxBinaryFile | | | | | vnav | exe | | | | | vo | exe vo.evf | | | | | xml | Extensible Markup Language | Any text editor | This is may appear to not be used anywhere in the game files, but is listed in the .exe and the fox2 files are just compiled XML files.[^foxtool-cite] | | [^count-explained]: Counts for archives like fpks contains duplicates. Counts only include files from \master, not master\0,\1 Counts for formats common to both TPP and GZ only added where ineresting (GZ only formats complete counts) [^uilb-source]: Source: `chunk1.dat/Assets/tpp/pack/vehicle/veh_rl_east_wav.fpkd/Assets/tpp/level_asset/vehicle/veh_rl_east_wav.fox2` ```xml veh_bd_east_wav|sight_vhcl_east_wav|UiGraphEntry0000 0x02D7FC10 /Assets/tpp/ui/LayoutAsset/hud_wpscope/UI_wpscope_vehicle_sav0_b.uilb /Assets/tpp/ui/LayoutAsset/hud_wpscope/UI_vhcl_def_FPS_bs.uilb /Assets/tpp/ui/LayoutAsset/hud_wpscope/UI_wpscope_vehicle_common.uilb ``` [^gz-filetypes]: File types from GZ (to be split further) or referenced in exe or lua but not yet found/extracted as seperate files. [^foxtool-cite]: ### `wiki:wiki/File_Monolith.md` File Monolith is a set of open-source tools which provide support for file management and folder formatting for MGSV:TPP. File Monolith consists of seven separate tools as of v0.5.0.0 which all use WinForms and Microsoft .NET 8 Framework: - Archive Unpacker: The user can select Archive (.dat) files, which the tool will unpack into a target directory. Then, the tool will unpack all .fpk, .fpkd, .pftxs, and .sbp files within the directory. - Mass Texture Converter: The user can select a directory and the tool will attempt to convert all texture files from .ftex(s) to .dds. The resulting .dds files are sent to a target directory. - File Proliferator: The user selects any number of files, of any type. The tool will search for these files in the MGSV file structure. If these filenames are found in the game files, the tool creates a directory structure to mirror MGSV's and then copies the user's files into the structure. - Filename Updater: The user can select any files with hashed filenames, and the tool will attempt to update their names and filepaths using the latest qar_dictionary. Any updated files are copied to the target directory. - Archive Transferrer: The user selects their Ground Zeroes and Phantom Pain executable files, and the tool will attempt to automatically transfer the game archives from Ground Zeroes and Metal Gear Online into The Phantom Pain. - Texture Aggregator: The user can select a Packed Fox Textures (.pftxs) file, and the tool will attempt to automatically complete the textures partially contained in the .pftxs, and then convert the textures to DirectDraw Surface (.dds) format. - Regex File Copier: The user can copy files and their directory structures to another folder using regular expressions. ##### Archive Unpacker ![](/assets/Archive%20Unpacker.png){:.thumb .legacy-small width="220px"} The Archive Unpacker is a simple tool which unpacks user-specified .dat files, and then unpacks all .fpk, .fpkd, .pftxs and .sbp files which resided in the .dat files into one single directory structure. This tool has three purposes: 1. To provide the user with a "monolithic" view of MGSV's files, assuming the user chooses to unpack all .dat files. 2. To provide Mass Texture Converter with .ftex(s) files. 3. To provide File Proliferator with file lists (TppMasterFileList.txt is pre-included in the download) and a texture directory (for pulling vanilla .ftex(s) files into _pftxs folders). Notes: - Unpacking all .dat files will take a while. - The tool will unpack in reverse-alphabetical order, starting with texture4.dat and ending with 0/00.dat. This allows for any updated files to overwrite their older versions. For this reason, I do not recommend unpacking modded .dats into your target folders. - The unpacked (Condensed) directory structure requires \~25GB of space, excluding MGO/SDD Archives. - The "Condensed Directory Structure" option will take the files contained within the .pftxs, .fpk, .fpkd and .sbp and pull them to the head of the directory structure. - (Ex: \\Assets\\tpp\\SomePack_fpk\\Assets\\SomeFile.fmdl -\> \\Assets\\SomeFile.fmdl). - Otherwise, the files will remain in their unpacked folders (Ex: \\Assets\\tpp\\SomePack_fpk\\Assets\\SomeFile.fmdl). - The "Condensed Directory Structure" checkbox must be checked in order for Mass Texture Converter to convert all MGSV textures. ##### Mass Texture Converter ![](/assets/Mass%20Texture%20Converter.png){:.thumb .legacy-small width="216px"} The Mass Texture Converter enables the user to convert any given amount of .ftex/.ftexs files into .dds files. The user simply selects the input folder, the output folder, and whether to include subdirectories for conversion. This tool has one purpose: 1. To provide the user with an easy and safe way of converting a large number of .ftex/.ftexs into .dds files. Notes: - Unpacking all of MGSV's textures will take a while. - In order to convert a .ftex file, all of the .ftexs files for the texture must be contained in the same folder. \*For this reason, the Archive Unpacker must use the "Condensed Directory Structure" option (Some .ftex and .1.ftexs are contained only in .pftxs files, so they must be pulled into the same folder as the remaining .ftexs). - If "Convert Subfolders" is selected, the tool will also search through the subfolders of the input directory. The output directory will retain the directory structure. - (Ex: Input\\Assets\\SomeTexture.ftex -\> Output\\Assets\\SomeTexture.dds). - I recommend using the SageThumbs Plugin, in order to preview the .dds files in their thumbnails without opening them in GIMP or Photoshop. - - Excluding MGO/SDD textures, the unpacked .dds files require \~21GB of space. ##### File Proliferator ![](/assets/File%20Proliferator.png){:.thumb .legacy-small width="220px"} The File Proliferator tool is the most powerful and feature-rich tool of the set. Although it has a number of use-cases and functions, its primary role is to create MakeBite-ready file directories for MGSV. From the files input by the user, this tool will search through the entirety of MGSV's files (including the contents of .fpk, .fpkd, .pftxs and .sbp files) for a matching filename. Upon finding a match, the tool will create a mimic of the file's directory structure in the target directory, and then place a copy of the user's file into that directory. In essence, this "proliferates" the user's files into the MakeBite structure, ready to be packed into a .mgsv file. This tool has a number options, but only one purpose: 1. To help create a MakeBite-ready file structure from the user's input files. Notes: - TppMasterFileList.txt: The tool will look up files from a text document, TppMasterFileList.txt, which lists all of the file paths (including files contained in .fpk, .fpkd, .pftxs and .sbp files), excluding those from MGO/SDD Archives. - TppGeneratedFileList.txt is build automatically after using the Archive Unpacker. The user can promote TppGeneratedFileList.txt to TppMasterFileList.txt by simply changing the filename and replacing the old TppMasterFileList.txt. - Users can manually add file path entries into TppMasterFileList.txt, and File Proliferator will accept these paths as true MGSV file paths. - This may be useful if the user intends to use custom texture or script names for their mod. - Reference File: The user can choose to select a "Reference File" for their directory structure. File Proliferator will search the MGSV file paths for folders that contain the Reference File, and then create a directory structure to mimic wherever that file was found. All of the user's input files are then copied to those folders. - Using a Reference File is very situational, especially if the "Set in Root of Packs" checkbox is unchecked. - If the "Set in Root of Packs" checkbox is checked, File Proliferator will pull the user's file to the root directory of the _fpk, _fpkd, _pftxs and _sbp folders where the Reference File was found. This may be useful if the user is adding hashed files to the folder of a Reference File. - (Ex: User input: 1aa64302cee42.ftex, Reference File: SomeFile.ftex, | 1aa64302cee42.ftex -\> \\Assets\\SomePack_pftxs\\1aa64302cee42.ftex) - Texture Options: File Proliferator comes with three options for texture management when creating the MakeBite directory structure. - Pull Vanilla .ftex | .ftexs to _pftxs: Selecting this option will prompt the user to set a Texture Directory, where File proliferator can "autofill" the generated _pftxs folders by grabbing vanilla .ftex and .ftexs files and copying them to the _pftxs folders (in order to reflect the vanilla .pftxs file). - This option is intended to utilize the Archive Unpacker's Output Directory as a texture library. - This process may take a while depending on the number of generated _pftxs and their vanilla filesizes. - This function also utilizes the TppMasterFileList in order to find .ftex/.ftexs files that belong to a given pftxs path. - Convert .dds to .ftex: With this option enabled, The user can use .dds files as Input Files. The tool will attempt to convert these files to .ftex/.ftexs files before proliferating them to the MakeBite file structure. - If this option is not selected, using .dds files will not be converted or copied to the MakeBite directory structure (unless the user manually adds the .dds file paths to the TppMasterFileList.txt). - Pack _pftxs: Upon creating the MakeBite Directory Structure, this option will automatically pack any _pftxs folders to .pftxs files using BobDoleOwndU's AutoPftxsTool. - Since MakeBite does not automatically repack _pftxs folders like it does with _fpk or _fpkd, the user will need to either manually pack _pftxs folders, or check the "Pack _pftxs" checkbox. - After packing the .pftxs files, File Proliferator will ask the user whether to delete the leftover _pftxs folders. In either case, the user should not include _pftxs folders in their final MakeBite file. ##### Filename Updater ![](/assets/Filename%20Updater.png){:.thumb .legacy-small sswidth="220px"} The Filename Updater allows users to update old, hashed filenames to their unhashed filepaths. Assuming that the files were originally unpacked using an outdated version of the qar_dictionary.txt, this tool will copy and rename the input files to the target directory. This tool has one purpose: 1. To provide users with support when updating old mods. Notes: - Upon finding an update for a filename, the tool will create a copy of the hashed file. The copy is then renamed and moved to the output directory. - (Ex: 3cb5fc5a6e14d.2.ftexs -\> \\targetDirectory\\am10_main0_def_c00_bsm.2.ftexs) - When a filename is updated, the tool can include the file's full filepath by checking the "Include Directory Structure" checkbox. The copy of the updated file will be sent into the directory structure. - (Ex: 3cb5fc5a6e14d.2.ftexs -\> \\targetDirectory\\Assets\\tpp\\weapon\\amo\\Pictures\\am10_main0_def_c00_bsm.2.ftexs) ##### Archive Transferrer The Archive Transferrer allows for the user to automatically import Ground Zeroes and Metal Gear Online data into The Phantom Pain. This tool will reformat and copy the files as necessary, without modifying the original data. This tool has one purpose: 1. To provide the user with a streamlined method of pulling data archives from Ground Zeroes and Metal Gear Online into The Phantom Pain. Notes: - Currently the tool is only designed to transfer the "texture" archives from Ground Zeroes / Metal Gear Online. A future update should allow the user to transfer the "chunk" archives. - This tool utilizes [morbidslinky's fork of GzsTool](https://github.com/JosephZoeller/GzsTool) in order to reformat the Ground Zeroes archive. - Transferring the archives may take a moment. In order to read these foreign archives, SnakeBite makes the necessary edits to the foxfs.dat upon its initial setup, independently from the Archive Transferrer. - There is no order to setting up SnakeBite and importing foreign archives, but both steps are necessary in order to utilize the other games' data. ##### Texture Aggregator The Texture Aggregator allows for the user to automatically build textures from a Packed Fox Textures (.pftxs) file. Given a .pftxs, the tool will unpack the file's partial textures, pull the additional texture files from the user's unpacked archives (from the Archive Unpacker's output), and then (optionally) convert all fox textures to DirectDraw Surface (.dds) files. This tool has one purpose: 1. To provide the user with a streamlined method of collecting all textures associated with a specified .pftxs file. Notes: - This tool expects the user to have unpacked the contents of all of TPP's texture archives to a directory using the Archive Unpacker tool. - The aggregation process may take a moment, depending on the contents of the .pftxs file. - TppMasterFileList.txt: Similar to the File Proliferator tool, Texture Aggregator references TppMasterFileList.txt to determine the additional textures which need to be pulled from the unpacked texture archives. - I recommend using the SageThumbs Plugin in order to preview the .dds files in their thumbnails without opening them in GIMP or Photoshop. - ##### Regex File Copier More for researching, exploring and referencing files than creating mods. Given a regular expression (try https://regexr.com/), the tool will copy files that match the regular expression from one specified folder into another, retaining the subdirectory nesting of the copied files. ### `wiki:wiki/File_Structure_(TPP).md` Metal Gear Solid V: The Phantom Pain's file structure is made up of a series of a series of files with the .dat extension. All of the .dat files are QAR archives with their extensions changed with the exception of e2f8e499bc8f3606.dat, e2f9a1fda590d087.dat, e2faa449a7e0781d.dat, e2fb02c35da41a21.dat, and e2fbebbd66f86086.dat, which are .wmv files with their extensions changed. See [File Formats](/File_Formats "wikilink") for more information about the files in the dats, [Things Codes](/Things_Codes "wikilink") for information on some of the naming of files, [Sound Codes](/Sound_Codes "wikilink"), or [animation notes](https://chocmake.github.io/guides/mgsv-adding-player-motions/#resources). ##### Master Folder The master folder contains all of the assets used in The Phantom Pain. | Label | Dat File | Texture File | Notes | | ----- | ---------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | | cypr | chunk0.dat | texture0.dat | Cyprus chunk. Also contains files related to the player and items used by the player. | | base | chunk1.dat | texture1.dat | Base chunk. Contains files related to buddies, some form variation related files (mostly unrelated to the player), and some weapon files. | | afgh | chunk2.dat | texture2.dat | Afghanistan chunk. Contains files related to Afghanistan. | | mtbs | chunk3.dat | texture3.dat | Motherbase chunk. Contains files related to Motherbase. | | mafr | chunk4.dat | texture4.dat | Middle Africa chunk. Contains files related to Africa. | | data | data1.dat | N/A | Data chunk. Contains unpatched scripts. | In addition to the base .dat files, the master folder also contains directories for updates and DLC respectively. | Folder | Notes | | ------ | ---------------------------------- | | 0 | Contains the game's updated files. | | 1 | Contains the game's DLC files. | Each of the 1 folder's DLC folders also contain a 0 folder. Which just like the 0 folder in the master folder, contains a 00.dat and 01.dat file. In each of these folders, the 01.dat file contains textures, while the 00.dat file contains all other assets. When SnakeBite is installed it moves the files in master/0/00.dat,01.dat to master/a_chunk7.dat, a_texture.dat and the patched 00.dat lua files into 01.dat. From then it installs mods into 00.dat ### `wiki:wiki/Fox.md` The Fox Engine provides the organizational and functional framework atop which the Metal Gear Solid V games are built. The game engine cannot do anything by itself; it exists simply to build games. When the game is packaged for distribution, the game and game engine code become indistinguishabl from one another, which is why there is no separate "FoxEngine.dll" or even another executable aside from mgsvtpp.exe. However, the engine vs. game separation is highly visible in the organization behind the scenes. Fox divides its code into "Modules," which are each loaded by the game and they can also reference each other. For example, **Anim** requires **Gr**, the graphics module, to be loaded first. A list of modules can be seen below: - [Anim](/Anim) - [Animx](/Animx) - [As](/As) - [Cc](/Cc) - [Character](/Character) - [FoxCore](/FoxCore) - [Demo](/Demo) - [Demox](/Demox) - [Des](/Des) - [EdDemo](/EdDemo) - [Fio](/Fio) - [Fs](/Fs) - [Fx](/Fx) - [GameCore](/GameCore) - [FoxGameKit](/FoxGameKit) - [GameService](/GameService) - [Geo](/Geo) - [Geox](/Geox) - [Gr](/Gr) - [Graph](/Graph) - [Graphx](/Graphx) - [Grx](/Grx) - [FoxKernel](/FoxKernel) - [MotionGraph](/MotionGraph) - [Nav](/Nav) - [Navx](/Navx) - [Ncl](/Ncl) - [Nio](/Nio) - [Nt](/Nt) - [PartsBuilder](/PartsBuilder) - [Ph](/Ph) - [Phx](/Phx) - [FoxQuark](/FoxQuark) - [Sd](/Sd) - [Sdx](/Sdx) - [Sim](/Sim) - [Simx](/Simx) - [Tactical](/Tactical) - [Ui](/Ui) - [UiScene](/UiScene) - [Uix](/Uix) - [Vd](/Vd) TPP itself also has multiple modules which host functionality specific to the game - [TppEffect](/TppEffect) - [TppGameCore](/TppGameCore) - [TppGameKit](/TppGameKit) - [TppMotherBaseCore](/TppMotherBaseCore) - [TppMotherBaseStage](/TppMotherBaseStage) - [TppNetwork](/TppNetwork) - [TppSound](/TppSound) - [TppSystem](/TppSystem) - [TppUi](/TppUi) ### `wiki:wiki/FoxKit-_GeoTrap_GeoModuleCondition_and_BoxShape.md` Guide for FoxKit 1.0. This guide resume in one Video how to add a Trap, set the lua and mod folder and test Ingame the condition. GeoTrap is the entity that trigger something if a Gameobject (Player, Enemy, Camera) touch the Shape under certain condition. There are inumerous condition to trigger but this guide only show the smallest one: If Player reach the trap, print "Trap Works\!\!\!". The video does not have sound to follow the steps, but visually can help understand how to procede. After work in FoxKit, it show how to set from scratch a mod folder using the mission free roam in afgh, f30010 and how to trigger in f30010_sequence.lua the Trap "TrapWhatever" in fox2 file. ### `wiki:wiki/FoxKit-_Installing_Import_Files_and_Terrain.md` ##### **Installing FoxKit** Download at Click Code (green button) \> Download zip Unzip FoxKit-master somewhere. The FoxKit folder within this is a Unity Project. Open Unity 2018.3.6f1 (64-bit). Probably there is a better version, but this one works fine with current FoxKit. File \> Open Project. Point it to FoxKit-master\\FoxKit Loading will take a long time. ![](/assets/Foxkit%20Window.jpg){:width="555px"} ##### **Extracting Game Files and Texture Folder** Please see [File Monolith](/File_Monolith "wikilink"). Using Archive Unpacker in all the four-five chunks to one main folder should be ok. ![](/assets/Foxkit03.jpg){:width="466px"} In general FoxKit works by replicating the mgsv Assets files in the FoxKit Assets folder, though due to the time to import different files you should limit what you copy in to what you're working on. Just an example:![](/assets/AssetsFolder.jpg){:.thumb} Texture chunks do not need to be imported into the FoxKit folder, and are set up differently. Extract and convert all the texture in dds with the tools in File monolith and place wherever outside Unity. After that go to menu **Unity/FMDL studio/ Set Texture Folder.** **It's highly important do it now, before import assets of the game in Unity as we'll see later.** ##### Loading TerrainFile This guide will treat a small area of location AFGH loading just a few tiles. ###### **Finding the .tre2 file (TerrainFile)** Go to **chunk_all/Assets/tpp/pack/location/afgh/pack_common.** Inside the pack_common there are the Fox Packages. Extract **afgh_common.fpk**. Continue to open the folder. **afgh_common_fpk/Assets/tpp/level/location/block_common/.** Here there is afgh_common_terrain.tre2. ![](/assets/Tre2.jpg){:width="554px"} Now, create all those paths that you find the tre2 inside Unity and copy paste the file. Below it can see the afgh_common_terrain.tre2 in the right folder. ![](/assets/Inunity.jpg){:width="493px"} ##### **Loading TerrainTileFile** Afghanistan location has 128x128 tiles. But here we will load just a small area. The user can load all the tiles and wait a lot to load in Unity or find a few one and work isolate with each one. The follow tiles will be choose: afgh_130_146 and afgh_130_148 Go to **chunk_all/Assets/tpp/pack/environ/stagelow/afgh/small_lod0/130/** Extract the two Fox Packages, **afgh_slod0_130_146.fpk and afgh_slod0_130_148.fpk** See below: ![](/assets/Fox04.jpg) Copy and paste this folder path to Unity. **Assets/tpp/pack/environ/stagelow/afgh/small_lod0/130/** and copy paste the fpks inside of 130. ![](/assets/Iunity.jpg){:width="543px"} Inside this Fox Package should have two htres per folder in level. But also it has a lod0 model of the assets that it's interesting to keep and drag to scene View to grasp a hint on visual. ##### **Loading the TRE2 file** Now that we have the tre2 inside the pack_common and two htre files in pack_small it's time to show terrain in Unity. To back to the file afgh_common_terrain.tre2 in Unity and select it. A window called inspector will show. Click at "**stitch terrain file**". Save the prefab to /Assets and wait until it shows something in Scene View. ![](/assets/Unity52.jpg){:width="558px"} At first it seems like nothing worked after prefab showing up in Hierachy window. Select the prefab again and scroll down the Inspector Window until you see the T**essellation Edge Lengh**. Slide to value 1. ![](/assets/Un6.jpg){:width="546px"} **Check the Beautiful terrain below.** ![](/assets/Terrainloaed.jpg){:width="552px"} ##### **Loading Small Assets from the two Tiles** Each tile is built with tons of Assets and Files in pack_small folders. You can see the Terrain above is complete empty. To fullfill it with cliffs, rocks, trees and other types of file like geoms, nav2, bushs, paths it will need to copy and paste new files and datas. At this point it's interesting to copy a lot of FMDL and GEOM files in environ folder the game has. Loading this into Unity takes some time and can be annoying... Even Afgh that has its own environment assets take some model from another location so... It's wise to reserve some time to load all the models the game has. ![](/assets/Paths02.jpg){:width="591px"} Copy and paste the folder to Unity and relax... ![](/assets/Relax.jpg){:width="437px"} FoxKit can show a preview of fmdl before anything else... Texture is missing, but it can be done later. ![](/assets/Fmdl%20view.jpg){:width="493px"} Now to find the Fox2 files\!\!\! Go to **chunk_all/Assets/tpp/level/location/afgh/block_small/130.** Notice that this small pack is not the same where **htre** files were founded. If the terrain says 130_146 and 130_148. This is not the case for the fox2 files to load the models on Terrain. This is something that it needs several attempts to find where the models will load in terrain. See image Below that I loaded to Unity a few ones and only 132_149, 132_150 and 131_149, 131_150 had some rocks to fit the Terrain. Later you can copy all those Datas to Unity as long you get familliar with the files... ![](/assets/NoneedFornow.jpg){:width="486px"} When you load a Fox2 file in Unity, FoxKit will warn about missing files in Console Window. It help to know which file should be located and paste to project. ##### **Converting FOX2 file as Asset file in FoxKit** Go to one of Fox2 we load. I will use 130_146_asset.fox2 file as example. Select it and at Inspector Window hit Create Editable Copy. Save the new file with the same name of the original file or a new one in the same place. ![](/assets/Hitbutton.jpg){:width="470px"} The Icon is the same for fox2 file and the new .asset file. Now it's missing a package definition. Let's create one and stick the new file to it. ![](/assets/Missingpackage.jpg){:width="461px"} Go to menu **Unity Assets/Create/FoxKit/Package Definition**. It will create a package that can be fpk or pfkd or other types. Standard its fpkd which is the right one. Usually Unity will generate the PackAge in FoxKit/Assets folder or in the folder the user is at the moment. Check if its the case. For now I place the Definition in the same folder where the afgh_130_146_asset_copy.asset is. I rename to something whatever... Select the "Whatever", go to Inspector Window. Hit plus in Entries and Drag the afgh_130_146_asset_copy.asset to the empty field below Entries. See image below. Now the editable fox2 should load the files in the DataSetView. Even if the fox2 is not converted to .asset in Unity. It can be open in DataList Window later, but not editable. ![](/assets/Aff.jpg){:width="546px"} ##### **Small Fix to Loading StaticModelArrays** User whose nickname is Automat pointed a small fix to correctly load StaticModelArrays. It's recommended to fix that before trying to load any fox2 file the game have that load tons of Entity StaticModelArray. I don't know if this makes sense or not for a user that just began to work with FoxKit. It's a good routine to read, find and understand every Entity a Fox2 file have to knowledge the amount of possibilites and nopes as Modding mgsv. Anyway... Open the Image Below. Navigate to the StaticModelArray.cs and open in Notepad++ or any editor. Remove the red line and add what Green Line says. Save, Close and back to Unity to auto load fix. ![](/assets/FixStaticModelArray.jpg){:width="592px"} ###### **Drop Assets in Terrain** Alright\! Go to Menu **Unity FoxKit/Data List Window**. Place that new window whatever you want. Go back to any assets we loaded, let's say **afgh_130_146_asset_copy.asset** . Check if Package definition still holds the Entries. Back to one of afgh_130_146_asset_copy.asset for example, double click to see the Dataset list entities as well the models and gameobjects in the Scene View. Check it\!\! ![](/assets/Finally.jpg){:.left width="482px"} ![](/assets/Ending.jpg){:.left width="464px"} ###### And that's it!! A small guide to install, import Assets and Load Terrain as well see a little bit of the fox2 files. Check Discord Server Modders Heaven to talk about it and ask for help related to Mods/FoxKit. ### `wiki:wiki/FoxKit-_TppLightProbe_PointLight_and_Spotlight.md` This guide show how to set a Probe to indoor space and add two types of light, Point and Spot. Require the user to know how Datasets and Entities in FoxKit. First. create a Dataset and add two Entities. TppLightProbeSHCoefficients and TppLightProbe. Ground and House is just to have a better picture of the use here. ![](/assets/Light1.jpg){:.legacy-small width="390px"} ##### **LightProbe** ###### **TppLightProbeSHCoefficients** TppLightProbeSHCoefficients will load the lpsh file that have all the probes inside to use. We can reuse the lpsh **afgh_field_light.lpsh** found in *Chunks\\Assets\\tpp\\pack\\location\\afgh\\pack_large\\afgh_field_fpk\\Assets\\tpp\\level\\location\\afgh\\block_large\\field\\**afgh_field_light.lpsh*** Copy and paste to the fpk of you mod that match with the folder structure in FoxKit. In my case my mod load here *\\Assets\\tpp\\pack\\location\\smpl\\smpl_fpk\\Assets\\tpp\\level\\location\\smpl\\block_common\\**afgh_field_light.lpsh*** *And in FoxKit Assets\\tpp\\level\\location\\smpl\\block_common\\**afgh_field_light.lpsh.*** Drag and drop the file ***afgh_field_light.lpsh*** in TppLightProbeSHCoefficients. ![](/assets/Light2.jpg){:width="465.991px"} ###### **LightProbes in LPSH file** Before move to TppLightProbe have a look on image below. I list all the 124 probes that afgh_field_light have inside in day and night light. Some are dark while other are bright. All have this tint of afgh colour in red, orange, yellow. At night it goes green, grey blue. Indoor areas use dark probes. So lets choose the LP_0038. The name "LP_0038" you can find inspecting the lpsh in FoxKit and its matter write the exactly name of the Probe in Dataset if you want make work. ![](/assets/Light3.jpg){:.left width="421px"} Name in FoxKit. ![](/assets/Light4.jpg){:.legacy-small width="372.972px"} ![](/assets/LPSH%20Field%20ref.jpg){:.left .thumb} ###### **TppLightProbe** 1 . After choose the probe to use. Rename to the one in Dataset before adding to the scene. We choose LP_0038. 2\. Hit TransformEntity to the Entity go to Scene. 3\. Create a primitive cube under the lightprobe and move/rotate/scale the entity to fill the inside of the house. Remember to add the scale in TppLightProbe window later, ![](/assets/LightProbe5.jpg){:width="842px"} Now. Lets see all the parameters TppLightProbe have. **enable** = True or False. Check true of course. **lightArea** = Can be a locator entity to store the area where probe will happen, but in this case we dont need to use. **innerArea** = To be Written. Can be left empty for now. **shCoefficientsData** = is the lpsh so our LP_0038 will have the probe inside the lpsh. Open and choose TppLightProbeSHCoefficients0000 here. **onLights and OffLights** = To be Written. Can be left empty for now. **innerScales** = Are the float values between 0 and 1. If above 1 it will unload. Look the graphic about it below. The Axis is the mid of this probe and then we have the X+-, Y+- and Z+-. A Value of 1 in all will fullfill the probe in the map sharp. While a value of 0 in all the innerScales will show a soft probe. For indoors the best is 0.98 in all. There are nice probes to configure here. If the house were open on a side so we could diffuse the probe to this open side. ![](/assets/Light6.jpg){:width="737px"} **priority** = This parameter define which probe will be over another probe. Its common use tons of probes and then use a huge one to diffuse some probes or use a Probe to Dark all the map first and then use lots of probes with more priority to bright the area. Number can be 500 to 1 and 500 be the low in priority and 1 be the first of course. **debugMode** = To be Written. Can be left empty for now. **drawRejectionLevel** = We can choose Level 7, no Reject. This show the distance of rendering the entity. Game normally use Level 4. **shapeType** = Default is the square cube. For experimentation later, why not use the other options... **exposure** = To be Written. I try to add lots of values but nothing happen here. I choose -1 mostly because all the entities I found use the same. Need to test more to see if more values does something or not. I have some ideas that this is the amount of time the player need to recover from see the color of probes or when goes off the probe to the light. **localFlags** = To be Written. Choose 11 should be fine. **occlusionModeOpenRate** = To be Written. Can be 0. ![](/assets/Light7.jpg){:width="362.995px"} In Game it shows like this. ![](/assets/Light8.jpg){:width="659px"} ###### **Small Fix in FoxKit to show Flags.** FoxKit normally dont show the localFlags parameter. To enable this option in the Entity go to \\FoxKit\\Assets\\FoxKit\\Modules\\DataSet\\Fox\\TppEffect and open in any editor the file TppLightProbe.Generated.cs. Find this line and change the **Never** word to **EditorAndGame.** Same will be happen to PointLight and SpotLight entities. ```csharp [OdinSerializeAttribute, NonSerializedAttribute, PropertyInfoAttribute(Core.PropertyInfoType.UInt32, 504, 1, Core.ContainerType.StaticArray, PropertyExport.Never, PropertyExport.Never, null, null)]` private System.UInt32 localFlags; ``` ##### **PointLight** **PointLight** Entity use a second Entity to convey the **LightArea** using the **Entity Locator** to do the room of light, rotate and scale. The PointLight Entity itself does not scaled or rotated, only move inside the LightArea as the pivot of the source light. Just think like the lamp position (Pointlight) inside a room (Locator). *For the record, looks like a parameter of Locator "size" is always set to be 1, not 0.* The **IrradiantionPoint** need to be test, though can be left for now. ![](/assets/P1.jpg) **Color** PointLight use Color to delivery aesthetics visual. The strenght of the color wil change once we set the Temperature which will turn it warm or cool. So, if you choose a green, this green color can be warm if temperature is lower or cool if the temperature is higher. Set Alpha to 255 if you want to keep the max of colour strenght in the field. ![](/assets/P2.jpg) **ReachPoint** The Scale of the Entity Locator looks to fit the ReachPoint Field. And the OuterRange will set how far the light will get, to the bounder. Usually the best OuterRange size would be the minimum ReachPoint value so that the light will fade correctly inside the room. For now, I set 22 in the example. ![](/assets/P3.jpg){:width="461.969px"} **OuterRange and InnerRange** The OuterRange have the values between the minimum and max values of ReachPoint. If a square reachPoint is 10,10,10. The OuterRange can be safely 10. 11 does not nothing. Then once set the Outer, InnerRange will be 0 to 9. If Inner is 10 or higher it will turn off Light. As well, inner does the fade of the light as near of the OuterRange Value. Image below show using the Outer fade to Z: 22. Even if Inner is 12 so that the light will be diffuse, the Y value is 7 and the Height of the room will hit stronger. ![](/assets/P4.jpg){:width="493.986px"} **Temperature** This turn the color Warm or Cool. The Values are pretty much between 0 to 80.000 if needed. ![](/assets/P5.jpg){:width="509.988px"} **Color Deflaction.** The float parameter may help adjust a color to be right, but need more test. For now, can be left 0 value. **Lumen.** Its the **Brightness** of the source Light. A Value between 100 to 20.000 is safe to use. 20.000 will shiny maybe too much... **LightSize.** Need to test more. It does increase brightness a little bit if value is set to 1. Float can be left with 0. **Dimmer.** Does lower the brightness. Float can be left with 0. **ShadowBias.** It displace the shadow position that Light creates if **LodShadowDrawRate** is higher than 0. This float can be negative or positive. **LodFarSize and LodNearSize** does have a huge impact to look right, the light. It need more test to create a perfect Light. My best values so far are LodFarSize 40 and LodNearSize 140. But I did not get a logic between then, yet. I hope anyone can contribute here. **LodShadowDrawRate.** If 0, it will not cast shadow even if LocalFlag does the true value for castShadow. Between 0.1 and 1 if will slowly add the shadow cast by the Light source. More than 1 does not have any effect as float 1 pitchdark the shadow area. 0.5 will opacity the shadow. **LightFlags.**I hope CapLag can write better here about it. So far, put value 11 does everything it need. **LodRadiusLevel.** Between 0 or 7. **LodFadeType**. Note sure what are the types. It looks like common have 4 here as it see in many PointLight Entities. **The Result** ![](/assets/P6.jpg) > \== **SpotLight** == To be written {:.needs-revision} ### `wiki:wiki/FoxKit-_TppPrimRiverModel_TppWaterBounding_TppTextureLoader_and_FxLocatorData.md` Guide for FoxKit 1.0. This guide will continue the Mod Folder created in [FoxKit: StaticModel and GeoxCollisionFreeShape](/FoxKit-_StaticModel_and_GeoxCollisionFreeShape "wikilink"). Please, see [Setting the Mod Folder](/FoxKit-_StaticModel_and_GeoxCollisionFreeShape/#setting-the-mod-folder) and [Creating a Fox2 file](/FoxKit-_StaticModel_and_GeoxCollisionFreeShape/#creating-a-fox2-file). Now we'll meet four entities building water in-game and adding a vfx. #### **TppPrimRiverModel** and TppPrimRiverModelParam This Entity creates the visual and movement of water in-game. A second Entity called TppPrimRiverModelParam deals with more options. The Entity also needs to load a texture which TppTextureLoader should come in hand. Also we need to attach this water visual to a static-model that game calls for Puddle. I choose the puddle afgh_pddl001_vrtn032. This one does not need a geom file, it is optional. If the puddle has a geom, it will avoid camera go underwater. As we learned from the previously guide on how to load a static-model, this one is the same. Check the rotation and copy paste to Entity Window. Change the pivot to Center/Local because some models, like the one I chose, have a far pivot to handle... Place where you think it may be good and done. ![](/assets/Puddle01.jpg){:width="615px"} ###### After that let's see the Entity Window **TppPrimRiverModel. Create it in DataList Window/Entity/TppPrimRiverModel** ![](/assets/Prim01.jpg) **primRiverGroupName** is whatever you might call it. I named it as WeirdWater. **visibility** is the bool of false or true. Check true. **depthBlendLength** seems to work with float values between 0 to 1.0 and it seems to handle how much visibility between the surface and the bottom of the puddle. I choose 0.2 **raise**. It's not clear what it does to me. I saw values like -800, -1000. Lastly, link the StaticModel Puddle we created. It only shows up if the DataSet is inside the package definition we chose. **afgh_common**. ###### Now, **TppPrimRiverModelParam** ![](/assets/Prim02.jpg) **primRiverGroupName** is the same name we chose before. WeirdWater. **visibility** is the bool of false or true. Check true. **baseTextureName** (afgh_pddl001_ct_bsm)**, normalTextureName** (afgh_pddl001_te_nrm) **and cubeMapName** (cmp2) are the textures names that we will see with TppTextureLoader later. **lightCaptureLocator** Need more info about that. It can be empty. **First Wave** (scrollDirection0, scrollSpeed0 and scrollScale0), **Second Wave** (scrollDirection1, scrollSpeed1 and scrollScale1). You can see that I chose one wave to be calm while the second wave will be bigger, fast and move to another direction. Unfortunately it lacks more info about which values precisely means. **transparency** is obviously. Float value between 0 to 1.0. **transparencyDepthBlend** sounds a lot like the **depthBlendLength** **reflectionRate** Float value between 0 to 1.0. Didn't catch what reflection means here. Need more info. **distortionPower** Float value between 0 to 1000. If value is too high it disturb the water a lot if player walk through. If jumps into the ground/water it splashes a lot of water. **surfaceShadowRate** Float value between 0 to 1.0. Shad only. **oilIntensity** It needs more info. I put 0 to not have any oil aspect. **useHnmTexture** and **debugReset** are booleans that need more info. Can be unchecked. ##### **TppWaterBounding** It adds a effect of player getting wet, splash water and trigger a sound of wet. It's quite simple to add. **Create it in DataList Window/Entity/TppWaterBouding.** ![](/assets/Prim03.jpg){:width="554px"} Once you load the **TppWaterBounding entity** to the Dataset and create a TransformEntity, set a cube inside of the gameobject in Hierachy Window. Move, rotate and scale, not the cube but the TppWaterBounding0000. Make sure the WaterBouding fills the puddle. Copy and paste the rotation and scale to the Entity Window. **enableRotate** can be unchecked. Need more info about it. **debugDraw** need more info. **type** choose what is the best for you. ##### **TppTextureLoader** This one will link the texture that needs to be showed for water in **TppPrimRiverModelParam.** **baseTextureName,** afgh_pddl001_ct_bsm **normalTextureName,** afgh_pddl001_te_nrm **cubeMapName,** cmp2 Because of that we now have to create a pftxs folder and add the ftex textures. The way is the same as we did with afgh_common_fpk and afgh_common_fpkd in **Setting the Mod Folder.** go to **LoadingStairsInGame/Assets/tpp/pack/location/afgh/pack_common/...** Create a **afgh_common_pftxs** folder. ![](/assets/Texturefolder01.jpg){:width="530px"} Open the afgh_common_pftxs and create **/Assets/tpp/environ/object/afghanistan/puddle/afgh_pddl001/sourceimages/** Get all the **ftex** and **ftex_1** textures in Texture_dat from the same path folder we made, copy and paste to the folder we created. It should look like the image down below. ![](/assets/Texturefolder07.jpg){:width="601px"} One more folder path should be made for the cubemap. Open the afgh_common_pftxs and create **/Assets/tpp/common_source/cubemap/environ/afghanistan/cm_afgh_cb_vllg003/sourceimages/test03/** ![](/assets/Texturefolder04.jpg){:width="598px"} The choice of those texture are my fav. Feel free to choose the best texture for puddle and Cmap. Copy this folder with the files to Unity. **/Assets/tpp/environ/object/afghanistan/puddle/afgh_pddl001/sourceimages/ /Assets/tpp/common_source/cubemap/environ/afghanistan/cm_afgh_cb_vllg003/sourceimages/test03/** Let's see the Entity Window for **TppTextureLoader. Create it in DataList Window/Entity/TppTextureLoader** ![](/assets/Texturefolder06.jpg) The name of Textures and forceLargeTextures are the same we saw in **TppPrimRiverModelParam.** Only that wt_bsm and srm went out of TppPrimRiverModelParam. We need more info about those two and if can work without them or not. Choose only ftex. And not ftex_1. ![](/assets/Texturefolder08.jpg) Now, let's pack the **afgh_common_pftxs** with the tool **[AutoPftxsTool.v0.2](https://github.com/BobDoleOwndU/AutoPftxsTool/releases)** and place it into the Mod Folder for when we test in-game. MakeBite does not pack pftxs folders like it does with fpk and fpkd. ![](/assets/Texturefolder05.jpg){:width="635px"} ##### **FxLocatorData** **FxLocatorData,** just pick one vfx and load inGame. But what vfx to load? We currently don't have any tool that does a preview of each vfx. This Entity comes to help us load the vfx and look in gameplay how it looks like. Another way to see a hint of what vfx is is open the file with the [vfxTool](https://github.com/youarebritish/VfxTool/releases/tag/1.2) and search the texture to grasp a visual of what might be the effect. After some tests I found one vfx of water for this guide. **SPLASH/ fx_tpp_splwtr10_m1.vfx**, its a waterfall. We need to add a new folder path to our Mod Folder. Go to **afgh_common_fpkd** Create the path **/Assets/tpp/effect/vfx_data/splash/** Find the Effect **fx_tpp_splwtr10_m1.vfx** and copy to this new folder. ![](/assets/Fxlocator01.jpg) Copy the **vfx_data/splash/fx_tpp_splwtr10_m1.vfx** to Unity under the /Assets/tpp/effect/ ![](/assets/Splash011.jpg){:width="405px"} Create Let's see the Entity Window now. **Create it in DataList Window/Entity/FxLocatorData** ![](/assets/Fxlocator02.jpg){:width="647px"} Move the effect where it fits. Some effects really matter if rotated or noted. The Axis Blue seems to indicate the direction = 0. Scale does not matter unless you edit it with the vfxTool. **variationName** Need more info about. Can be empty. **effectInstanceName** Any string input here can be use in Lua script to turn off/on the effect with TppDataUtility.CreateEffectFromId("Waterfall") or TppDataUtility.DestroyEffectFromId( "Waterfall" ) **enableUserRandomSeed** Need more info about. Can be empty. **shapeKeep** Check it so that if the vfx does not have a loop it will keep alive. **createOnInitialize** It will of course spawn as soon player show up. **blockMemoryAllocation** Need more info, but does sound interesting to check it if it's using more than five FxLocatorData. Sometimes six or even ten wont load... And the last, drag and drop the vfx file. ##### **Almost Done...** Save and export the new fox2 file to fpkd. Remember to update the fpk folder with the new staticmodel puddle. Now.. there is a few things we need to edit manually for the fox2file. The same process we did in the previously guide. ###### **First Fix** The Package Definition does not look right here. So its better to erase and keep empty. ![](/assets/Ending01.jpg){:width="648px"} ###### **Second Fix** And the StaticModel **FLAG** should be **4** and not **7**. If kept as 7 it won't load the transparency of water and texture. ![](/assets/Ending02.jpg){:width="540px"} Pack the fixed fox2 file again. Make the .mgsv file in MakeBite, building the **LoadingStairsInGame folder.** Open with SnakeBite and see it in-game. ![](/assets/Ingame01.jpg) ##### Doing it without FoxKit Alternatively, you can do it without using FoxKit. Immidiately spawning chaff effect from lua: 1. Create a custom fpkd with a custom Fox2 effects file and the `/Assets/tpp/effect/vfx_data/weapon/fx_tpp_wepchf01_s3.vfx` file from chaff strikes (`0/00_dat/Assets/tpp/pack/collectible/common/col_common_tpp.fpkd`) 2. This fox2 file has a `FxLocatorData` entity that points to said vfx file and has an `effectInstanceName` 3. With that, calling `TppDataUtility.CreateEffectFromId` with the `effectInstanceName` should load in said effects ### `wiki:wiki/FoxKit.md` FoxKit is a general-purpose Fox Engine data editor, which includes features such as importing, exporting, and creat new AI routes utilizing TppRouteSet or Routes. (.[frt](/FRT "wikilink")) Most existing materials referencing FoxKit concern FoxKit-1, including the following guides. A successor, FoxKit-3 (following a short-lived FoxKit-2 test project), is under active development. To learn more, or to contribute to FoxKit-3's development, please visit our Discord. FoxKit-1 works by wrapping FoxLib's importers into ScriptedImporters which is handled automatically by Unity. FoxKit reads the project's directory structure and mimics the game's directory structure. Installation procedures and a basic modification tutorial can be referenced [here.](/FoxKit-_Installing_Import_Files_and_Terrain "wikilink") {:.small} ### `wiki:wiki/FoxTool.md` FoxTool is an open-source Fox Engine XML compiler/decompiler for Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain created by Atvaark. It is capable of reading the data from compiled XML files and converting them back into standard XML files, where users may read and edit them. It can also do the opposite, converting standard XML files into compiled XML files. ##### Usage To decompile a compiled XML, the user simply needs to drag the file onto FoxTool. To compile a decompiled XML, the user simply needs to drag the .xml file onto the tool. ##### Supported Formats The following is a list of all formats compatible with FoxTool: - .bnd - .clo - .des - .evf - .fox2 - .fsd - .lad - .parts - .ph - .phsd - .sdf - .sim - .tgt - .vdp - .veh - .vfxlf ##### Dictionary FoxTool utilizes a dictionary of filenames called fox_dictionary.txt. As it decompiles the fox2, it compares the hashes generated from this dictionary to any hashed string literals it finds. If it finds a match, it will output the string by it's real name. If it cannot find a match, it will output the string by its hashed name. ### `wiki:wiki/Foxkit-_StaticModel_and_GeoxCollisionFreeShape.md` Guide for FoxKit 1.0. This guide will show how to add a simple model in Unity and test it ingame working with the Entity StaticModel. It will show another Entity that might be useful for some that add a small collision shape with eight points. #### Setting the Mod Folder Before anything else, let's create a folder structure for the Mod we will call as "LoadingStairsInGame". Do it outside of Unity FoxKit for now. **LoadingStairsInGame/Assets/tpp/pack/location/afgh/pack_common/...** Inside the pack_common should have two packages. **FoxPackage afgh_common_fpk** -\> Where the assets, models, routes, geoms... **FoxPackage Data afgh_common_fpkd** -\> The data, fox2 files, lua, scripts, effects... ![](/assets/FolderEstrutura01.jpg){:width="563px"} Inside the fpk folder we will add the StaticModel in: **afgh_common_fpk/Assets/tpp/environ/object/afghanistan/house/afgh_hous032/scenes/** copy and paste the fmdl and geom if have it. ![](/assets/FolderEstrutura02.jpg){:width="561px"} Inside the fpkd folder we will add the fox2 file, but for now all we need is set the folder path because we will generate the fox2 file in Unity. **afgh_common_fpkd/Assets/tpp/level/location/afgh/block_common/** Copy this folder structure in Unity. It should be like the image below. No need to copy the fpk if the user already load the assets in the guide [FoxKit: Installing, Import Files and Terrain](/FoxKit-_Installing_Import_Files_and_Terrain "wikilink"). ![](/assets/FolderEstrutura03.jpg) Done. We have the mod ready to makebite and the folder in Unity. ##### **Creating a Fox2 file** In Assets folder Unity create a Package Definition at menu **Unity Assets/Create/FoxKit/Package Definition**. Name it as afgh_common. The type of this package will be fpkd as stantard. Open the Data List Window in Menu **Unity FoxKit/Data List Window**. Place that new window whatever you want. At this window, hit **Create/DataSet.** ![](/assets/Package01.jpg) Choose the Package Definition, Type DataSet and the name can be whatever you think about. I go silly and name it MyFirstFox2File. Before hitting the button **create,** it's highly recommend select the folder where you think it should create the .asset otherwise it will create in /Assets. We want to generate the dataset in /**Assets/tpp/level/location/afgh/block_common/** and not **/Assets.** This is not a bug, but a matter of organize. After that, you shall see the Data List with one Entity called TexturePackLoadConditioner0000. ![](/assets/Unity001.jpg){:width="565px"} Good. Now we are ready to throw a lot of entities in there, but let's stick with the StaticModel. ##### **Entity StaticModel** There are two ways to add this entity. A Horrible way and a Best Way. ###### **Horrible Way** At Data List Window hit create/Entity. A new window with tons of entities will be listed. Dont get distracted, search for StaticModel and choose it. ![](/assets/StaticModel01.jpg){:width="502px"} Now the DataSet have a staticmodel. It can be renamed to anything else, but once renamed it should close and open again the dataset to update in Hierarchy Window. Look the Entity Window now and fill the modelfile and geomfile with the model we choose at the begin of this guide. You can drag and drop it too. The model still not show in Scene View because as we saw, we are doing the Horrible Way. Close and Open again the DataSet. And move the staticmodel to the place you want in Game. ![](/assets/StaticModel02.jpg){:width="534px"} ###### **Best Way** Just go to the model you want and Drag Drop to scene view. It will add it to the DataList with the name of the staticmodel. Its the fast way to add staticmodel, but there is a annoying thing to keep in mind. First, as long you drop the fmdl to scene view it will load far away from the camera because it doesn't recognize the terrain as some support point. But don't move the fmdl with the afgh_hous032_star001 as blue in Hierarchy Window. First, empty the local transform position to X:0, Y:0, Z: 0 and then select the afgh_hous032_star001_0000 to actual move the staticModel. ![](/assets/StaticModel03.jpg){:width="594px"} Let's repeat this process... It should be easy and fast to go around. ![](/assets/StaticModel04.jpg) Move the StaticModel to where we want and avoid adding any value inafgh_hous032_star001 prefab. The reason why not edit in there is because it will not be save the rotation if you close the dataset and because the values are not the same ingame. I recommend try to edit it and do mistakes by yourself to learn. ![](/assets/StaticModel05.jpg){:width="572px"} Lastly, don't forget to add the geom file in Entity Window. A Interesting fact to keep in mind is.. If you drag and drop the staticmodel in dataSet. If close and open again it will not shown the prefab anymore and then this issue will not be annoying anymore. It's good to do it if there is just a few models to spawn. But if it's thousand... ###### **Rotation** Let's rot this piece of StaticModel\! It's easy, but once you rotation the value at the Inspector Window does not add automatic to the Entity Window. This is a small bug the current foxkit have. Just copy and paste. Don't forget to do it otherwise ingame... ![](/assets/StaticModel06.jpg){:width="579px"} ##### **Exporting DataSet** Go to Data List Window, select the Dataset and hit right button mouse to show the options. Remember to set active if not otherwise it wont export. ![](/assets/Exportdataset01.jpg) Go to the Mod Folder we did at the begin. Precisely the fpkd folder. **LoadingStairsInGame/Assets/tpp/pack/location/afgh/pack_common/afgh_common_fpkd/Assets/tpp/level/location/afgh/block_common/** And save the file in it. ![](/assets/Exportdataset02.jpg){:width="584px"} Done. Now test it. Do the .mgsv file in Makebite building the **LoadingStairsInGame folder.** Open with Snakebite and see it in game. One thing to remember. Save a scene in Unity. When exit the software, don't forget to close the DataSet in Data List Window. It may cause issues after you open again FoxKit with any DataSet still hangout in DataListWindow. ![](/assets/AssetInGame.jpg){:width="587px"} ###### **Entity GeoxCollisionFreeShape** This Entity add a small collision with eight points. Good if the geometry of the model is just a square or something simple. Let's take the StaticModel Staris we did and to a collision after the end of the Stairs. Check the sketch of the idea. ![](/assets/SketchGeox.jpg){:width="602px"} Open Unity and the DataSet we work before. Open the Entity List and search for **GeoxCollisionFreeShape.** In the Entity Window we see this: ![](/assets/GeoxCollision01.jpg){:width="591px"} 1 - One is of course the transform positions, scale, rotations. Hit Create TransformEntity and it will drop the Entity in Hierachy Window next to the Stairs. 2 - CollisionCategory **All** means all. I don't know what means **Chara** and **Recoil**. **All** works fine. 3 - CollisionMaterial is greyed here. Currently not a option to edit in FoxKit 1.0. That we'll edit later manually using Fox2 tool to generate a xml. MTR_NONE_A is a good choice. The user can find more types in 4 - Tags. CHARA, PLAYER and ENEMY. 5 - This eight points will be parented with the TransformEntity of **GeoxCollisionFreeShape.** ###### **TransformEntity** After you create the TransformEntity, set pivot/local. Rotation to be according with the staticModel Stairs. Copy the rotation in Inspector Window to the Entity Window as we talk about that foxkit don't to this automatic. Move the **GeoxCollisionFreeShape** to where you think you'll start the shape we planned. ![](/assets/GeoxCollision02.jpg){:width="600px"} Create a Cube and drop inside the GeoxCollisionFreeShape0000. Erase the coords to 0,0,0 and scale it to 0.3,0.3, 0.3. This cube will be our First Point. ![](/assets/GeoxCollision03.jpg){:width="606px"} Create then more Seven Cubes and start to move then according to the Idea we sketch. It must be in that order. 1, 2, 3 and 4. Then 5, 6, 7 and 8. ![](/assets/GeoxCollision04.jpg) Add the tags. ![](/assets/GeoxCollision05.jpg) Now.. Every Point we did with cubes we will copy the Positions to the Entity Window. ![](/assets/GeoxCollision06.jpg){:width="597px"} Done. Export the Dataset as we learn in previously with StaticModel. But now we need to edit manually the Fox2 File. Let's navigate to the Fox2 we build and with the FoxTool, extract it to XML. Open it with notepad++ or any editor that work. ![](/assets/Foxtooll01.jpg){:width="589px"} Search for CollisionMaterial and add MTR_NONE_A or any type you may find interesting in that list. Save and double click the xml to pack again in Fox2 file otherwise it wont load in game. ![](/assets/Foxtooll02.jpg) Done. Now test it. Do the .mgsv file in Makebite building the **LoadingStairsInGame folder.** Open with Snakebite and see it in game. ![](/assets/ColissionSucess.jpg){:width="717px"} ### `wiki:wiki/Foxkit-_TppSharedGimmickData.md` Guide for FoxKit 1.0. This guide assumes that the user already knows how to work with FoxKit and understand Datasets/ fox2 files and the mod folder structure. Please see [FoxKit: Installing, Import Files and Terrain](/FoxKit-_Installing_Import_Files_and_Terrain "wikilink") and [FoxKit: StaticModel and GeoxCollisionFreeShape](/FoxKit-_StaticModel_and_GeoxCollisionFreeShape "wikilink") ##### **Beginning** Entity that works with lba files. (Locator Binary Array). Location data used to place gimmicks that is a little bit different then the **TppPermanentGimmickData.** This entity transforms a model as something that becomes alive, animated, breakable, falling by gravity. A static model of a chair, if not loaded by lba files, will be just a static model that won't fall if player touches it. Or a box that without lba it won't break if a grenade blows up near. Cloth will not swing around without lba. The game has a limit of how many lba should be spawned in free roam mission. Luckily, if the user does a new custom mission or location the limit can raise to up more than hundreds of lba working without crashing the game. This guide will only spawn two Gimmicks in the free roam mission as a good start to understand how to load lba files. Each location pack_common gimmick have **TppGimmickImmediateStateData** and other types of entities that set a kind of limit of gimmicks the location will have. The guide will load two Gimmicks. A Chair and a Flag/Banner. The first thing to do is build a mockup assets in Unity with a simple Dataset that will not be inside MOD. The purpose of creating this fox2 file is to get the Positions and Rotations of the model to copy/paste into lba files. We do it because FoxKit can not load lba files just yet. Create a Dataset named "MockupGimmicks" and build a small assets scene. I did this: ![](/assets/Mockup01.jpg){:width="742px"} We'll see this Fox2 later. ##### **TppSharedGimmickData list** Very important list to query the values that we will need later. **numDynamicGimmick** It does need more info about this one. Not sure what it means other than value 0 does not do nothing. The highest number founded was 22 from cable gimmick. The majority of gimmicks only need 1 or 2. **flags** Every gimmick will have a first flag and a second flag. Notice that flag2 will have value 0 for the mostly gimmicks. Some have more than one number in flag1 that it will depend of which model is been loaded. Barbwire has three types of staticmodel and therefore has three flags1 that cause a specific behavior. But, this still needs more information. It's a lot of time to look at each one and it will be a pleasure to anyone who tries to test each and note what happens in-game.
Query list of gimmicks, numDyn and flags

name

numDynamicGimmick

flags1

flags2

alarm_lamp

3

603980296

0

ashtray

1

267

0

barricade

3/ 5

16642

258

0

barbwire

2

16781568

256

16777472

0 8192

barrel

1

262400

0

basket

2

267

0

bed

1

262400

0

book

5

267

0

bottle

1/ 4

282

0

bucket

1/ 2/ 3

267

536871185

0

cable

6/ 16/ 22

274

3145993

67109138

0 64

can

1

267

0

carton

2

267

0

chair

1/ 2/ 3

267

0

chandelier

1

285

0

cloth

2/ 3

259

0

cloth inhouse

1

536870915

0

communicator

1

3145993

0

cup

1/ 2

282

0

desk

2

2147483904

0

dish

1/ 2/ 3/ 4

267

0

drum white/blue

2

270

0

drum red

2

260

0

normal drum

2/ 4

1049119

0

flag/banner

2/ 7

603980035

0

fence

3/ 4

259

16781568

16777478

16777486

16777497

281

0

gas_cylinder

2

267

0

gunny_sack

1

273

0

house window

1/ 2/ 3

261

0

hut

1

262

2147483910

298

0 524288

ladder

1

297

0

lamp

3

1573397

0

light

1

3146249

3146250

0

med_equip

1

267

0

net

1

259

0

pot

1

267

278

0

radio

1

24

267

0

roadcone

2

267

0

sandbag

1

34

0

signboard

1

16777486

303

0

stairs

1

2147483904

0

sunshade

2

3

603979779

0

tank

2/ 3

267

0

television

1

261

0

tent

2/ 3

3

259

0 2

timber

1

262

0

tin_wall

1

16777486

0

tire

6

267

0

tree

2

270

0

tool

4

267

0

tub

1

267

0

utility_pole

1/ 2

284

0

wall

2

2

0

window

2

261

603979779

0

wood_box

1/ 6

256

0

wood_box gntn

5

262400

0

wood_box/mafr_desk001

1/ 2/ 3

2147483904

0 65536

##### **LbaTool** Download here. Find the lba for **afgh_char002** and **afgh_flag001** and paste in **afgh_common_fpk/Assets/tpp/level/location/afgh/block_common/lba** or in a place you know better for it in your project. The path folder I choose here is because we are working to spawn in free roam AFGH location pack_common. If we're in a side-op it probably would be in Sideop_fpk/Assets/tpp/level/mission2/quest/ih/lba. Open the **afgh_char002** and **afgh_flag001** outside of Unity with the LbaTool. Remember the mockupGimmick we did later and open the file too. Erase the content afgh_char002.lba we have at the start, including the dataset path. **locator name of chair:** afgh_char002_gim_n0000|srt_afgh_char002 **locator name of flag:** afgh_flag001_gim_n0000|srt_afgh_flag001 If you want to add more than one locator, just increase the ...**gim_n0000|** to **gim_n0001|**, **gim_n0002|** and so on. Copy position and rotation from the mockupGimmick to the lba file and save. Example afgh_char002: ![](/assets/Gimmick01.jpg){:width="578px"} Do the same for **afgh_flag001.** Notice that **dataset="path"** will be our fox2file where we'll add the Entity **TppSharedGimmickData.** So, once we finish exporting the main fox2 file, we will add the dataset path in lba file again and repack with the tool. ###### **Entity TppSharedGimmickData** Create a new DataSet and drop two Entities **TppSharedGimmickData.** One for the Chair and another for Flag/Banner we planned. **afgh_char002** ![](/assets/Mockup02.jpg){:width="552px"} **modelFile** Just add the model of afgh_char002.fmdl here **geomFile** Just add the geom of afgh_char002.geom here **breakedModelFile and breakedGeomFile** Some models like box, wood desk, wall have a second fmdl and geom for pieces that will of course end the break animation and result in a visual broke of the first model. It's funny that you can add anything here and make the break quite interesting visually. **partsFile** Model needs a part file to load ph, target and effects. Remember to add the files and path in Unity and Mod Folder. **numDynamicGimmick** As we talk about at the beginning of this guide. Need more information about. **locaterFile** lba files will be in every fpk folder. Precisely in /Assets/tpp/level folder. In our case we are using afgh_common_fpk. So the location for it will be is **/Assets/tpp/level/location/afgh/block_common/lba.** Make sure to add it later in Unity and Mod Folder. **flags1** Please see the QueryList. It's not clear what this flags actually means. Needs more information. **flags2** Please see the QueryList. It's not clear what this flags actually means. Needs more information. Do the same for the afgh_flag001. Export the Fox2 file to the fpkd of our Mod Folder. You can now delete the mockupGimmick. It's important that this fox2 file we did just to take the positions and rotations for lba files not load in the Mod. Look that I'm using the same mod from the previously guides. Every mod can have tons of fox2 file that deals with something in specific. ![](/assets/Gimmick02.jpg){:width="542px"} We need to edit manually the MyThirdFox2File in xml to add the flag number and of course check if the paths are correctly done. Remember now to check the QueryList and choose the best flag. ![](/assets/Gimmick03.jpg){:width="512px"} Save and pack the fox2 file. ###### **Last steps...** ###### **Lba files** Back to the lba files and now let's add the dataset path. Save, pack with the LbaTool and copy/paste for our Mod Folder in **fpk/Assets/tpp/level/location/afgh/block_common/lba** or the path you choose in **TppSharedGimmickData.** ![](/assets/Gimmick04.jpg){:width="557px"} ![](/assets/Gimmick05.jpg){:width="566px"} ###### **Models, motions and parts files** We need to add to our mod folder the fmdls, geoms, parts and motion of our chair and flag. Motion is only about the flag. Sometimes a lba will need a effect too. To know which effect and motion to add to our project, look inside the parts file of the model and everything will be there. **Fmdl and Geoms** ![](/assets/Gimmick06.jpg){:width="428px"} **Motion** ![](/assets/Gimmick07.jpg){:width="410px"} **Parts** Notice that parts goes to fpkd folder, not fpk. ![](/assets/Gimmick08.jpg){:width="431px"} Done. Now test it. Make the .mgsv file in Makebite building the **LoadingStairsInGame folder.** Open with SnakeBite and see it in game. Unfortunately due to the limits of Free Roam. Only one TppSharedGimmick was spawned. The flag works at least. {:.thumb} ### `wiki:wiki/FsmTool.md` FsmTool is open-source unpacker and repacker for Metal Gear Solid V: The Phantom Pain's .fsm files written by BobDoleOwndU. The tool can extract the DEMO and SND chunks from .fsm files. Additionally, when extracting SND chunks, the tool automatically builds them into a Wwise sound file (.wem). ##### Usage To unpack a .fsm, a user simply needs to drag and drop a .fsm onto the tool. The tool will output the extracted chunks into a folder named *\_fsm* along with a .xml file documenting the contained chunks. A .wem file built from the file's SND chunks will also be inside the folder containing the chunks. To repack a .fsm file, the user needs to drag an output .xml file onto the tool. The tool will read the file list from the .xml and repack the .fsm file based on that list. ### `wiki:wiki/FvTwool.md` FvTwool provides a simple, standalone interface for modying [FormVariation2](\FV2) files. ### `wiki:wiki/Fx_nodes.md` There are a large number of nodes used in [VFX](/VFX "wikilink") files, although not all of them have been discovered yet. Each has its own set of parameters, which are written in .vfx files in alphabetical order. Please add new nodes as you discover them. Also be sure to list a file in which that node can be found. ##### FxModuleGraph There is a single instance of this node in each .vfx file, and it is the output of the graph. - allFrame (uint32) - boundingBoxOffsetPos (Vector3) - boundingBoxOffsetSize (Vector3) - boundingBoxType (int) - debugInfo (bool) - effectName (uint64) - executionPriorityType (int) - fadeInEndFrame (uint32) - fadeOutStartFrame (uint32) - playMode (int) - updateType (int) ##### FxIntervalProbabilityEmitNode Example: fx_tpp_splbrdwng01_s1.vfx - delayFrame (uint32) - delayFrameRandomRange (uint32) - emitVersion (int32) - fadeOutPosition (float) - fadeOutReverse (bool) - intervalFrame (uint32) - lifeFrame (uint32) - lifeRandomRangeFrame (uint32) - numMax (uint32) - numMin (uint32) - probability (float) - randomGatherSeedValue (uint32) - randomGatherType (int32) - receiveName (string) ##### FxConstLifeNode Example: fx_tpp_splbrdwng01_s1.vfx - lifeFrame (uint32) ##### FxRandomVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - force (float) - global (bool) - globalEvaluateRealTimeRootRotate (bool) - randomGatherSeedValue (uint32) - randomGatherType (int32) - randomMax (Vector4) - randomMin (Vector4) - vectorType (int32) - xySquere (bool) ##### FxConstVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - force (float) - global (bool) - vector (Vector4) - vectorType (int32) ##### FxColorVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - color (Vector4) ##### FxUniformVelocityVectorNode Example: fx_tpp_splbrdwng01_s1.vfx (No parameters) ##### FxUniformVelocityTimeVectorNode Example: fx_tpp_splbrdwng01_s1.vfx (No parameters) ##### FxDragTimeVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - drag (float) - method (int32) - scale (float) ##### FxCompositionVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - maskValue (float) - secondMaskW (bool) - secondMaskX (bool) - secondMaskY (bool) - secondMaskZ (bool) ##### FxOscillateVector2Node Example: fx_tpp_splbrdwng01_s1.vfx - periodicity (bool) ##### FxMultiplyVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - maskValue (float) - secondMaskW (bool) - secondMaskX (bool) - secondMaskY (bool) - secondMaskZ (bool) ##### FxPlaneRotShapeNode Example: fx_tpp_splbrdwng01_s1.vfx - autoBoundingBoxMargin (Vector4) - axisFix (int32) - axisFixParticleDirectionPoolName (string) - baseRot (Quaternion) - baseSizeScale (float) - boundingBoxType (int32) - centerU (float) - centerV (float) - cullFace (bool) - enable (bool) - localSpace (bool) - manualBoundingBoxOffset (Vector3) - manualBoundingBoxSize (Vector3) - numSimulatedMaxParticle (uint32) - rotGlobal (bool) - rotateOrderType (int32) - sortMode (int32) - sortOffset (float) ##### FxLightInfluenceMaterialNode Example: fx_tpp_splbrdwng01_s1.vfx - ambientRate (float) - cameraFadeInFar (float) - cameraFadeInNear (float) - cameraZOffset (float) - directionalLightRate (float) - opaque (bool) - pointLightRate (float) - receiveShadowMap (bool) - shaderType (int32) - softBlend (bool) - softBlendFactor (float) - textureAnimeBlend (bool) - textureAnimeBlendFrame (float) - textureAnimeBlendHeight (uint32) - textureAnimeBlendWidth (uint32) - textureAnimeClamp (bool) - textureAnimeRandomStart (bool) - textureFile (string) ##### FxTimeScaleVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - endScale (float) - maskW (bool) - maskX (bool) - maskY (bool) - maskZ (bool) - startScale (float) ##### FxUVMapRandomVectorNode Example: fx_tpp_splbrdwng01_s1.vfx - randomDivisionHeightGrid (uint32) - randomDivisionWidthGrid (uint32) - randomFlipU (bool) - randomFlipV (bool) - randomGatherSeedValue (uint32) - randomGatherType (int32) ##### FxDynamicLuminanceMaterialNode Example: fx_tpp_flrrbw01_s5.vfx - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownUint2 (uint32) - unknownUint3 (uint32) - unknownBool0 (bool) - unknownString0 (string) - unknownFloat0 (float) - unknownFloat1 (float) - unknownFloat2 (float) - unknownFloat3 (float) - unknownBool1 (bool) - unknownUint4 (uint32) - unknownFloat4 (float) - unknownFloat5 (float) - unknownUint5 (uint32) - unknownUint6 (uint32) - unknownBool2 (bool) - unknownBool3 (bool) - unknownString1 (string - texture file path) ##### FxUVMapVectorNode Example: fx_tpp_flrrbw01_s5.vfx - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownBool0 (bool) - unknownBool1 (bool) - unknownVector0 (Vector4) ##### FxSpriteRotShapeNode Example: fx_tpp_flrrbw01_s5.vfx - unknownVector0 (Vector4) - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownUint2 (uint32) - unknownBool0 (bool) - unknownBool1 (bool) - unknownBool2 (bool) - unknownVector1 (Vector4) - unknownVector2 (Vector4) - unknownUint3 (uint32) - unknownBool3 (bool) - unknownBool4 (bool) - unknownUint4 (uint32) - unknownUint5 (uint32) ##### FxInfinityLifeNode Example: fx_tpp_flrrbw01_s5.vfx - unknownUint0 (uint32) ##### FxRandomLifeNode Example: fx_tpp_flrrbw01_s5.vfx - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownUint2 (uint32) - unknownUint3 (uint32) ##### FxFirstLoopOnlyEmitNode Example: fx_tpp_flrrbw01_s5.vfx (No parameters) ##### FxKeyframeVectorNode Example: fx_tpp_flrrbw01_s5.vfx Notes: Some of the float parameters have been observed to be arrays. Observed sizes include 2 and 4. - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownUint2 (uint32) - unknownUint3 (uint32) - unknownUint4 (uint32) - unknownUint5 (uint32) - unknownUint6 (uint32) - unknownFloat0 (float) - unknownFloat1 (float) - unknownFloat2 (float) - unknownFloat3 (float) - unknownFloat4 (float) - unknownFloat5 (float) - unknownUint7 (uint32) - unknownFloat6 (float) ##### FxLodVectorNode Example: fx_tpp_flrrbw01_s5.vfx - unknownFloat0 (float) - unknownFloat1 (float) - unknownFloat2 (float) - unknownFloat3 (float) - unknownFloat4 (float) ##### FxUniformAccelVectorNode Example: fx_tpp_chrquifotsmk01_s1.vfx (No parameters) ##### WindFxVectorNode Example: fx_tpp_chrquifotsmk01_s1.vfx - unknownFloat0 (float) - unknownBool0 (bool) - unknownUint0 (uint32) ##### FxUVAnimeIntervalVectorNode Example: fx_tpp_chrquifotsmk01_s1.vfx - unknownFloat0 (float) - unknownBool0 (bool) - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownBool1 (bool) - unknownBool2 (bool) - unknownBool3 (bool) - unknownBool4 (bool) - unknownUint2 (uint32) - unknownUint3 (uint32) - unknownBool5 (bool) ##### FxCameraCorrectionVectorNode Example: fx_tpp_chrwmueye01_s0.vfx - unknownFloat0 (float) - unknownUint0 (uint32) - unknownFloat1 (float) - unknownBool0 (bool) - unknownUint1 (uint32) - unknownFloat2 (float) - unknownFloat3 (float) - unknownFloat4 (float) - unknownFloat5 (float) ##### TppLensFlareShapeNode Example: fx_tpp_chrwmueye01_s0.vfx - unknownVector0 (Vector4) - unknownUint0 (uint32) - unknownUint1 (uint32) - unknownBool0 (bool) - unknownDouble0 (double) - unknownString0 (string - appears to be a .vfxlf path, sans path and extension) - unknownBool1 (bool) - unknownVector1 (Vector4) - unknownVector2 (Vector4) - unknownUint2 (uint32) - unknownString1 (string) - unknownBool2 (bool) - unknownFloat0 (float) ##### FxReceiveVectorNode Example: fx_tpp_chrwmueye01_s0.vfx - unknownBool0 (bool) - unknownVector0 (Vector4) - unknownFloat0 (float) - unknownBool1 (bool) - unknownBool2 (bool) - unknownBool3 (bool) - unknownBool4 (bool) - unknownBool5 (bool) - unknownBool6 (bool) - unknownString0 (string - appears to be a name; the two in fx_tpp_chrwmueye01_s0 were "headPosition" and "Size", respectively. This could be a way to interface with DataSet classes, however, no property of name "size" is listed in fx_tpp_flrlnswmueye01_s2VG.vfxlf.) ##### FxTrailShapeNode Example: fx_tpp_chrwmueye01_s0.vfx - unknownFloat0 (float) - unknownBool0 (bool) - unknownUint0 (uint32) - unknownFloat1 (float) - unknownFloat2 (float) - unknownUint1 (uint32) - unknownVector0 (Vector4) - unknownFloat3 (float) - unknownUint2 (uint32) - unknownBool1 (bool) - unknownUint3 (uint32) - unknownUint4 (uint32) - unknownBool2 (bool) - unknownVector1 (Vector4) - unknownVector2 (Vector4) - unknownUint5 (uint32) - unknownUint6 (uint32) - unknownBool3 (bool) - unknownUint7 (uint32) - unknownBool4 (bool) - unknownUint8 (uint32) - unknownUint9 (uint32) ##### FxSpriteShapeNode Example: fx_tpp_chrwmueye01_s0.vfx - unknownVector0 (Vector4) - unknownUint0 (uint32) - unknownFloat0 (float) - unknownFloat1 (float) - unknownBool0 (bool) - unknownBool1 (bool) - unknownBool2 (bool) - unknownVector1 (Vector4) - unknownVector2 (Vector4) - unknownUint1 (uint32) - unknownUint2 (uint32) - unknownUint3 (uint32) ### `wiki:wiki/GANI.md` Generic Animation file, stored in [MTAR](/MTAR/). Stock file descriptions: [Link](https://github.com/chocmake/chocmake.github.io/tree/main/guides/mgsv-adding-player-motions/files/gani-descriptions) ###### Resources [010 Editor Template](https://github.com/kapuragu/FoxEngineTemplates/blob/main/gani.bt) ###### See also [MTAR](/MTAR/). ### `wiki:wiki/GRXLA.md` **GrxLA**, or **Grx** **L**ight **A**rray, is a file format used by Metal Gear Solid V: Ground Zeroes, The Phantom Pain and Metal Gear Survive to store light entity data, such as Light Probes, Point Lights, Spotlights and in similar .grxoc files, Occluder Arrays. .grxla files can either only have Light Probe entries or Point Light and Spotlight entries, and .grxoc files can only have an Occluder Array entry. The PC version's format is Little-Endian, meaning bytes are written in reverse order of significance. ##### Format ###### Header - 0x0-0x3 - Signature. "FGxL" in .grxla files and "FGxO" in .grxoc. - 0x4-0x7 - Always empty. - 0x8-0xB - Header size? Always 10. - 0xC-0xF - Always 1. ###### Entries Entries are listed arbitrarily with no set count. They always start with a "CM00" DataSet Path entry and end with an empty null eight byte long entry. - 0x0-0x3 - Entry type. - 0x4-0x7 - Entry size. The following is part of the entry depending on the Entry Type: ###### DataSet Entry: "CM00" The DataSet entry appears as the first entry of every .grxla and .grxoc file. It defines the path to the .fox2 DataSet file that has the LightArray, TppLightProbeArray or OccluderArray class entity that loads the .grxla or .grxoc file with a path to it. The ulong values are different between files and all of them are unknown, and they are most likely arbitrary names of the array. - 0x0-0x7 - An unknown uint64 hash, different for all files. Most likely not important. - 0x8-0xB - Always 8. Local offset to string? - 0xC-0xF - Always 0. - 0x10 - Null-terminated string path to the .fox2 that uses the file. If the string's length including the null terminator byte aren't divisible by 4, then the remainder to the next byte count divisible by 4 will be padded out to with zeroes. ###### Array Terminator Entry: "" This is the entry at the end of every .grxla and .grxoc file. Seeing how light arrays don't define an array entry count, this entry is most likely for signifying that the array has ended. It only contains the entry type (4 zero bytes) and the entry size (8 bytes, including the entry type and entry size). ###### Directional Light : "DL00" This entry is never seen in binary files in the wild, but is mentioned in the .exe. ###### Point Light: "PL01," "PL02" and "PL03" These entries define point lights. There are three versions - PL01 is never seen in binary files in the wild and only mentioned in the .exe, PL02 is only used in Ground Zeroes but can still work in The Phantom Pain and PL03 is used in The Phantom Pain and beyond. - 0x0-0x7 - StrCode64 hash of the light name. The string is listed later in PC files. - 0x8-0xB - Local offset to the string of the light name. PS3 TPP files don't use strings, so these offsets are empty. - 0xC-0xF - Unknown flags. - 0x10-0x13 - Light flags. 0x1 is Enable, 0x2 is Cast Shadow, 0x8 is Has Specular, and there are many more. - 0x14-0x17 - Unknown flags. - 0x18-0x1B - Local offset to Light Area. Lights that don't use a Light Area have this value as 0. - 0x1C-0x1F - Translation X float. - 0x20-0x23 - Translation Y float. - 0x24-0x27 - Translation Z float. - 0x28-0x29 - Reach point X half float. - 0x2A-0x2B - Reach point Y half float. - 0x2C-0x2D - Reach point Z half float. - 0x2E-0x2F - Color Red half float. - 0x30-0x31 - Color Green half float. - 0x32-0x33 - Color Blue half float. - 0x34-0x35 - Color Brightness half float. - 0x36-0x37 - Temperature half float. - 0x38-0x3B - Color deflection float. - 0x3C-0x3F - Lumen float. - 0x40-0x41 - Light size half float. - 0x42-0x43 - Dimmer half float. - 0x44-0x45 - Shadow bias half float. - 0x46-0x47 - LOD far size half float. - 0x48-0x49 - LOD near size half float. - 0x4A-0x4B - LOD shadow draw rate half float. - 0x4C-0x4F - LOD radius level uint. - 0x50-0x53 - LOD fade type uint. - 0x54-0x57 - Local offset to irradiation point. Entries that don't have an irradiation point have the value as 0. If the String Offset isn't 0: - 0x0 - Null-terminated string name of the light. If the string's length including the null terminator byte aren't divisible by 4, then the remainder to the next byte count divisible by 4 will be padded out to with zeroes. If the Offset to Light Area isn't 0: - 0x0-0x3 - Light area scale X float. - 0x4-0x7 - Light area scale Y float. - 0x8-0xB - Light area scale Z float. - 0xC-0xF - Light area rotation quaternion X float. - 0x10-0x13 - Light area rotation quaternion Y float. - 0x14-0x17 - Light area rotation quaternion Z float. - 0x18-0x1B - Light area rotation quaternion W float. - 0x1C-0x1F - Light area translation X float. - 0x20-0x23 - Light area translation Y float. - 0x24-0x27 - Light area translation Z float. If the Offset to Irradiation Point isn't 0: - 0x0-0x3 - Irradiation point scale X float. - 0x4-0x7 - Irradiation point scale Y float. - 0x8-0xB - Irradiation point scale Z float. - 0xC-0xF - Irradiation point rotation quaternion X float. - 0x10-0x13 - Irradiation point rotation quaternion Y float. - 0x14-0x17 - Irradiation point rotation quaternion Z float. - 0x18-0x1B - Irradiation point rotation quaternion W float. - 0x1C-0x1F - Irradiation point translation X float. - 0x20-0x23 - Irradiation point translation Y float. - 0x24-0x27 - Irradiation point translation Z float. ###### Spotlight: "SL01," "SL02" and "SL03" These entries define spotlights. There are three versions - SL01 is never seen in binary files in the wild and only mentioned in the .exe, SL02 is only used in Ground Zeroes but can still work in The Phantom Pain and SL03 is used in The Phantom Pain and beyond. - 0x0-0x7 - StrCode64 hash of the light name. The string is listed later in PC files. - 0x8-0xB - Local offset to the string of the light name. PS3 TPP files don't use strings, so these offsets are empty. - 0xC-0xF - Unknown flags. - 0x10-0x13 - Light flags. 0x1 is Enable, 0x2 is Cast Shadow, 0x8 is Has Specular, and there are many more. - 0x14-0x17 - Unknown flags. - 0x18-0x1B - Local offset to Light Area. Lights that don't use a Light Area have this value as 0. - 0x1C-0x1F - Translation X float. - 0x20-0x23 - Translation Y float. - 0x24-0x27 - Translation Z float. - 0x28-0x2B - Reach point X float. - 0x2C-0x2F - Reach point Y float. - 0x30-0x33 - Reach point Z float. - 0x34-0x37 - Rotation quaternion X float. - 0x38-0x3B - Rotation quaternion Y float. - 0x3C-0x3F - Rotation quaternion Z float. - 0x40-0x43 - Rotation quaternion W float. - 0x44-0x45 - Outer range half float. - 0x46-0x47 - Inner range half float. - 0x48-0x49 - Umbra angle half float. - 0x4A-0x4B - Penumbra angle half float. - 0x4C-0x4D - Attenuation exponent half float. - 0x4E-0x4F - Dimmer half float. - 0x50-0x51 - Color Red half float. - 0x52-0x53 - Color Green half float. - 0x54-0x55 - Color Blue half float. - 0x56-0x57 - Color Brightness half float. - 0x58-0x59 - Temperature half float. - 0x5A-0x5B - Color deflection half float. - 0x5C-0x5F - Lumen float. - 0x60-0x61 - Light size half float. - 0x62-0x63 - Shadow umbra angle half float. - 0x64-0x65 - Shadow penumbra angle half float. - 0x66-0x67 - Shadow attenuation exponent half float. - 0x68-0x69 - Shadow bias half float. - 0x6A-0x6B - View bias half float. - 0x6C-0x6D - Power scale half float. - 0x6E-0x6F - LOD far size half float. - 0x70-0x71 - LOD near size half float. - 0x72-0x73 - LOD shadow draw rate half float. - 0x74-0x77 - LOD radius level flags. - 0x78-0x7B - LOD fade type flags. - 0x7C-0x7F - Local offset to irradiation point. Entries that don't have an irradiation point have the value as 0. If the String Offset isn't 0: - 0x0 - Null-terminated string name of the light. If the string's length including the null terminator byte aren't divisible by 4, then the remainder to the next byte count divisible by 4 will be padded out to with zeroes. If the Offset to Light Area isn't 0: - 0x0-0x3 - Light area scale X float. - 0x4-0x7 - Light area scale Y float. - 0x8-0xB - Light area scale Z float. - 0xC-0xF - Light area rotation quaternion X float. - 0x10-0x13 - Light area rotation quaternion Y float. - 0x14-0x17 - Light area rotation quaternion Z float. - 0x18-0x1B - Light area rotation quaternion W float. - 0x1C-0x1F - Light area translation X float. - 0x20-0x23 - Light area translation Y float. - 0x24-0x27 - Light area translation Z float. If the Offset to Irradiation Point isn't 0: - 0x0-0x3 - Irradiation point scale X float. - 0x4-0x7 - Irradiation point scale Y float. - 0x8-0xB - Irradiation point scale Z float. - 0xC-0xF - Irradiation point rotation quaternion X float. - 0x10-0x13 - Irradiation point rotation quaternion Y float. - 0x14-0x17 - Irradiation point rotation quaternion Z float. - 0x18-0x1B - Irradiation point rotation quaternion W float. - 0x1C-0x1F - Irradiation point translation X float. - 0x20-0x23 - Irradiation point translation Y float. - 0x24-0x27 - Irradiation point translation Z float. ###### "LP00" This entry is never seen in binary files in the wild, but is mentioned in the .exe. ###### Light Probe: "EP00" These entries define light probes. - 0x0-0x7 - StrCode64 hash of the probe name. The string is listed later in PC files. - 0x8-0xB - Local offset to the string of the light name. PS3 TPP files don't use strings, so these offsets are empty. - 0xC-0xF - Unknown flags. - 0x10-0x13 - Light flags. 0x1 is Enable, 0x2 is Cast Shadow, 0x8 is Has Specular, and there are many more. - 0x14-0x17 - Unknown flags. - 0x18-0x19 - Inner scale X positive half float. - 0x1A-0x1B - Inner scale Y positive half float. - 0x1C-0x1D - Inner scale Z positive half float. - 0x1E-0x1F - Inner scale X negative half float. - 0x20-0x21 - Inner scale Y negative half float. - 0x22-0x23 - Inner scale Z negative half float. - 0x24-0x27 - Bounding box Scale X float. - 0x28-0x2B - Bounding box Scale Y float. - 0x2C-0x2F - Bounding box Scale Z float. - 0x30-0x33 - Bounding box Rotation quaternion X float. - 0x34-0x37 - Bounding box Rotation quaternion Y float. - 0x38-0x3B - Bounding box Rotation quaternion Z float. - 0x3C-0x3F - Bounding box Rotation quaternion W float. - 0x40-0x43 - Bounding box Translation X float. - 0x44-0x47 - Bounding box Translation Y float. - 0x48-0x4B - Bounding box Translation Z float. - 0x4C-0x4F - Unknown float. Translation W? - 0x50-0x51 - Priority short. - 0x52-0x53 - Shape type ushort. 0 - default square, 1 - triangular prism, 2 - semi-cylindrical, 3 - half-square. - 0x54-0x55 - Related light index from the list property in the .fox2's TppLightProbeArray. - 0x56-0x57 - Spherical harmonics data index from the list property in the .fox2's TppLightProbeArray. - 0x58-0x5B - Unknown float. Open occlusion mode? - 0x5C-0x5F - Unknown float. Always 0. If the String Offset isn't 0: - 0x0 - Null-terminated string name of the light. If the string's length including the null terminator byte aren't divisible by 4, then the remainder to the next byte count divisible by 4 will be padded out to with zeroes. ###### Occluder array entry: "OC00" - 0x0-0x3 - Unknown integer. - 0x4-0x7 - Local offset to faces array. - 0x8-0xB - Faces count. - 0xC-0xF - Local offset to vertices array. Always 8. - 0x10-0x13 - Vertices count. For every vertex: - 0x0-0x3 - Translation X. - 0x4-0x7 - Translation Y. - 0x8-0xB - Translation Z. - 0xC-0xF - Translation W, always 1.0. For every face: - 0x0-0x1 - Unknown index. - 0x2-0x3 - Unknown index. - 0x4-0x5 - First vertex index. - 0x6-0x7 - Vertex count. ### `wiki:wiki/GameObjectTypes.md` Game objects have their own types; object ids depend on them. To get object id range, shift type id to the left by 9. ID range for `Soldier2`, 1024-1536: ``` 2 << 9 = 1024 3 << 9 = 1536 ``` You can shift object id to the right by 9 and get a type: ``` 1056 >> 9 = 2 ``` ###### List Taken from `tpp::gm::impl::ExportTppGameObjectToLua`. ``` 0: GAME_OBJECT_TYPE_PLAYER2 1: GAME_OBJECT_TYPE_COMMAND_POST2 2: GAME_OBJECT_TYPE_SOLDIER2 3: GAME_OBJECT_TYPE_HOSTAGE2 4: GAME_OBJECT_TYPE_HOSTAGE_UNIQUE 5: GAME_OBJECT_TYPE_HOSTAGE_UNIQUE2 6: GAME_OBJECT_TYPE_HOSTAGE_KAZ 7: GAME_OBJECT_TYPE_OCELOT2 8: GAME_OBJECT_TYPE_HUEY2 9: GAME_OBJECT_TYPE_CODE_TALKER2 10: GAME_OBJECT_TYPE_SKULL_FACE2 11: GAME_OBJECT_TYPE_MANTIS2 12: GAME_OBJECT_TYPE_BIRD2 13: GAME_OBJECT_TYPE_HORSE2 14: GAME_OBJECT_TYPE_HELI2 15: GAME_OBJECT_TYPE_ENEMY_HELI 16: GAME_OBJECT_TYPE_OTHER_HELI 17: GAME_OBJECT_TYPE_OTHER_HELI2 18: GAME_OBJECT_TYPE_BUDDYQUIET2 19: GAME_OBJECT_TYPE_BUDDYDOG2, 20: GAME_OBJECT_TYPE_BUDDYPUPPY 21: GAME_OBJECT_TYPE_SAHELAN2 22: GAME_OBJECT_TYPE_PARASITE2 23: GAME_OBJECT_TYPE_LIQUID2 24: GAME_OBJECT_TYPE_VOLGIN2 25: GAME_OBJECT_TYPE_BOSSQUIET2 26: GAME_OBJECT_TYPE_UAV 27: GAME_OBJECT_TYPE_SECURITYCAMERA2 28: GAME_OBJECT_TYPE_GOAT 29: GAME_OBJECT_TYPE_NUBIAN 30: GAME_OBJECT_TYPE_CRITTER_BIRD 31: GAME_OBJECT_TYPE_STORK 32: GAME_OBJECT_TYPE_EAGLE 33: GAME_OBJECT_TYPE_RAT 34: GAME_OBJECT_TYPE_ZEBRA 35: GAME_OBJECT_TYPE_WOLF 36: GAME_OBJECT_TYPE_JACKAL 37: GAME_OBJECT_TYPE_BEAR 38: GAME_OBJECT_TYPE_CORPSE 39: GAME_OBJECT_TYPE_MBQUIET 40: GAME_OBJECT_TYPE_COMMON_HORSE2 41: GAME_OBJECT_TYPE_HORSE2_FOR_VR 42: GAME_OBJECT_TYPE_PLAYER_HORSE2_FOR_VR 43: GAME_OBJECT_TYPE_VOLGIN2_FOR_VR 44: GAME_OBJECT_TYPE_WALKERGEAR2 45: GAME_OBJECT_TYPE_COMMON_WALKERGEAR2 46: GAME_OBJECT_TYPE_BATTLEGEAR 47: GAME_OBJECT_TYPE_EXAMPLE 48: GAME_OBJECT_TYPE_SAMPLE_GAME_OBJECT 49: GAME_OBJECT_TYPE_NOTICE_OBJECT 50: GAME_OBJECT_TYPE_VEHICLE 51: GAME_OBJECT_TYPE_MOTHER_BASE_CONTAINER 52: GAME_OBJECT_TYPE_EQUIP_SYSTEM 53: GAME_OBJECT_TYPE_PICKABLE_SYSTEM 54: GAME_OBJECT_TYPE_COLLECTION_SYSTEM 55: GAME_OBJECT_TYPE_THROWING_SYSTEM 56: GAME_OBJECT_TYPE_PLACED_SYSTEM 57: GAME_OBJECT_TYPE_SHELL_SYSTEM 58: GAME_OBJECT_TYPE_BULLET_SYSTEM3 59: GAME_OBJECT_TYPE_CASING_SYSTEM 60: GAME_OBJECT_TYPE_FULTON 61: GAME_OBJECT_TYPE_BALLOON_SYSTEM 62: GAME_OBJECT_TYPE_PARACHUTE_SYSTEM 63: GAME_OBJECT_TYPE_SUPPLY_CBOX 64: GAME_OBJECT_TYPE_SUPPORT_ATTACK 65: GAME_OBJECT_TYPE_RANGE_ATTACK 66: GAME_OBJECT_TYPE_CBOX 67: GAME_OBJECT_TYPE_OBSTRUCTION_SYSTEM 68: GAME_OBJECT_TYPE_DECOY_SYSTEM 69: GAME_OBJECT_TYPE_CAPTURECAGE_SYSTEM 70: GAME_OBJECT_TYPE_DUNG_SYSTEM 71: GAME_OBJECT_TYPE_MARKER2_LOCATOR 72: GAME_OBJECT_TYPE_ESPIONAGE_RADIO 73: GAME_OBJECT_TYPE_MGO_ACTOR 74: GAME_OBJECT_TYPE_FOB_GAME_DAEMON 75: GAME_OBJECT_TYPE_SYSTEM_RECEIVER 76: GAME_OBJECT_TYPE_SEARCHLIGHT 77: GAME_OBJECT_TYPE_FULTONABLE_CONTAINER 78: GAME_OBJECT_TYPE_GARBAGEBOX 79: GAME_OBJECT_TYPE_IMPORTANT_BREAKABLE 80: GAME_OBJECT_TYPE_GATLINGGUN 81: GAME_OBJECT_TYPE_MORTAR 82: GAME_OBJECT_TYPE_MACHINEGUN 83: GAME_OBJECT_TYPE_DOOR 84: GAME_OBJECT_TYPE_WATCH_TOWER 85: GAME_OBJECT_TYPE_TOILET 86: GAME_OBJECT_TYPE_ESPIONAGEBOX 87: GAME_OBJECT_TYPE_IR_SENSOR 88: GAME_OBJECT_TYPE_EVENT_ANIMATION 89: GAME_OBJECT_TYPE_BRIDGE 90: GAME_OBJECT_TYPE_WATER_TOWER 91: GAME_OBJECT_TYPE_RADIO_CASSETTE 92: GAME_OBJECT_TYPE_POI_SYSTEM 93: GAME_OBJECT_TYPE_SAMPLE_MANAGER ``` ### `wiki:wiki/GeoTrap.md` ### `wiki:wiki/Ghidra_tips.md` Ghidra is a software reverse engineering (SRE) framework used by MGSV researchers to reverse engineer the game. Ask for access in [Modders' Heaven](https://discord.gg/3XwAsWV) discord. Don't hesitate to share information with others, we have the same goal - make the game even better. This page describes common techniques for working in collaboration with others. ##### Glossary Production exe = `msgvtpp.exe` Debug exe = `Tpp_main_win64.exe` ##### Starting After getting connection info on Discord, select the exe you are interested in and click on checkout button - the only active button on the panel. ![Checkout](/assets/Ghidra_tips/checkout1.png) That will download the file and set you into checkout mode. Do not drag the unchecked file into decompiler window - Ghidra will do something weird instead, slowly analyzing the file every time you do it. After checking out do whatever you wanted to do. After finishing you can check in the file or undo the checkout. ![Undo checkout](/assets/Ghidra_tips/checkout2.png) Undoing the checkout will cause Ghidra to forget about the data you downloaded. If you made some changes, saved them and have a write access, a new version of the file will be created by checking in (indicated by number and asterisk in parentheses in project window). ![Check in](/assets/Ghidra_tips/checkin.png) If you've made a mistake and realized that after saving the file (but before checking in), undo the changes by undoing checkout. You cannot revert changes in tool window (with Ctrl+Z) after saving the file. Consult Ghidra manual (F1 -> Version Control) for more information. ##### Naming functions Let's say you are looking for something related to how soldiers respawn. First, look for "Respawn" in debug exe: ![Filter settings](/assets/Ghidra_tips/ghidra_filter.png) Check `Use Path` and `Allow Globbing` in filter properties (button next to filter text input), then look for `soldier*/*respawn`. Use namespaces tree - it shows more info; `Impl` class usually has the code you are interested in. All right, you've found a function in the debug exe that looks like it - `tpp::gm::soldier::impl::Soldier2Impl::Respawn`, but we need the code in production executable. Load `mgsvtpp.exe`, press `g` (or `Navigation -> Go To`), paste full function name and click OK. ![Function not found](/assets/Ghidra_tips/ghidra_goto.png) Function was not discovered before, Ghidra doesn't know anything about it. There are several approaches to this problem. First is to run [Version Tracking](/Ghidra_version_tracking/) to match functions from debug exe to prod exe. That was already done before - this process runs for a long time, consumes a ton of memory and the results have to be filtered manually. In fact, ~30k functions in production exe were renamed by Version Tracking. Running it again is not advised, since there are much faster ways. Second is to look for specific function patterns. ###### Function patterns Select some code that looks unique to you in `Decompiler` window, then select continuous list of corresponding instructions in `Listing` window. Use `Search -> For Matching Instructions -> Exclude Operands`. Ghidra will automatically open a search window and form a binary string to look for. Search for it in debug exe first to make sure that there are not too many matches. ![](/assets/Ghidra_tips/ghidra_binsearch1.png) As you can see, we found 4 entries and only 2 functions. Good enough. Open search window in production exe by pressing `s`, change search type to binary, paste the search string and search for it. ![](/assets/Ghidra_tips/ghidra_binsearch2.png) Now you need to compare decompiled code in debug and production exe. Usually it looks almost the same, but you **must** make sure that this is the same function. Giving function a name adds context that will be used by other people; adding wrong context will misguide and confuse them, effectively losing hours of work. If function decompilation listing matches in both exes, copy full name of the function from debug exe: `tpp::gm::soldier::impl::Soldier2Impl::Respawn`. In production exe we matched against `FUN_141367810`, which has same amount of parameters, both reference other named functions in same places. Put cursor on function name in `Decompile` window and press `l` (right click -> Rename Function). Paste full function name into name field, set namespace to `Global`. Ghidra will automatically create proper namespaces for you; do not create namespaces by hand - this results in weird side effects. ![](/assets/Ghidra_tips/ghidra_rename.png) Now the function is properly named. Save the project by pressing `Ctrl+S` (and do it often). You *may* change parameter types by right-clicking on function name and selecting `Edit Function Signature`. This is not a required step; most of the types don't have proper definitions, so changing types may distort decompiled view to the point beyond recognition. It will also change decompilation view of other functions, so don't do that unless you really need it. You can rename the variable instead, adding the type in it. ###### Issues Let's say function looks almost the same, but you are not sure. Do **NOT** rename it just yet - you might be wrong and it will cost you a lot of time. You can select another chunk of that function and search for it. If there is a match in the same function, most likely you've found it. Still hesitate? Rename the function, but add `_MAYBE` suffix to indicate some uncertainty to others. Do **NOT** make up function names and namespaces, this leads to confusion. Leave a comment `might be a soldier respawn function`, but do not rename the function to `solly::RefillHealthAndChangePosition`. There is no need to sign the comment with your name, it is saved in [History](#code-history) automatically. ###### Pattern matching Another problem: function has some weird patterns that do not match at all. You can fine-tune search pattern: `Search -> For Instruction Patterns`. Click on `Enter bytes manually` icon (paper with pencil, left to home button, second on the right). Copy binary code, close the window. ![Binary pattern](/assets/Ghidra_tips/ghidra_pattern2.png) Open search pattern window in prod exe, paste copied bytes into same window. Addresses in prod and debug exes differ, so you must exclude them by clicking on them. Registers may be different too, mnemonic stays the same. ![Operands with static addresses excluded](/assets/Ghidra_tips/ghidra_pattern1.png) After tuning the pattern, click `Search All`, look through the results, compare them etc. ###### Vtables All right, pattern matching failed too. Third approach is vtable entries. Select the function in `Listing` window and click on the first XREF (or thunk function (with `(T)`)). Usually it points to the function reference in class' vtable. ![Location in vtable](/assets/Ghidra_tips/ghidra_xref1.png) ![Vtable entries](/assets/Ghidra_tips/ghidra_xref2.png) Look for `Soldier2Impl` in prod exe, select some function (`tpp::gm::soldier::impl::Soldier2Impl::Authorize`) and navigate to its position in vtable: ![Authorize in prod vtable](/assets/Ghidra_tips/ghidra_vtable1.png) Find same function in debug exe, navigate to vtable. ![Authorize in debug vtable](/assets/Ghidra_tips/ghidra_vtable2.png) `Authorize` is #17 and `Respawn` is #55. They should be in the same position in production exe. Scroll production vtable to the beginning, usually it has a label and referenced in other places. Create an array (right click -> `Data -> Create Array`) with same size as vtable in debug exe: ![Array creation in prod](/assets/Ghidra_tips/ghidra_vtable3.png) Navigate to entry #55, compare decompiled code, etc. Once again, make sure that code matches - production exe differs from debug exe, some code was added and some removed. Vtable function order is not guaranteed, mistakes were made. ###### References Look for referenced functions. For example, `Respawn` uses `UpdateTravelWithInstanceIndex` function. If it is already named in production exe, you can compare XREFs between exes. Amount of references and their order is not guaranteed to be the same. ###### When everything else fails Take a break, think of different approaches. Your function might've been inlined by compiler in other function or just removed from production exe. ##### Tracing Sometimes you need a bigger picture of things, like where and when is this function called? A lot of functions are not called directly, a vtable call is made instead. Let's use `tpp::gm::player::impl::UiControllerImpl::Update` function as an example. It runs in a loop doing player UI things; it also has no direct references. This function is located at `0x140fe9630`. Launch your debugger, I use [x64dbg](https://github.com/x64dbg/x64dbg/). Ghidra's debugger has serious UI issues - hangs / eats memory, so just avoid it. Start the game in the debugger, add a breakpoint at `0x140fe9630` and wait for it. After breakpoint was triggered, get a stacktrace (`printstack` in `Log` tab): ![x64dbg, log window with stacktrace](/assets/Ghidra_tips/stacktrace1.png) There are no function names, only addresses. Copy stacktrace and save it into a file, I use `C:\stack.txt`. Open Jython console in Ghidra (`Window -> Jython`) and paste the script: ```python def stack(): f = open("C:\\stack.txt", "r") lines = f.readlines() f.close() for line in lines: if line == "": print continue if "INT3" in line: print continue if "mgsv" not in line: print(line.rstrip("")) continue parts = line.split(".") symaddr = line.split(" ") addr = toAddr(parts[1]) fname = getFunctionAt(addr) if not fname: fname = getFunctionBefore(addr) print("\t" + symaddr[1].rstrip("\n") + " = " + fname.getSymbol().getObject().toString()) ``` Change `C:\\stack.txt` to whatever file path you saved your stack into. Then, call `stack()` function: ![Jython interpreter, Ghidra](/assets/Ghidra_tips/stacktrace2.png) All functions are already named, so you get a nice stacktrace: ``` mgsvtpp.0000000140FE9630 = tpp::gm::player::impl::UiControllerImpl::Update mgsvtpp.00000001409C1E18 = tpp::gm::player::impl::Player2GameObjectImpl::ExecuteSerially mgsvtpp.0000000146CA9E25 = fox::gm::impl::GameObjectLevel::ExecuteSerially mgsvtpp.0000000146CA89EA = fox::gm::impl::GameObjectExecuteJob::Do mgsvtpp.0000000142F2646A = fox::Job::Execute mgsvtpp.0000000142F2ADBA = fox::JobExecutor::Execute mgsvtpp.000000014002E5C9 = fox::impl::JobPool::Wait mgsvtpp.000000014311BE5D = fox::CoreFramework::Run mgsvtpp.0000000143119C1B = fox::CoreFramework::Go mgsvtpp.0000000142E5D0EA = Main mgsvtpp.000000014C1B9854 = _mainCRTStartup ``` Addresses are off by one instruction. Navigate to `0x1409C1E18` in `Player2GameObjectImpl::ExecuteSerially`, move one instruction up and leave a `Pre Comment` on `CALL` instruction (`;` button or right-click -> `Comments -> Set Pre Comment`). Other types of comments are either too big (like plate) or have bad visibility (end of line). ![Adding comment using listing window](/assets/Ghidra_tips/stacktrace3.png) Now vtable calls in `ExecuteSerially` are documented: ![Annotated vtable calls](/assets/Ghidra_tips/stacktrace4.png) Make sure you put the comment on `CALL` instruction - `Decompile` window may put comment text somewhere else, it must not be trusted. Do not use `Decompile` window to select addresses, it selects too much: ![Decompile window selection selects 2 more instructions](/assets/Ghidra_tips/stacktrace5.png) Function name comments in `Listing` window are clickable as long as they are fully displayed (not truncated); you can use them to navigate between functions. If some functions in your stacktrace are not named, be a gentleman and try to name them using methods above. You can also check where other `CALL` instructions in this function point to, adding more documentation. If destination function is not named, leave a comment with unresolved function name - better than nothing: ```c++ uVar29 = *(uint *)&this->localPlayerID; /* FUN_14963f770 */ lVar13 = (**(code **)(**(longlong **)&this->field_0x80 + 0x10))(); local_198._12_4_ = 0; ``` ##### Assigning proper names Production exe was researched in Ghidra before the debug exe so there are some made up namespaces and names. You can (and you should) name them properly - just like in debug exe. An example: ![](/assets/Ghidra_tips/badname1.png) `fox::gamekit::CameraSelector::s_MainInstance` is not a real variable name. Debug exe has a proper name for it: `fox::gk::CameraSelector::s_mainInstance`. Let's rename it by pressing `l`: ![](/assets/Ghidra_tips/badname2.png) Make sure to set namespace to `Global`, otherwise new namespace will be added to old one. ##### Naming constants Let's say you are looking for a StrCode32 message "PlayerDamaged". Press `s` to open search window, select "Hex" format, look for `45fdf281` - one match found in `tpp::gm::player::impl::DamageControllerImpl::AdjustDamageReaction`. You might be tempted to set that hex value to "PlayerDamaged" string using right click -> `Set Equate`, so decompiled view would be more readable. ![Don't do that](/assets/Ghidra_tips/equate.png) This is a bad idea for two reasons. First, Ghidra takes a lot of time renaming that hex in the whole project - it takes tens of minutes, locking ui. Second, it adds more confusion - searches usually start with hex value, but there is no hex in `Decompile` and `Listing` windows anymore, just some text, forcing you to recheck that string. Better solution is to leave a pre comment as seen on screenshot above. You can search for comment text using `Search -> Program Text` window and limiting it to comments. ##### Repairing flow Sometimes, your stacktrace might point to some garbage area without any code. In that case hold "Shift" and click on "F" button on the toolbar: ![](/assets/Ghidra_tips/fbutton.png) It will navigate you to the closest function above that point in code. Most likely that function will appear to be shorter than expected, breaking on `fox::SharedString::~SharedString` or `EntityPtr::Set`. Listing window looks like this: ``` 14d46ed26 e8 b5 e6 CALL fox::SharedString::~SharedString ba f2 -- Flow Override: CALL_RETURN (CALL_TERMINATOR) 14d46ed2b 90 ?? 90h 14d46ed2c 48 ?? 48h H ``` Right-click on that `CALL` instruction and choose `Modify Instruction Flow`. Set it to `Default` and press "OK". Now you can see more code in `Decompile` window. Put cursor on the next instruction (14d46ed2b) and press `d` to disassemble the bytes. Finally, navigate to the beginning of the function, right-click on it and select `Function -> Re-create Function`. That will repair navigation desync between listing and decompile windows. Byte disassembly doesn't always result in meaningful data; you may be disassembling some binary data instead. If data doesn't make any sense, undo the procedure by pressing `Ctrl+Z`. Do not blindly change the flow, sometimes Ghidra does the right thing and function ends where it ends. ##### Labels in vtables Vtables usually contain addresses of thunk functions that lead to real functions: ![Unnamed label](/assets/Ghidra_tips/thunk_label.png) Instead of renaming the label, turn it into a thunk function by pressing `f` on it: ![Thunk function](/assets/Ghidra_tips/thunk_function.png) It will automatically add comments, rename the label and do things right from Ghidra's point of view. ##### Code history Right click on instruction in `Listing` window, select `Show Label History`. ![](/assets/Ghidra_tips/history.png) ##### x64dbg on Linux Install [protontricks](https://github.com/Matoking/protontricks), run it, select MGSV:TPP. Select default prefix, run debug console, navigate to x64dbg.exe and run it: `wine x64dbg.exe`. Faster alternative: ``` protontricks-launch --appid=287700 ``` ##### Xbox360 Use [X360 XEX Loader](https://github.com/zeroKilo/XEXLoaderWV) for binary analysis. ##### See also - [Ghidra version tracking](/Ghidra_version_tracking) ### `wiki:wiki/Ghidra_version_tracking.md` Game updated, need to transfer symbols from old exe to new one. ###### Steps 1. Add as much memory as you can to `support/launch.sh` script (38G out of 48 available for me): `VMARGS_FROM_LAUNCH_SH+=("-Xmx38G")` 2. Launch Ghidra 3. Launch Version Tracking from gui, select old exe as source, new as destination 4. Click on magic wand button which will run all correlators and apply matches. 5. After the process finishes, Ghidra will start to sort matches. Interrupt the process, some matches are already there. ###### Optional steps for more matches Use this PyGhidra script _after_ automatic matching, adapt as needed: ```python import pyghidra import jpype USERNAME="unknown321" GHIDRA_DIR="/opt/ghidra_12.0_PUBLIC/" PROJECT_DIR="/media/dev/tpp-ghidra" PROJECT_NAME="mgsvtpp" TRACKING_SESSION_NAME="/153 - 154" # yes, with slash similarityScoreThreshold = 0.8 confidenceScoreThreshold = 1 pyghidra.start(verbose=True, install_dir=GHIDRA_DIR) # those imports are available only after starting from ghidra.framework.client import HeadlessClientAuthenticator from ghidra.feature import vt from ghidra import util HeadlessClientAuthenticator.installHeadlessClientAuthenticator(USERNAME, None, True) project = pyghidra.open_project(name=PROJECT_NAME, path=PROJECT_DIR) # ghidra asks for password here f = project.getProjectData().getFile(TRACKING_SESSION_NAME) monitor = util.task.ConsoleTaskMonitor() consumer = jpype.JObject() f.getDomainObject(consumer, False, True, monitor) domainObject = f.getDomainObject(consumer, False, True, monitor) manager = domainObject.getAssociationManager() ass = manager.getAssociations() # domainObject.startTransaction("newtransaction") used = {} i = 0 for entry in ass: i = i + 1 matches = domainObject.getMatches(entry) symbol = domainObject.getSourceProgram().getSymbolTable().getPrimarySymbol(matches[0].sourceAddress) if not symbol: continue if symbol.getName().startswith("FUN_") or symbol.getName().startswith("thunk_"): continue print(i, len(matches), symbol.object, matches[0].similarityScore, matches[0].confidenceScore, matches[0].sourceAddress, "->", matches[0].destinationAddress, matches[0].getAssociation().getStatus() ) if matches[0].sourceAddress in used: continue if matches[0].getAssociation().getStatus() != vt.api.main.VTAssociationStatus.AVAILABLE: continue if matches[0].similarityScore.getScore() < similarityScoreThreshold: continue if matches[0].confidenceScore.getScore() < confidenceScore: continue used[matches[0].sourceAddress] = symbol.object # entry.setAccepted() ``` ### `wiki:wiki/Guides.md` > See also the [Alphabetical](#alphabetical) subsection for an uncategorized list of all guides. - ## Getting Started - [SnakeBite Mod Manager](/SnakeBite_Mod_Manager) - [Infinite Heaven](/Infinite_Heaven) - [IHHook](/IHHook) - [Zeta](/Zeta) - [Steam Deck / Linux](/Steam_Deck) - [Ghidra](/Ghidra_tips) - ## References - [Collision Attributes](/Collision_Attributes) - [Entity Reference](/Entity_Reference) - [File Structure (TPP)](/File_Structure_(TPP)) - [Hash Wrangling](/Hash_Wrangling) - [Links to Useful Github Repos](/Links_to_Useful_Github_Repos) - [Locations](/Locations) - [Memory Tags](/Memory_Tags) - [Things Codes](/Things_Codes) - [Unsolved problems](/Unsolved_problems) - [Unpacking and Organizing Game Files](/Unpacking_and_Organizing_Game_Files) - ## Miscellaneous - [Localization](/Localization) - [How to create custom lang entries](/How_to_create_custom_lang_entries) - [External modding resources](/External_modding_resources) - ## Mission Design - [Mission Objectives](/Mission_Objectives) - [Mission Table Subscripts](/Mission_Table_Subscripts) - [Create a Custom Mission](/Create_Custom_Mission) - [Route Set](/Route_Set) - [Create a Custom Map](/Create_a_Custom_Map) - [Using UAVs in Side-Ops](/Using_UAVs_in_Side_Ops) - ## Rendering - [Using FMDL Studio with Blender](/Using_FMDL_Studio_with_Blender) - [Custom weapons](/Custom_weapons) - [Fx Nodes](/Fx_Nodes) - [Hair Materials](/Hair_Materials) - [Retexturing the Bionic Arm](/Retexturing_the_Bionic_Arm) - [Working with DDS Files](/Working_With_DDS_Files) - [Converting Between FTEX and DDS](/Converting_Between_FTEX_and_DDS) - [Mesh Mashup](/Mesh_Mashup) - [Textures](/Textures) - ## Sound - [Creating a Custom Sound Bank](/Creating_a_Custom_Sound_Bank) - [How to add custom sounds](/How_to_add_custom_sounds) - [How To Find & Change Audio Files](/How_To_Find_&_Change_Audio_Files) - [How to replace sortie prep music in less than five minutes](/How_to_replace_sortie_prep_music_in_less_than_five_minutes) - [Sound Codes](/Sound_Codes) - ## Wiki Related - [Wiki Tips](/Meta/Wiki_Tips) - [Formatting Reference](/Meta/Formatting_Reference) - [Creating/Editing Pages](/Meta/Creating_Editing_Pages) {:.index} ##### External Guides - ## Getting Started - [MGSV Modding Series playlist](https://www.youtube.com/playlist?list=PLvs_Pavo7cCXJoassPaeMKWE9R99M22Fz) - Covers: Snakebite, unpacking game files, FMDL Studio v2 setup, 3dsMax UI and basics, Unity model and texture editing, FV2 texture swaps - [SnakeBite In-Depth: Creating Your Own Mod Files](https://www.youtube.com/watch?v=Wg0qM7Yh5fU) - ## Sound - [Adding BGM From Other Missions](https://github.com/NasaNhak/git-tuppm-src/wiki/Guide:-Adding-BGM-From-Other-Missions) - [Sound Swapping and the Wwise Format](https://bobdoleowndu.github.io/mgsv/documentation/soundswapping.html) - ## Rendering - [Fmdl Studio v2: Merging Models w/ Blender](https://www.youtube.com/watch?v=0Z5Pt9EkUZM) - [How to Correctly Swap Player Models](https://www.youtube.com/watch?v=tqgLYR1GRF8) - [How to Create Custom Form Variations](https://www.youtube.com/watch?v=1oQ7V1-sUEQ) - FV2 editing tutorial using [FvTwool](/FvTwool) - [Perfect First-Person with Any Model](https://bobdoleowndu.github.io/mgsv/documentation/perfectfirstperson.html) - [Texture Modding Tutorial [AutoPftxsTool and Snakebite]](https://www.youtube.com/watch?v=WJ_HVJA-Zu0) - Follow-up to an earlier [tutorial](https://youtu.be/dqK2rErPd0s). - [Re-texturing a Supply Box](https://github.com/chocmake/MGSV-Custom-Texture-Path-Hex-Replacer/wiki/Re%E2%80%90texturing-a-Supply-Box) - Texture modding using FMDL path edits - ## Animation - [Adding Player Motions](https://chocmake.github.io/guides/mgsv-adding-player-motions/) - MTAR/GANI modding walkthrough, resources {:.index} ### `wiki:wiki/GzsTool.md` GzsTool is an open-source archive unpacker and repacker for Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain written by Atvaark. It supports unpacking and repacking QAR .dat, .fpk, .fpkd, .pftxs, and .sbp files. When unpacking archives, it automatically decrypts encrypted text files. It can also calculate file name hashes on the fly, allowing it to add new files to archives without needing a pre-calculated hash. > **Note:** version 0.6 of Atvaark's version has an [issue](https://github.com/Atvaark/GzsTool/issues/9) with repacking. Use the [linked](https://github.com/Atvaark/GzsTool/releases/tag/v0.5.3) v0.5.3 for the time being, or check out Bob's fork [below](#bobdoleowndus-fork). {:.important} > **Ground Zeroes compatibility:** if wanting to mod Ground Zeroes, the current version of GzsTool does not support Ground Zeroes .g0s files, you must use an earlier version: [GzsTool v0.2](https://github.com/Atvaark/GzsTool/releases/tag/v0.2) {:.important} ##### Usage GzsTool can unpack files simply by having an archive file dragged onto it. It can also unpack archives by command line, providing GzsTool the path to the file (example: `GzsTool Example.dat`). It will output all of the files contained in the archive into a folder named *\_\*, and an .xml file detailing all of the files that were contained in the archive. GzsTool can also unpack all .fpk and .fpkd archives in a specified directory, by dragging the folder onto GzsTool, or specifying the directory in command line (example: `GzsTool C:\Example\Folder`). GzsTool utilizes a dictionary of filenames called `qar_dictionary.txt`. As it outputs files, it compares the hashes generated from this dictionary to the hashed filenames found in the archive. If it finds a match, it will output the file by its real name. If it cannot find a match, it will output the file by its hashed name. To repack an archive, the user needs to drag the .xml file output by GzsTool onto GzsTool, or by using command line and providing GzsTool the path to the .xml (example: `GzsTool Example.xml`). GzsTool will reference the list of files listed in the .xml to find and add files to the archive. GzsTool can also add new files to an archive by adding files into its output folder and adding the file to the .xml list. Because it can calculate hashes on the fly, it does not need a pre-calculated hash for new files with unhashed names. For files with hashed names, a separate entry for the hash with its extension is required. ##### Dictionary GzsTool utilizes a dictionary of strings called `qar_dictionary.txt` for qar (dat) and pftxs archives to match hashed file names to original file path names. If it does not find a match it will output the files with the hash in the root of the extraction folder for the archive, if it does find a match it will create the original file/folder layout and name. > An up to date qar_dictionary can be found at [TinManTex's repository](https://github.com/TinManTex/mgsv-lookup-strings). GzsTool also uses a dictionary called fpk_dictionary.txt to recover full filenames of files in fpks VERIFY possibly this is only for GZ fpks. ##### BobDoleOwndU's Fork BobDoleOwndU created a fork of GzsTool with some added debugging commands, and the ability to repack .pftxs files without providing a hash for entries with hashed names. ###### Debugging Commands All debugging commands can be accessed by command line by providing GzsTool a `-d` argument. | Command Name | Command | Description | | ------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | Hash Filename | `-d -h ` | Produces the hashed version of a given filename. | | Hash Extension | `-d -he ` | Produces the digits that when binary left-shifted by 51 then binary ored with the filename, will produce the filename's hash with extension. | | Hash With Extension | `-d hwe ` | Produces the hashed version of a given filename with its extension included. | | Hash Legacy | `-d -hl` | Uses the legacy hash function, which is still used in TPP to hash most strings. | ### `wiki:wiki/Hair_Materials.md` ##### Do you want the hair on your custom model to look awesome? Well here's a guide to help you! This guide is only dedicated to explaining the individual hair texture maps the game uses and how to create them and what shaders to use. ###### Requirements - [Unpacked game](/Unpacking_and_Organizing_Game_Files/) - [FMDL Studio V2](/FMDL_Studio_V2/) Please make sure to check out [this YouTube playlist](https://www.youtube.com/playlist?list=PLvs_Pavo7cCXJoassPaeMKWE9R99M22Fz) first before going through this guide! We are assuming you already have a more or less idea on how to add textures to models and export them! ##### Texture maps There would be no point in just demonstrating without explaining what the textures do and how they work, so let's get that out of the way first. The game uses one hair shader most of the time, although there are instances where it will use a normal skin shader instead of a hair shader. This is only used when you might want to add a normal map for the hair, but it's been noted that the effect won't look as good as the dedicated hair shader that most vanilla models use. Miller's hair uses a skin shader to have a normal map give the strands depth, which is another way to make hair look messy. Unfortunately, the game doesn't have a shader that supports both a normal map (NRM) texture and a shift texture (SHM). First, let's understand what texture maps Fox engine uses for hair materials. | FMDL Studion texture Names | Sufixes | Compression Format | |-----------------------------|---------|--------------------| | Base_Tex_SRGB | bsm | DXT5 | | SpecularMap_Tex_LIN | srm | DXT1 | | Translucent_Tex_LIN | trm | DXT1 | | Shift_Tex_LIN | shm | DXT1 | Let's explore each texture! ###### Base_Tex_SRGB (bsm) The base texture is prefixed with 'bsm' (base colour map, or diffuse) and gives your custom hair model its colouring on the hair strands. The texture will be saved in the compression format of DXT5 and that goes for any texture that contains an alpha map, which in this case will be the opacity map. ![Diffuse map without the alpha texture](/assets/Hair_Materials/hair_diffuse_example.jpg){:.thumb} ![Alpha texture](/assets/Hair_Materials/hair_diffuse_example-alpha.jpg){:.thumb} ###### SpecularMap_Tex_LIN (srm) The specular map gives your hair its reflection on the material. In this case, we will only be using a roughness map and a specular occlusion map for the SRM texture. ![Specular map](/assets/Hair_Materials/hair_srm_example.jpg){:.thumb} ###### Translucent_Tex_LIN (trm) The trm map is a fairly important texture to make your hair look snazzy. This map is responsible for the Subsurface Scattering effect that softer materials will have when light hits the material. Instead of deflecting it, it will absorb the light, which will cause the material to glow. What this does is highlights strands giving more depth. Since Fox Engine's dedicated hair material doesn't support normal maps, it would end up looking flat. If your trm texture is done correctly it might just give you the edge to make hair look nice and 3D. ![Translucent map](/assets/Hair_Materials/hair_trm_example.jpg){:.thumb} ![TRM texture effect in game](/assets/Hair_Materials/DEDICATED_TRM_VS_BLACK_TRM.jpg) ###### Shift_Tex_LIN (shm) The shm is responsible for the anisotropic diffusion. This gives the hair a bright reflection. Real life hair has a shiny reflection to it. People with longer hair, ponytails for example will really give off the anisotropic effect. The same is true with weed in weed fields, giving the same effects. The important part of this texture is it can practically highlight individual strands giving it a better in depth look, highlighting strands and deflecting light with more contrast and sharpness. Good example is the small grey hairs you might see when you are getting older they will pop-out and shine more than the darker one's with much more reflection to them. ![Shift texture](/assets/Hair_Materials/hair_shm_example.jpg){:.thumb} ![SHM vs no SHM](/assets/Hair_Materials/shm_vs_no_shm.jpg) ![No SHM vs SHM](/assets/Hair_Materials/no_shm_vs_shm_2_ring.jpg) ##### Shaders The Fox Engine uses the **FoxShaders/fox3DDF_Hair** shader most of the time. Quiet's hair shader is designed for her abilities to disappear, but for the most part **FoxShaders/fox3DDF_Hair** is the preferred one to use. ###### Material settings ![Shader settings](/assets/Hair_Materials/hair_shader_base_changes.jpg) The constant values that never change for hair shaders are underlined in red. The ones underlined with orange are settings you might need to change but it's depending on what final effect you are looking for! The ones underlined in blue are the ones that might need absolute adjustments but yet again it depends on what you are looking for, which I will explain next. The settings that's important to us for the final output that might need adjustments are the `Anistropic_Diffusion` underlined in orange and the `Incidence_Colour` underlined in blue. ###### What do these settings do? **Anistropic_Diffusion**: This determines how strong the anisotropic reflection must be for the hair. This is also affected by how bright your SHM texture is, so you might need to adjust the texture before tampering with the `Anistropic_Diffusion` value. For the most part, `16` is used for Quiet's hair while Snake, Ocelot and Paz uses a value of `30`, using either one of them will work fine. The higher the number the stronger the reflection effect will be. **Note**: anisotropic is spelled `Anistropic` in game files. This is not a typo. **Incidence_Colour**: Incidence colour is basically the Subsurface Scattering colour in `x, y, z` values or `RGB` where `x=R, y=G, z=B` and `w` is the strength or Alpha strength of the Subsurface Scattering (SSS). Most hair Incidence_Colours use X, Y, Z values of 1 which will just highlight the hair as a semi white, 1 for all values would be ideal to use for hair colours like black, white and grey while brown and red hair sometimes will have adjusted values. Quiet and Mantis have their own unique Incidence colouring, while Quiets hair has a more brownish highlights to it and Mantis hair highlights has a reddish colouring when light passes through the hair. It is advised to not use a value larger than 1 otherwise the hair will light up like a candle having a balance is always preferred. ###### Example of the Incidence_Colouring | Incidence_Colour | X | Y | Z | W | |-------------------|-------|-------|-------|-----| | White | 1 | 1 | 1 | 0.25| | Brown | 0.976 | 1 | 0.996 | 0.25| | Light Red | 1 | 0.773 | 0.541 | 0.3 | You can adjust the W value to be more if you wish to have a larger Subsurface Scattering (SSS) radius on the hair. ###### Hair naming convention Before we dive into a practical example take note of the naming convention to use. This isn't needed but it is good practice to keep a good naming convention when naming your textures for the game. I like to keep a good practice of exporting the texture with the name tag of `chara_hair_bsm` | Texture Map | alias | Example | |--------------|----------------|--------------| | diffuse | chara_hair_bsm | sna_hair_bsm | | specular | chara_hair_srm | sna_hair_srm | | Translucency | chara_hair_trm | sna_hair_trm | | Shift text | chara_hair_shm | sna_hair_shm | ##### Practice Now that we have an understanding of what we are working with, we can do a practice run. We can start with converting the textures of our custom model to be properly utilized in Fox Engines material settings. In the practice example that we will be doing I was using Ashley's hair (from Resident Evil 4 Remake) over Ada Wong's head, so I named it `ada_hair0_bsm`. This is just part of good organizing of texture names. ###### Diffuse Map (BSM) Let's start with the diffuse map. Depending on what custom hair model you will be using we are going to import the diffuse map into a texture editing program either using GIMP, PhotoShop or Paint.Net. This is the simplest one to do, decompose the RGB values of the diffuse map then compose them as `RGBA` add the corresponding layers to where they were so RED -> Red channel, BLUE -> Blue Channel and GREEN-> Green Channel only extra channel now is the Alpha texture most games will have the diffuse and Alpha texture separated but some will have them combined like MGSV! The alpha texture will be added to the Alpha channel to add the transparency to the hair. Now that we composed the layers you can export the texture take note of the export settings in the screen shot below, it's very important! ![Export settings](/assets/Hair_Materials/diffuse_export_setting.jpg) ![Custom Diffuse Map, without the Alpha channel (this is just for demonstration on the wiki, but your Alpha texture is always in the Alpha channel of your diffuse map)](/assets/Hair_Materials/hair_diffuse_example.jpg){:.thumb} ###### Specular Map (SRM) If your custom hair model has a lot of different textures, you'll have to try and find the roughness map and specular occlusion. This can depend from texture to texture that you have. In my case, I used the base albedo for the red channel, this channel should not be very bright. The only thing in the red channel that must be a little bit bright is the hair strands themselves, so I dragged down the brightness and increased the contrast, which will make the strands brighter but not too much. For the Green channel I took the roughness texture and inverted it, but depending on how it looks some games might have it already inverted. The strands in the green channel are usually darker for the most with the surrounding background being bright white. Basically the inverse of what the red channel has. The srm output with all textures combined should have the hair strands either be a really light yellow or very light grey. For female hair I use a balance between the two for more reflection so the strands would be a light yellow, for males usually I use a specular map that highlights the strands as dark grey for less reflection. For Example the two pictures down below. ![Custom SRM for Snake](/assets/Hair_Materials/delta_hair_srm.jpg){:.thumb} ![Custom SRM For Ashley](/assets/Hair_Materials/hair_srm_example.jpg){:.thumb} As you can see Ashley's hair is a bit more yellow than that of Snake's srm which will give it a bit more reflection. ###### Subsurface Scattering Map (TRM) Your trm will mostly have a dark grey background, why? The brighter the background colour of the texture the more it will be highlighted. Is this what we want? Not at all, you will see areas glow more that doesn't have a hair strand there which will look out of place so this is why it might be better to have a way darker background to only highlight the hair strands and not the transparent areas of the hair. In my case the albedo map for Ashley's hair had a certain amount of strands that were darker than the other which will be ideal to get more depth. I composed a texture map with the albedo as one solid colour which will look grey and added the alpha map in the alpha channel to only have the strands visible. You can create a new image texture of the same size and colour it to a dark grey. Add a new layer in the texture and paste the composed albedo with the alpha texture you made it over the background texture this way they are separated from each other which will make it easier to adjust the strand's colouring. At first it might not be what we want but that's ok. You can select the new layer and adjust its brightness I like to have it a bright grey but not too much. Anchor the layer down and that's all that's needed. You can export the texture. ![Custom TRM for Ashley](/assets/Hair_Materials/hair_trm_example.jpg){:.thumb} ###### Anisotropic Texture Map (SHM) We are almost done with the textures! The last one well also very important and is luckily easy to make. Anisotropic hair highlights move from bright to dull so at the base origin of the hair on the texture it should be duller and in the middle brighter and transition back to dull when it go's to the hair tips. How do you make it? In my case I used the trm texture and started to adjust the colours, to get the transition of brighter highlights to lighter ones you can use a black paint brush with a low opacity and paint over it, but I use a contrast adjustment of the texture in this case, where it will be darker on the edges and brighter in the middle and it's as simple as that, depending on how reflective you would like your hair to be, you can stick with a bright grey to a light white for super reflection or a darker grey for lighter or duller reflection. ![Custom SHM for Ashley](/assets/Hair_Materials/hair_shm_example.jpg){:.thumb} **Ay there is a tip!** Most games might have a extra map for some individual hair strand pop-outs. In my case I used the roughness map of Ashley's hair. Now of course you might not have this so it is possible that you might need to improvise. In that case you could actually use the diffuse map or even the alpha map and turn the contrast way up and adjust it's brightness to use it as a alpha texture to paste it over your shm. I used the roughness texture as an alpha since it already had individual strands and made the texture a brighter white with a dark background and pasted this as a layer over the SHM map I just made. It will now basically highlight a couple of random individual strands. If you are still fairly Unsure take a look at this YouTube video. It's a practice session of the textures I converted above: [MGSV:TPP Hair Texture practice session](https://youtu.be/mDqAXhOCQt4). Basically what I do in this video is what I explained above. Now perhaps it could be tricky to explain the steps since sometimes it might become super free hand and guesswork depending on what texture maps your custom model has. **Great Job**, now we have created our textures for our custom hair model. ##### Adding the shaders inside of FMDL Studio! **This is the simple part!** **Creating a directory to store your textures** *If you already know how to add a directory for your custom textures then you can skip this part and move on to the Import of the fmdl file* Firstly we need to add the textures we just created into FMDL Studio. We will start by creating a file directory in the `Assets` folder in the console at the bottom of FMDL studio, go into your `Assets` folder and right click and select `Create` -> `Folder` and rename the folder just created in my case I wanted to store my textures in `/Assets/tpp/tutorial/Pictures` so I repeated this process until the entire directory structure is created. You can make your own directory path and store your custom hair texture in there just be sure to have the exact same file path to your textures in your mod. ![Creating texture directory in FMDL studio](/assets/Hair_Materials/1_a_create_file_dir.jpg){:.thumb} After creating your directory navigate to where you exported your custom textures in an file explorer, select all the textures and drag and drop it into the `Pictures` folder (Depending on what your child directory is of your custom directory mine is `Pictures`). ![Navigate to the directory containing the textures drag and drop all the textures in your folder(More clarification with the blue arrow)](/assets/Hair_Materials/1_c_select_text_dnd_into_dir.jpg){:.thumb} After you dragged in the textures your folder should look like this: ![Final outcome of your texture directory](/assets/Hair_Materials/1_d_result_af_dnd.jpg){:.thumb} **Importing fmdl file** Now that we have our textures in FMDL studio we can import a vanilla model to use it's hair materials. Go to `FMDL studio` -> `Import FMDL` navigate to the vanilla fmdl file you will be using in your unpacked game files. ![FMDL studio import button location](/assets/Hair_Materials/a_import_button.jpg){:.thumb} ![Navigating to your fmdl file of choice and import the fmdl](/assets/Hair_Materials/b_locate_model_import.jpg){:.thumb} ![Import of your fmdl in Unity](/assets/Hair_Materials/c_quiets_model_aft_imp.jpg){:.thumb} **Applying the materials onto your custom hair model** Selecting the vanilla model hair mesh, navigate to the shader properties in the bottom right hand side and drag the material onto your custom hair mesh. ![Dragging and dropping the material onto your custom hair mesh](/assets/Hair_Materials/d_drag_drop_hair_mat.jpg){:.thumb} Repeat this process depending on how many parts your hair mesh has. After you are done you can delete the vanilla model it is no longer needed. ![Outcome after adding the hair material to all parts of the custom hair mesh](/assets/Hair_Materials/e_result_after_finis_dnd.jpg){:.thumb} Now that we have added all the materials needed we can drop our custom hair textures into the texture slots of the material settings. Expand the material settings by clicking on the small arrow, that will expose 4 texture slots that we will drag our custom textures into. ![The arrow mentioned above is underlined in red](/assets/Hair_Materials/expand_mat_settings.jpg){:.thumb} Drag and drop your custom textures from the directory you made into the corresponding texture slots. ![Take note of where the textures will be dragged and dropped in](/assets/Hair_Materials/f_dnd_hair_into_tex_slot.jpg){:.thumb} After you added your custom textures to all texture slots in the shader settings, you will have to fix the tilling right now the hair might look strange on the model. Why is that? Well Unity flips the tilling around of the texture so right now it's mirrored. ![Texture tilling with a value of `-1` meaning the texture is mirrored on the y-axis](/assets/Hair_Materials/g_notice_text_tilling.jpg){:.thumb} We can fix that by swapping the tilling around which will have a tilling value of `1`, now you will see that the texture orientation will be correctly orientated on the mesh. Repeat that for all the textures. ![Texture tilling with a value of `1`](/assets/Hair_Materials/h_correct_tilling.jpg){:.thumb} Great! We have applied the textures and materials to our custom hair mesh! **Well great now it's applied. Where do we go from here?** Depending on what your custom model is (male hair, female hair, etc), you might need to adjust some shader settings for your hair. This will depend on what result you are looking for, in my case the only setting I changed was the `Incidence_Colour` values. I changed the `x, y` and `z` values to be all 1. As I mentioned previously it's so far the preferred colour for black hair and in general most hair, unless you are looking for a specific SSS colour it must be. **Importantly well what Fox Model component settings must be used?** Hair textures and any texture that will be rendering an alpha map is recommended to have the settings to be set to `Alpha`, to render the transparency of the diffuse map. For a hair shader it must never cast a shadow other wise your hair will be flagging a red colour. Why is that? It appears some shaders support only a couple of Fox Model settings. It can be different depending on the shader you are using, the hair shader here can only be set to `Alpha` and `No Shadow` .The only occasion when you can set it to cast a Shadow is if you wanted to use a normal skin shader or Quiet's hair shader for your hair it is able to render the hair with an `Alpha` and a `Shadow` although normal skin shaders might cast extremely strange shadows onto the hair when the the Fox Model component is set to cast a shadow, so keep that in mind if you do want the hair model to cast a shadow. ![Example of Fox Model Component](/assets/Hair_Materials/hair_shader_base_Fox_Model_settings.jpg) **And BOOM!!** Export that beauty and we are done! Check the result in game! ##### Final result! Here was the final result of Ashley's hair in the Fox Engine. ![](/assets/Hair_Materials/Ingame_Hair_Result_1.jpg){:.inline width="300px"} ![](/assets/Hair_Materials/Ingame_Hair_Result_2.jpg){:.inline width="300px"} {:.center} ##### A couple of notes This isn't related to this guide but perhaps since we are dealing with hair well your hair will always have a different outcome than that of other hair models. Well why? Many modern hair models have become ever more realistic but at the cost of performance in my case here this model had a really large poly count that will have a large effect on the appearance from a far distance since high poly models with an alpha texture applied to them will become pixelated at a certain distance. ### `wiki:wiki/How_To_Find_&_Change_Audio_Files.md` > This guide uses an alternative method to the prior, related custom sound [guide](/How_to_add_custom_sounds), along with some different tools. ##### Step 1 1. Download [File Monolith](https://www.nexusmods.com/metalgearsolidvtpp/mods/739?tab=description\). 2. Extract the files from the zipped/.rar file you downloaded. Put them into a separate folder of your choice. Mine is labeled `File Monolith`. 3. Run the "Archive Unpacker" Application that is located in the files you just moved. 4. Find where your "chunk" files are located. In my directory, it is `A:\Steam\steamapps\common\MGS_TPP\master`. 5. Use the ellipses to find and click on a "chunk" file. Ex. `chunk0.dat`. 6. Determine an output folder. I labeled mine "MGSVTPP Folders," as I use multiple files. Feel free to make backups of any file you intend to modify, but the programs that we use make backups for you, or don't modify the original file to begin with. --- ##### Step 2 1. Assuming you extracted `chunk0.dat`, as previously instructed, the files you need are located here: `\Assets\tpp\sound\asset`. 2. Download the [sbp_tool](https://github.com/secaproject/SBP_tool). 3. Extract the files from the zipped/.rar file you downloaded. Put them into a separate folder of your choice. Mine is labeled `sbp tool`. 4. If you intend to modify any of Venom Snake's combat lines (ie. holdups, interrogatons, buddy lines & commands, etc), you need `vox_sna.sbp` located in the `chunk0` Folder we extracted earlier. As previously stated, it would be located in `\Assets\tpp\sound\asset`. 5. Copy the `vox_sna.sbp` file. Then, paste the copy into the same folder that the "sbp_tool" is located in. 6. Run the "sbp_tool_V0.8" application. Write the full name of the file you intend to open. In our case, it's `vox_sna.sbp`. Type that name in exactly as presented, without the quotations that I added. Then, click "Enter" on your keyboard. --- ##### Step 3 1. You should now have an openable folder labeled as `vox_sna`. The lines you'll need to replace are located in two separate folders. The bulk of the lines are in `vox_sna\stp` whereas the smaller amount are located in `vox_sna\bnk\DIDX`. 2. I heavily recommend making two separate folders elsewhere. Name one `stp Folder` and the other `bnk Folder`. Then, copy all `.wem` files from `vox_sna\stp` and paste them into your `stp Folder`. Lastly, copy all .wem files from `vox_sna\bnk\DIDX` and passte them into your `bnk Folder`. --- ##### Step 4 1. Download the [vgmstream](https://github.com/vgmstream/vgmstream/releases/tag/r1879) tool. 2. Extract the files from the zipped/.rar file you downloaded. Put them into a separate folder of your choice. Mine is labeled `VGMStream Audio Converter`. 3. The way to run the "vgmstream-cli" application is different than the other apps we've used so far. You must drag any .wem file you have ONTO the .exe itself. Far as I'm aware, you can't just run the app on its own. 4. As an example, I took my copied .wem files and selected them all at once. I dragged all of them onto "vgmstream-cli", and they were converted to `.wav` **inside the folder that you drag them from**. 5. This line is for those still confused. If you understood the previous line, move on. - Copy all .wem files you intend to convert. Paste them into the `VGMStream Audio Converter` folder that we made. Then, **drag** any `.wem` file you want to convert **directly onto** the "vgmstream-cli" app. They'll convert to **listenable** files known as `.wav` files. 6. I recommend taking your newly generated `.wav` files and putting them into a subfolder. For any from your `stp Folder`, I recommend creating a folder in there named `.wav files` and putting any `.wav` file in there. It keeps things organized, but it's up to preference. --- ##### Step 5 1. Write down the names of **each** file somewhere and LABEL what the line states. Example: `0cdc0624.wem`, when converted to `.wav`, has Snake saying, "Cease cover fire." Write both the file name and what is said somewhere. You don't *have to*, but it's a headache to remember 100+ lines. 2. Record or find any audio you like. If you wanna replace `0cdc0634` with "Is there a way to take off my pants?" from MGS3, go wild. After you have whatever lines you have, change their name to what you want to replace. Ex. Change the name of the file "Is there a way to take off my pants?" to `0cdc0634`. --- ##### Step 6 1. Download [Wwise 2013.2.9](https://www.nexusmods.com/witcher3/mods/3234). > If you're wondering why, it's because only the older versions of Wwise work for MGSV. And the Wwise website doesn't have them anymore, as of me writing this guide. 2. Open it (you *may* need the base version of Wwise from the website, but I haven't tested it as I already have it). 3. Create a new project. When you do, hold `Shift` and `K` at the same time until a menu pops up. 4. Go to "Source Settings". Click on "Default Conversion Settings". Then, go to "Factory Conversion Settings," then "Vorbis", then "Vorbis Auto Detect Medium." Then click "OK". > **Note:** I am uncertain if other conversions work, but I'm operating under what I know works. Feel free to test. 5. Click on "Project" in the upper left corner of the app, then click "Import Audio Files". Add in all files you renamed, etc. 6. Go back to "Project", but this time click on "Convert All Audio Files." All the files you just made back into .wem via that should be located in your `Documents\WwiseProjects\YOURPROJECT\.cache\Windows\SFX`. 7. Take all those `.wem` files and edit out the extra numbers it added. Take them and place them back into either the "stp" or "bnk" folders that we extracted with the sbp_tool, wherever the **original** lines were. You'll know you did it right if you get an "Overwrite Files?" type of popup. Obviously overwrite. 8. Reopen the sbp_tool, and then type in the file name. It should just be `vox_sna`. It'll repack said file back into its original full form. It should be labeled as `vox_snaNEW.sbp`. Copy that `.sbp` file. --- ##### Step 7 1. Take that `.sbp` file and follow the necessary steps to make a mod through MakeBite. If that's vague, then it *should* be the following case: Make a folder with your mod's name on it. Ex. `Venom Snake Audio Mod`. Then, inside that folder, create the following folders in order: `\Assets\tpp\sound\asset`. Place the copy of the .sbp file into the last "asset" folder. Rename the `.sbp` file into `vox_sna.sbp`, just as the original was. 2. Use MakeBite to package the file, et cetera. 3. If any of that is confusing, then I'm sorry. Just the way I did it, and I had to learn 3/4 of that on my own over the course of dozens of very irritating hours. > **Author's Note:** Yes, you do need to replace at least well over 100 lines, depending on your patience level. The good news is that most of them are not used in-game. At all, from what I can tell. You only *have to* replace the lines that you know, or suspect, are used. > > There are many repeat lines such as "Go." I do not have a good answer as to which lines are for certain used over others, even though I've spent dozens of hours on this. If you have the time and patience, you can discover for yourself, but I'm tired of this damn thing. ### `wiki:wiki/How_to_add_custom_sounds.md` In this article I'll be explaining how to change sounds in MGSV. This guide will assume you have none of the tools required or any experience with modding. There are a few things you need to have done before you begin, so before we actually do anything let's go over a checklist. ##### **Things to have done before you begin:** 1. An easy to access folder that will act as your workstation 2. Have [File Monolith](https://www.nexusmods.com/metalgearsolidvtpp/mods/739?tab=description) in your MGSV folder 3. Have [Ravioli Game tools](https://www.scampers.org/steve/sms/other.htm) in an easy to access location, preferably within the workstation folder. 4. Have [Wwise 2015.1.9](https://www.audiokinetic.com/downloads/previous/) downloaded. (This requires more depth and will be explained below) 5. Have [Snakebite Mod Manager](https://www.nexusmods.com/metalgearsolidvtpp/mods/106) downloaded and installed. 6. Have [Audacity](https://www.audacityteam.org/) installed. 7. Have [MGSV Sound Replacement Tool](https://www.nexusmods.com/metalgearsolidvtpp/mods/826) downloaded and in your workstation folder. 8. Have the sound file you want to add to the game labeled and in the workstation folder. **Context for these programs:** Before we go further I'll give a brief rundown of these programs and what they're used for. **File Monolith:** You can't just open MGSV files like a folder and browse the ones you want and pick them out. So file monolith has tools that makes copies of the files within the MGSV archives and extracts them into a readable format. If you don't know how to use File Monolith refer to [this guide](/File_Monolith) to familiarize yourself. **Ravioli Game Tools:** So this is an open source tool kit that comes with a few things, we only need "Ravioli Explorer" because it can read the file that the game sounds are packed in and listen to each one without needing to unpack the archive. **Wwise 2015.1.9:** Don't ask why you need this specific version, it's just the one that works for some reason. Downloading it and getting it working is tricky so I'll elaborate on that soon. But what this does is it converts the soundfile you want to add into a format the game can read, that being ".wem" **Snakebite Mod Manager:** Once you are done replacing the files it allows you to pack and install mods without damaging the original game files. Familiarize yourself with [this guide](/SnakeBite_Mod_Manager). **Audacity:** This is a generic audio editing tool, basically we need it to make any adjustments to sounds before we put them in the game. MGSV sounds also have different attributes depending on what they're used for and we will use audacity to make sure the attributes of the sound we want to add match those that we want to replace. I'll go into detail on it later in this guide. **MGSV Sound Replacement Tool:** An amazing tool that allows us to take the sound files we spent so much time editing and creating and allows us to overwrite existing ones in the game. Will detail use later on in this guide. **Downloading Wwise:** When you try and download Wwise 2015.1.9 from their website, it'll likely prompt you to make an account and sign in, unfortunately to avoid legal altercations you're gonna have to do that. Make an account and sign in and it should take you [to this page](https://www.audiokinetic.com/download/): ![](/assets/Wwise%20home%20screen.png){:.thumb width="524px"} Using the image on above as a guide, click on "older versions", alternatively click [here](https://www.audiokinetic.com/downloads/previous/). ![](/assets/Wwise%20shit2.png){:.thumb width="522px"} It should now take you to the page in the above screenshot. Download "Windows Web Installer". Then click "Offline Setup for windows" to expand the category and download "Wwise Authoring (64-bit)" "Wwise Authoring Data" and "VC 2013 Redistributable (64-bit)". You may have the "VC 2013" file installed already but just download and run it anyways to be sure. Next step is to run all these files one at a time **except** the "windows web installer" that is last, because it will run a check if you have all these components installed. If you have all those parts installed then here is the kicker. You need to now turn off your internet and run the installer. Otherwise it will try and download the files and fail and kick you out. Once you have Wwise installed then you can turn the internet back on and move on. This is the hardest part of the process. ##### **Step 1: Find a sound you want to add** This is pretty self explanatory, you need to know what you want to add. I'm gonna just assume you have whatever sound you want to add saved as a .mp3 or .wav or something in your workstation folder. ##### **Step 2: Find the sound you want to replace** This is tricky. The sounds in MGSV aren't labeled, so you can't just search "footstep" and have it be labeled for you. You need to either know the name of the file you want to replace or go through the sound bank and listen to them until you figure out which one. Now in the game many different sounds are stored in many different parts of the games files. For the sake of this guide we'll assume you want to change a gunshot sound, which is located in common_bank_01.sbp in chunk0.dat. Once you have chunk0 unpacked it should be in "Assets\\tpp\\sound". You \*can\* do anything you want with the files here since they're just copies but what you should do is copy it and make a folder in your workstation folder and name it "original common sbp" or something so you know this is the vanilla game's sound bank. So before we go any further, you have two ways of identifying the sound you need to change. The first is by using the [sound codes](/Sound_Codes) page on the wiki. If you find the sound you're looking for keep node of it's file name. Countfuzzball also has some more sounds documented [here](https://docs.google.com/spreadsheets/d/1UYeaGqfZllUOZuiy0IMMf5A7fgFn4-fo5SQmT6BjKkQ/edit#gid=2132902213). The second is by using Ravioli Explorer. But before that we need to do one last thing. ###### **Step 2.5: Using MGSV Sound Replacement Tool** So the MGSV is a modified version of Wwise, with almost everything stripped away from it. The .exe will unpack and repack the common_bank_01.sbp we copied earlier. So make a copy of the "Wwise.exe" and put it in the same folder as "common_bank_01.sbp" then drag the .sbp onto the .exe to open it. This will create two folders, a Wwise_Input and a Wwise_Output. For now open the Wwise_Output folder and make a copy of "common_bank_01_BNK.log" this is a file that has the filename and info on every sound file in this sound bank. You'll need it. This isn't the last we'll be using the sound replacement tool but for now you can leave it alone. ###### **Finishing Step 2: Using Ravioli Explorer** You only need to use Ravioli Explorer if you do not know which file you want to replace yet. That is- you have not found the sound file you are looking for in the sound [codes section](/Sound_Codes). If you have not found it and need to look for the sound then you simply click on "Ravioli Explorer" and click open file at the top left then navigate to "Wwise_Output" then open "common_bank_01.bnk" from there you can navigate through all the sounds in this bank. Once you find the sound you're looking for write down the number somewhere. ##### **Step 3: Creating a replacement sound** Okay, you found which sound you want to replace, you know where it is, etc. Now we need to have a replacement for it. Replacing a sound file in MGSV is like giving a blood transfusion: it needs to match the original type or it will likely not work. It's quite simple but I'll start very basic anyways: There are two main types of sound in this game: Mono and Stereo. Stereo sound is more detailed and can be affected by various things in game such as being indoors, etc. When a player shoots a gun, the gunshot sound is stereo. Let's contrast this to Mono. Mono is generally lower quality, and isn't affected by as many things as stereo such as directional sound, sound propagation, echoing, etc. It just plays the sound with minor variables. When an enemy shoots a gun in game, it is mono and uses a different sound file. I mention this just to give you an idea of what is made stereo vs mono. The second thing is sample rate. This is basically a form of audio quality. I don't know much more than that and it's unimportant. So the gist is that when you find a sound, you need to open it with [audacity](https://www.audacityteam.org/), and make it [stereo or mono](https://www.wikihow.com/Change-a-Mono-Track-Into-Stereo-Track-Using-Audacity) depending on what the file you're replacing is, and match the [sample rate](http://www.dynamicsoflanguage.edu.au/research/data-archives/guides/resampling-audio-using-audacity/). ###### **Step 3.5 Finding audio file details** Alright so in order to match the sound quality of the new file with the old one, we need to know what the old one's information was. This is actually quite easy. Open up "common_bank_01_BNK.log" and this will give you the information on every sound file. Lets say we opened up Ravioli tools and want to replace "651564874" with something. Well we simply open up the log and search for "651564874". From the log I can see the real name of the file is "RIFF_0902.wem". Again the name that is "RIFF_XXXX" is the **REAL** name of the files. Keep note of that. Furthermore I can see that the file uses "PCM" as an audio format, is in Mono, and has a sample rate of 41,000Hz. Write all of these things down somewhere. ![](/assets/Sound%20shit2.png){:.thumb width="504px"} ###### **Finishing Step 3: Creating the sounds** So the rest of this is self explanatory. Match the sample rate and audio type (Mono or Stereo) in audacity then export the file from audacity. Export it as a .wav for simplicity. You should put it and whatever other sounds you want to add in a folder and rename each file to be "RIFF_XXXX" obviously replace the XXXX with the number of the file you want to replace. ##### **Step 4: Converting your new audio files** Let's make sure we're on the same page: You should have your new file(s) in .wav format, renamed to the files you want to replace such as "RIFF_0902.wem" or something. These files also match the sample rate and sound type as the original. If you're at this point you are almost done, don't worry. Let's now open up Wwise 2015.1.9, not the Wwise.exe we used earlier. [Here](https://www.youtube.com/watch?v=H33bRnUHT54&t=186s) is a link to a video by Cuba on this part of the procedure, the relevant part is from 1:18 to 2:26. Make a new project, then press "shift + K" then click on "source settings" then click the three dots next to "Default Conversion Settings" ![](/assets/More%20wwise%20shit.png){:.thumb .legacy-small width="222px"} After you click that it should open up a new box that gives you some options to convert the sounds. This is mostly mumbo jumbo to me, here's what matters: Remember the info about the sound file you got from the log earlier? It said PCM, Mono, and 41,000Hz. This is the part where we convert the new files to PCM. Again, not every file will be PCM but the ones in "common_bank_01" are all PCM. I don't know what PCM means but we need to have it. ![](/assets/More%20wwise%20shit%202.png){:.thumb} Select "PCM as input" this will convert all files we add to this project to PCM. NOW we import the files to the Wwise project. Select project at the top, then click "Import audio files" if you have the files you want to add in one folder you can just select the folder. Once you have all your files in then click "project" then "convert all audio files" ![](/assets/Untitled.png){:.thumb} This will export all your audio files to the cache of your project folder. Which should be in WwiseProjects\\(Project Name)\\.cache\\Windows\\SFX ##### **Packing the files** Now take all the .wems and make sure their names are "RIFF_XXXX.wem" they might have a bunch of numbers at the beginning or end don't worry about it just delete them. Now we go back to the "common_bank_01.sbp" we have in our workstation. Go to the Wwise_Input folder, then the common_bank_01BNK folder then paste your new .wem files in there. Next drag the common_bank_01.sbp back onto the Wwise.exe once more, this time it will compile the new sounds and overwrite the old ones. You're done. Create a folder name it the name of your mod so for example I'll call mine "soundmod" I'll now create these folders: Soundmod\\Assets\\tpp\\sound then in the sound folder I place the common_bank_01.sbp. From here simply pack the file with snakebite then you're done. ### `wiki:wiki/How_to_create_custom_lang_entries.md` > This page is a mess and needs either a rewrite or a complete removal. > > You should use [Lang_Files](/Lang_Files) instead. {:.needs-revision} This tutorial will help you create your own lang entries instead of replacing them. This can be useful for when you create your own custom equips, staff members, or missions/locations. It is recommended that you read [Lang Files](/Lang_Files "wikilink") before following this tutorial. ##### Getting Ready Install [SnakeBite Mod Manager](/SnakeBite_Mod_Manager "wikilink"), which also includes MakeBite, the tool you need to build MGSV files. Download [GzsTool](/GzsTool "wikilink") and [LangTool](/LangTool "wikilink") then extract them to their own folders. ##### lang_default_data_XXX.fpk If you haven't extracted **lang_default_data_\.fpk**, you can extract it from **chunk0.dat** by drag & dropping it on [GzsTool](/GzsTool "wikilink"). Once extraction is finished, go to your mod's project folder and create this directory structure **Assets\\tpp\\pack\\ui\\lang\\.** Copy **lang_default_data_\.fpk** to **Assets\\tpp\\pack\\ui\\lang\\**. Last step, open [MakeBite](/SnakeBite_Mod_Manager "wikilink"), select the mod's project folder, build the MGSV file as it will also extract all FPKs. Alternatively, you can drag & drop **lang_default_data_\.fpk** onto [GzsTool](/GzsTool "wikilink"). If you're unsure which language to modify, choose **eng (english)**. You can provide support for other languages if you'd like. ###### Creating new entries If you're only adding custom lang entries, remove all lng2 files inside of the FPK from the **"\\Assets\\tpp\\lang\\ui"** directory. It should be empty so it doesn't overwrite any existing entries. ###### Modifying existing entries Inside that directory, you'll find lng2 files for staff, weapons, items, dialogues, etc. If you're interested in modifying existing lng2 files, you can use the [LangTool](/LangTool "wikilink") to decompile them as XML files by drag and dropping them on [LangTool.exe](/LangTool "wikilink"). From there, you can edit the XMLs and compile new lng2 files from them. Whatever lgn2 files you don't modify, should be removed as well. **NOTE: Decompiling lng2 files might replace langIDs with keys, which are StrCode32 versions of them.** ##### Lang XML Template Below is an example XML script which you can use to setup your very own lang entries\! When you replace the LangIDs, make sure they're unique enough. You can copy the following snippet and paste it into a text editor, make your modifications, and save it as an XML file, rename the extension to **".lng2.xml"**. ```xml                      ``` ##### Compile lng2 file Next, drag and drop your lang XML file onto [LangTool.exe](/LangTool "wikilink"). It should compile the XML as a [lng2 file](/Lang_Files "wikilink") in the same directory. If it doesn't, check if your XML file is missing any opening or closing quotes or tags, such "\" or "\". Once it successfully compiles it as a lng2 file, you can add it in the **\\Assets\\tpp\\lang\\ui** directory inside your custom **lang_default_data_\.fpk**. ##### Using your custom lang entries for equips To setup an equip's lang entries, you have to change their development const settings. | | | | ------- | ---------------------------------------------------------------------------------------------------- | | **p00** | The DevConst ID for the equip. | | **p06** | The langId for the equip's name in the iDroid development menu and Hud. | | **p07** | The langId for the equip's description in the iDroid development menu and Hud | | **p30** | The langId for the equip's full name shown in the infobox displayed in the iDroids development menu. | ###### Setting it up for Zeta For Zeta mods, you can create new equips or alter existing equips without overwriting **EquipDevelopConstSetting.lua**. If altering an equip, **p00** should match the DevConst ID of the equip you wish to change. \[Coming Soon: A tutorial for creating custom equips in Zeta will be linked here\] ```lua function this.EquipDevelopConstSetting() return{ { p00=XXX, --Should match the DevConst ID p06="name_wp_XXX", p07="info_wp_XXX", p30="real_wp_XXX", }, } end ``` ###### EquipDevelopConstSetting.lua For legacy MGSV mods, you have to modify **EquipDevelopConstSetting.lua** to replace an equip's lang entries. Each **RegCstDev** call sets an equip's devconst parameters. You can modify an existing entry or create your own, and set the **p06, p07, p30** parameters to use your entries instead. `TppMotherBaseManagement.RegCstDev{` `   p00=XXX,` `   p01=TppEquip.EQP_XXX,` `   p02=TppMbDev.EQP_DEV_TYPE_XXX,` `   p03=XXX,` `   p04=XXX,` `   p05=XXX,` `   `**`p06`**`="name_wp_XXX",` `   `**`p07`**`="info_wp_XXX",` `   p08="/Assets/tpp/ui/texture/EquipIcon/XXX",` `   p09=TppMbDev.EQP_DEV_GROUP_XXX,` `   p10="ability_XXX",` `   `**`p30`**`="real_wp_XXX",` `   p31=XXX,` `   p32=XXX,` `   p33=XXX,` `   p34=XXX,` `   p35=XXX,` `   p36=XXX` `}` ##### Using your custom lang entries for staff Unique staff members can have their own unique names. Fortunately, all that needs to be changed is the **nameLangMessageId**. ###### Setting it up for Zeta For Zeta mods, you can create new unique staff or alter existing staff without overwriting **MbmCommonSetting.lua**. If modifying a unique staff member, **uniqueTypeId** should match the uniqueTypeId of the unique staff member you wish to change. \[Coming Soon: A tutorial for creating unique staff members in Zeta will be linked here\] ```lua function this.MbmCommonSetting() return{ uniqueStaff={ { uniqueTypeId=XXX, --Should be unique to the staff member nameLangMessageId="unique_staff_XXX", }, }, } end ``` ###### MbmCommonSetting.lua For legacy MGSV mods, you have to modify **MbmCommonSetting.lua** to replace an equip's lang entries. Each **RegisterUniqueStaff** call sets a unique staff member parameters. You can modify an existing staff member or create your own and set the **nameLangMessageId** parameter with your custom langID. `TppMotherBaseManagement.RegisterUniqueStaff{` `   uniqueTypeId=XXX,` `   `**`nameLangMessageId`**`="staff_name_XXXXX",` `   combatSectionPoint=XXX,` `   developSectionPoint=XXX,` `   baseDevSectionPoint=XXX,` `   supportSectionPoint=XXX,` `   spySectionPoint=XXX,` `   medicalSectionPoint=XXX,` `   skill=XXX,` `   isEnmity=XXX,` `   moraleEnmity=XXX,` `   condition=XXX,` `   badConditionWeight=XXX,` `   langProficEnglish=XXX,` `   langProficRussian=XXX,` `   langProficPashto=XXX,` `   langProficKikongo=XXX,` `   langProficAfrikaans=XXX,` `   missionId=XXX` `}` ### `wiki:wiki/How_to_replace_sortie_prep_music_in_less_than_five_minutes.md` **This video assumes you have unpacked your game with File Monolith and have SecaProjects SBP Tool, Wem Converter and Wwise installed.** You will also need a basic understanding of MakeBite and how to use SnakeBite Mod Manager. [File Monolith](https://www.nexusmods.com/metalgearsolidvtpp/mods/739) [SBP Tool](https://mega.nz/file/SVxHWQ6D#Y9UcP0t61XG5q_I3ObTZxMTsGnupNBMUZ0-llfz3aFs) **[Sound Converter](https://mega.nz/file/uZxjWaga#H9blO_Zdw_s75ghccGKOKFIMlKtDpR5Bma7bQq2pVq8)** Alternative to Sound Converter, [vgmstream](https://github.com/vgmstream/vgmstream-releases/releases/download/nightly/vgmstream-win64.zip) [Wwise 2015](https://mega.nz/file/HcxVBYjC#KBYOI1EQ54iFYgwF-oWi0tTuPAPlDgf-Y743CzQdTRI) ###### Part 1: Locating the .sbp and extracting it To start off, you will need to find **common_bank_01.sbp.** located in **Assets/tpp/sound/asset**. Once you have found it copy it into your working folder, then drag it onto the SBP Tool. This will create a folder called common_bank_01 and extract it into .wems we can work with. Now open the new common_bank_01 folder and go into the stp folder. There you will find **3cb314cd.wem**, This is the sortie prep music file. ###### Part 2: Converting and finding a replacement Now you have **3cb314cd.wem** you should copy it into the sound converter folder alongside **divinity_converter.exe**. Double click the exe and it will convert the .wem into a .ogg inside the NUMBERED folder. Just to be safe, listen to it to make sure you got the right file. Now comes the fun part, find a piece of music you think would sound good and make sure its in the **.wav** format. Now open **Wwise 2015** and create a new project, go to **File** up the top left and down the menu to **Project Settings.** Click on the **Source Settings** tab then **Default Conversion Settings**, Change it to **Vorbis Quality High**. Now click ok on both panels to save your new settings. ###### Part 3: Wav to Wem At this point you should have your new music in wav format ready to be imported into Wwise. Click **File** up the top left and go down to **Import Audio files**, after clicking this a new window will pop up and you must drag your .wav into it. Now click the import button. Once done head back up to the top left and click on **File** once more then down to **Convert All Audio Files**. Make sure **Windows** is ticked then click ok and your wav has been successfully converted\! Finally, Head to **(User)/Documents/WwiseProjects/(projectname)/Windows/SFX.** Your .wem will be there. ###### Part 4: Replacing and Repacking Copy your new .wem back to your working folder and into **common_bank_01/stp**, now delete **3cb314cd.wem** rename your new .wem to **3cb314cd**. Once this is done go back to the folder with **SBP Tool**, The **Common_bank_01 Folder** and **Common_bank_01.sbp**. Rename **Common_bank_01.sbp** to something like **Common_bank_01_Backup** for safety, Then drag the **Common_bank_01 Folder** onto **SBP Tool**. This will create a new **Common_bank_01.sbp**. ###### Part 5: Making your mod Create a new folder structure like: **Assets/tpp/sound/asset** and place your new **Common_bank_01.sbp** inside. Open **MakeBite** and build your mod, make sure you fill out the name and description so you don't forget what the mod does. Once created, install your mod with **Snakebite** and you are done\! ### `wiki:wiki/IHHook.md` A proxy dll (of dinput8.dll) that loads with MGSV to provide extended features for modding. Previously bundled with [Infinite Heaven](/Infinite_Heaven "wikilink"), IHHook has been split into a separate install and nexus page to isolate feedback and issues. ##### Requirements - MGSV version 1.15 (in title screen), 1.0.15.3 in exe. - [Infinite Heaven r258](/Infinite_Heaven "wikilink") - [Microsoft Visual C++ Redistributable for Visual Studio, x64](https://aka.ms/vs/17/release/VC_redist.x64.exe) ##### Features - [dear-IMGUI based menu for Infinite Heaven.](https://youtu.be/ERL7okZVcW4) - Lua C API support (mostly complete): Allows extending the MGSVs embedded lua via C. Does not have dynamic library support as mgsv lua is statically compiled, and running the mgsv lua state through a seperate distro of lua isn't desirable since the mgsv lua core is modified from default. However it is possible to compile lua C modules into IHHook. - Logging via spdlog: Infinite Heaven uses this for better performance (mostly used for debugging). Has it's own separate log for debug/info output. - Named Pipe server: Starts up a threaded Named Pipe server with two pipes mgsv_in, mgsv_out. Currently used by Infinite Heaven to improve performance when using IHExt and should open further possibilities I was reluctant to pursue due to old text file based IH\>IHExt communication. - CityHash logging (currently has to be compiled in with a \#define) using emooses cityhash logging (though using spdlog for better performance) that IHHook was initially built off. - RawInput keyboard processing and blocking (proof of concept) **[See this Youtube playlist for features that are visually demonstratable](https://www.youtube.com/playlist?list=PLSKlVTXYh6F9XCIpHUGTSkd9gDzoU6N1s).** ### `wiki:wiki/I_want_to_mod.md` - ## Missions - [Mission objectives](/Mission_Objectives) - [Creating a basic custom route](/Creating_a_basic_custom_route/) - [Create a custom location](/Create_a_Custom_Map) - [Using UAVs in Side-Ops](/Using_UAVs_in_Side_Ops) - ## Models - [Export and modify models](/Using_FMDL_Studio_with_Blender/) - [Swap model parts](/Mesh_Mashup) - [Custom weapon models](/Custom_weapons) - [Hair](/Hair_Materials) - ## Textures - [Retexturing models](/Retexturing_the_Bionic_Arm/) - [Emblem](/Emblem/) - ## Weapons - [Weapon part combinations](/Chimera_Weapon_System/) - [Iron Sight adjustments, fire-rate, draw and reload speeds](/Iron_Sight_adjustments,_fire-rate,_draw_and_reload_speeds/) - [Enable NPC Weapons](/Enabling_CS_Weapons/) - [Change damage](/Damage_Tables/) - [Custom models](/Custom_weapons) - [Development requirements](/EquipDevelopSetting/) - ## Sound - [How to add custom sounds](/How_to_add_custom_sounds) - [How To Find & Change Audio Files](/How_To_Find_&_Change_Audio_Files) - [How to replace sortie prep music in less than five minutes](/How_to_replace_sortie_prep_music_in_less_than_five_minutes) - [Creating a Custom Sound Bank](/Creating_a_Custom_Sound_Bank) - ## Radio - Need a guide! - ## Animations - Need a guide! - ## UI - Need a guide! - ## Language / Text - [Changing and adding localized text](/Lang_Files) - [Localization](/Localization) - ## Rendering - [Attaching graphics debuggers](/Attaching_graphics_debuggers/) - [Color processing](/FILTERLUT_Texture_Guide/) - [Textures](/Textures) - [NVG filter](/NVG_Filter) - ## Cutscenes - Need a guide! - ## Effects - [Spawning a custom effect using FoxKit](/FoxKit-_TppPrimRiverModel_TppWaterBounding_TppTextureLoader_and_FxLocatorData) - ## Fonts - Need a guide! - ## Vehicles - Need a guide! - ## Exe - [Ghidra](/Ghidra_tips) {:.index} ### `wiki:wiki/Input_Handling.md` Input is handled by checking bitflags on `PlayerVars.scannedButtonsDirect`. Example, triggered by pressing `RELOAD` button (`R` by default): ``` if bit.band( PlayerVars.scannedButtonsDirect, PlayerPad.RELOAD ) == PlayerPad.RELOAD then ... end ``` ##### Bitflags (keys) ``` DECIDE = 0 STANCE = 1 DASH = 2 HOLD = 3 FIRE = 4 RIDE_ON = 5 RIDE_OFF = 5 ACTION = 5 MOVE_ACTION = 5 JUMP = 5 RELOAD = 6 STOCK = 7 ZOOM_CHANGE = 7 VEHICLE_CHANGE_SIGHT = 7 MB_DEVICE = 8 CALL = 9 INTERROGATE = 9 SUBJECT = 10 UP = 11 PRIMARY_WEAPON = 11 DOWN = 12 SECONDARY_WEAPON = 12 LEFT = 13 RIGHT = 14 VEHICLE_LIGHT_SWITCH = 14 VEHICLE_TOGGLE_WEAPON = 14 CQC = 15 SIDE_ROLL = 16 LIGHT_SWITCH = 17 EVADE = 18 VEHICLE_FIRE = 19 VEHICLE_CALL = 20 VEHICLE_DASH = 21 BUTTON_PLACE_MARKER = 22 PLACE_MARKER = 22 ESCAPE = 23--tex Not in PlayerPad own name ``` ##### Notes `DASH`, `HOLD`, `FIRE`, `SUBJECT` and `CQC` aren't listed in exe for whatever reason but are used at different points in script. I worked through it all manually anyway back when, both printing out the value of the flags and testing flags that would fall in the gaps. The numbers on the list are the pow values, so do 2^flag index (except for ALL obviously) if for whatever reason you want to use a direct value, though not much use since they mostly seem accounted for. `ESCAPE` (my naming) is a bit odd, figured it out manually from the next logical value/outputting scannedbuttons, but there's no actual matching use of it I could see in the scripts, it's not strictly the Pause binding since it's still set on press even if Pause is rebound. 2^24 is set on both quick dive and RS click, which has so much bound to it that I can't really figure out what it's supposed to signify. Testing 2^25 to 2^32 (assuming uint) didn't come up with anything further, though it can't remember how exhaustively I tested those (it's been a while) You'll see a bunch of the flags use the same values, which means there's no way to differentiate on those when pressed. The naming of the functions band/bor/bxor and the rest in the exe suggest fox engine is using an implementation of bitops http://bitop.luajit.org `STICK_L`, `STICK_R`, `TRIGGER_L`, `TRIGGER_R`, `TRIGGER_ACCEL`, `TRIGGER_BREAK` are used with other functions/variables/not used with `scannedButtons` See Infinite Heavens `/Assets/tpp/script/ih/InfButtons.lua` for some more notes. ### `wiki:wiki/Iron_Sight_adjustments,_fire-rate,_draw_and_reload_speeds.md` Iron sight adjustments can be made to guns, this is needed specially for custom model guns. These values are in EquipParameters.lua which can be found on: TPP > \\0\\00_dat\\Assets\\tpp\\level_asset\\weapon\\ParameterTables\\parts > - *With Snakebite* > \\data1_dat\\Assets\\tpp\\level_asset\\weapon\\ParameterTables\\parts > - *Without Snakebite* MGO > chunk0_dat\\Assets\\mgo\\level_asset\\weapon\\ParameterTables\\parts After we locate the file we have to search for *receiverParamSetsBase=* Each section {} belongs to a weapon, the order follows the same in-game order. Here is what we know so far what each value does: ![](/assets/Values-1.png){:.center .thumb width="662px"} The names are self explanatory. Here we will focus on iron sight alignment, as you can see there are 2 iron sights, here is an image showing this: ![](/assets/Iron-Sights.png){:.center .thumb width="621px"} The sights used to look like this before getting fixed: ![You](/assets/Adamaska.png){:.center .thumb width="682px"} gotta find an alignment between the two sights First Iron sight; 1 being the center, the higher the value, the farther the view will be, example value 111 ![](/assets/Right%20-%20Down.jpg){:.center .thumb width="680px"} The less the value the closer it will be (zoomed in) example -111 ![](/assets/-111.jpg){:.center .thumb width="678px"} You can see it completely skips the second sight. If 1 is the ''center ''you will usually will want to work with decimals when aligning. Second iron Sight; The second sight usually deals with depth, just like the first one 1 being the "center" although this time the higher the closer, example of 111 ![](/assets/Zoom1.jpg){:.center .thumb width="680px"} Example of -111 ![](/assets/-111%20middle.jpg){:.thumb width="678px"} Just as a reference this is how it looks with the vanilla values: ![](/assets/Vanilla%20(i%20like%20vanilla%20Ice-cream).jpg){:.center .thumb width="500px"} The rest of the values are self evident, Fire-rate takes care of the fire-rate of the weapon the higher the faster, draw speed is how fast the player pulls the weapon and aims, this sometimes gets affected by other factors like snake's arm or certain abilities either on tpp or mgo, for that it is better to play with decimals the closer to 1 the faster, the farther the slower, reload speed works the same way. Aim-assist distance is calculated in meters. ### `wiki:wiki/LBA.md` The .lba file format is a binary file format used in GZ and TPP to store locator data for [gimmicks](/Gimmick "wikilink"). Its technical name is unknown, but it's referred to in [DataSets](/DataSet "wikilink") as a *locaterFile* (sic) and is unofficially called a GimmickLocatorSet by FoxLib. ##### Usage While most entities have their transforms specified by a [Locator](/Locator "wikilink"), [TransformData](/TransformData "wikilink"), or [TransformEntity](/TransformEntity "wikilink") in a DataSet, gimmicks instead pull their transform from a .lba file. An example can be found in s10070_gimmick.fox2\[1\]: ```xml gntn_cntn001_vrtn001_gim_i0000|TppPermanentGimmick_gntn_cntn001_vrtn001 0x06C69D20 /Assets/tpp/parts/environ/object/guantanamo/container/gntn_cntn001/gntn_cntn001_vrtn001.parts /Assets/tpp/level/mission2/story/s10070/lba/gntn_cntn001_vrtn001.lba 0x00000000 1 0 ``` In this case, when the gimmick is spawned, gntn_cntn001_vrtn001.lba is read to determine where it should be placed. This has a few advantages over specifying the transform directly in the DataSet: most importantly, it's possible to query the Locator in Lua and to grab a reference to the gimmick from its Locator. The ID of a gimmick can be obtained in Lua by calling `TppGimmick.GetGimmickID(gameId, locatorNameHash, dataSetNameHash)` Where gameId is a TppGameObject type ID\[2\], locatorNameHash is the StrCode32 hash of the locatorName (in this example, *gntn\_cntn001\_vrtn001\_gim_i0000|TppPermanentGimmick\_gntn\_cntn001\_vrtn001*), and dataSetNameHash is the PathFileNameCode32 hash of the dataSetName (in this example, */Assets/tpp/level/mission2/story/s10070/s10070_gimmick.fox2*). Many TppGimmick functions take in a gimmick ID, such as TppGimmick.GetGameObjectId and TppGimmick.SetVisibility. By using these functions, you can perform various operations on gimmicks through scripting, such as showing them, hiding them, breaking them, querying their location, querying their broken status, and sending messages when their state changes. ##### Format There are three known types of gimmick locators. Their technical names are unknown but have been given unofficial names in FoxLib: - **PowerCutAreaGimmickLocators** are used by TppGimmickPowerCutAreaData entities. They have a position and rotation. As they have no locatorName, it's unknown if they can be accessed through Lua or how they're referenced by the engine at all. - **NamedGimmickLocators** are by far the most common variety. They have a position, a rotation, a locatorName, and a dataSetName. When creating a custom .lba file, this should be the default format unless you're working with TppGImmickPowerCutAreaData entities or wish to scale the gimmick. - **ScaledGimmickLocators** are a rare variety which appear to be usable anywhere a NamedGimmickLocator is used. They have a position, a rotation, a scale, a locatorName, and a dataSetName. The scale format is still not fully understood. All known ScaledGimmickLocatorSets have the suffix \_scl in the filename (e.g., *cypr_cabl002_vrtn001_scl.lba*). ###### Header - 0x0 - 0x3 (uint32): Number of locators. - 0x4 - 0x7 (uint32): Locator type. 0 indicates PowerCutAreaGimmickLocators, 2 indicates NamedGimmickLocators, and 3 indicates ScaledGimmickLocators. - 0x8 - 0xF: Padding. ###### Transforms This section, the main body of the file, contains one entry for each locator. Its content differs depending on the type of locator. PowerCutAreaGimmickLocators and NamedGimmickLocators use unscaled transforms and ScaledGimmickLocators use scaled transforms. ###### Unscaled transform struct - 0x0 - 0x3 (float): World space position, x coordinate. - 0x4 - 0x7 (float): World space position, y coordinate. - 0x8 - 0xB (float): World space position, z coordinate. - 0xC - 0xF (float): World space position, w coordinate. - 0x10 - 0x13 (float): World space rotation quaternion, x coordinate. - 0x14 - 0x17 (float): World space rotation quaternion, y coordinate. - 0x18 - 0x1B (float): World space rotation quaternion, z coordinate. - 0x1C - 0x1F (float): World space rotation quaternion, w coordinate. ###### Scaled transform struct - 0x0 - 0x3 (float): World space position, x coordinate. - 0x4 - 0x7 (float): World space position, y coordinate. - 0x8 - 0xB (float): World space position, z coordinate. - 0xC - 0xF (float): World space position, w coordinate. - 0x10 - 0x13 (float): World space rotation quaternion, x coordinate. - 0x14 - 0x17 (float): World space rotation quaternion, y coordinate. - 0x18 - 0x1B (float): World space rotation quaternion, z coordinate. - 0x1C - 0x1F (float): World space rotation quaternion, w coordinate. - 0x20 - 0x23 (float): World space scale, x factor. - 0x24 - 0x27 (float): World space scale, y factor. - 0x28 - 0x2B (float): World space scale, z factor. - 0x2C - 0x2D (uint16): Unknown value A. - 0x2E - 0x2F (uint16): Unknown value B. ###### Footer The footer, only present in NamedGimmickLocatorSets and ScaledGimmickLocatorSets, has one entry for each locator. ###### Footer struct - 0x0 - 0x3 (uint32): StrCode32 hash of the locatorName. - 0x4 - 0x7 (uint32): PathFileNameCode32 hash of the dataSetName. ##### References 1. Assets\\tpp\\level\\mission2\\story\\s10070\\s10070_gimmick.fox2 2. ### `wiki:wiki/LangTool.md` LangTool is an open-source Fox Engine XML compiler/decompiler for Metal Gear Solid V: Ground Zeroes and Metal Gear Solid V: The Phantom Pain created by Atvaark. It is capable of reading the data from lng and lng2 files and converting them into XML files, where users may read and edit them. It can also do the opposite, converting XML files into lng/lng2 files. ##### Usage To decompile a lng or lng2 file, the user simply needs to drag the file onto LangTool. To compile a decompiled lng file, the user simply needs to drag the lng.xml file onto the tool. ##### Dictionary LangTool utilizes a dictionary of filenames called lang*_dictionary.txt.* As it decompiles the lng, it compares the hashes generated from this dictionary to any hashed keys it finds. If it finds a match, it will output the string by it's real name with the XML attribute 'LangId'. If it cannot find a match, it will output the string by its hash with the XML attribute 'Key'. The most current dictionary can be found here: ### `wiki:wiki/Lang_Files.md` Lng/lng2 files aka lang files are lists of strings used for localization of text, mainly used for UI. Mostly found in `Assets\tpp\pack\ui\lang\lang_default_data_.fpk` ``` 0/00.dat/Assets/tpp/pack/ui/lang/lang_default_data_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_challenge_task_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_emblem_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_event_item_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_fob_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_parts_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_ps3_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_ps4_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_stm_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_x36_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_xb1_eng.fpk 0/00.dat/Assets/tpp/pack/ui/lang/lang_tpp_tips_info_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_default_data_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_database_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_emblem_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_fob_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_mbhelp_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_mbhelp_fob_cstm_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_parts_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_ps3_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_ps4_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_stm_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_x36_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_system_xb1_eng.fpk chunk0.dat/Assets/tpp/pack/ui/lang/lang_tpp_tips_info_eng.fpk ``` Remember, `00.dat` takes priority over chunk files. Fox Engine will load **all** lng2 files from a pack (fpk) enabling addition of completely new .lng2 files. ###### Language codes List of language codes: | code | name | |---|---| | 00 | jpn | | 01 | eng | | 02 | fre | | 03 | ita | | 04 | ger | | 05 | spa | | 06 | por | | 07 | rus | | 08 | ara (tpp, unused) | | 09 | cht (survive) | | 10 | kor (survive) | ###### Converting lng/lng2 files can be converted to and from editable xml files using [LangTool](/LangTool). Alternatively, [datfpk](https://github.com/unknown321/datfpk) can be used for the same purpose. The converted lng2 xml localization string entries will look like: ```xml ``` Key is a `Fox.StrCode32` hash of the lua key string, most commonly refereed to at langId in the lua scripts. It will be replaced by `LangId` if there is a matching entry in LangTool dictionary (4191827342 resolves to `key_poster_3500`). Color is...? ###### String formatting Localization strings support string formatting characters, in the above entries seen as `%s` for another langId, `%d` for a number. What it will accept however seems dependent on the function. AnnounceLogViewLangId will only accept the string, number, or two numbers as its parameters, other combinations may lock the game up. Evidence from other localization strings in lng2 files suggest other functions are less restricted. ###### Lua usage ```lua TppUiCommand.AnnounceLogViewLangId("announce_get_gravure", "key_poster_3500", 500) TppUiCommand.ShowPopup("key_poster_3500", Popup.TYPE_ONE_BUTTON) ``` If a langId is called without a matching entry in the particular language lang file it will return empty string. ###### Lng2 file notes The following is a partial list of lng2 files and an explanation of what they are: ###### lang_default_data_eng.fpk | name | note | |---|---| | mb_staff_name | List of all possible Mother Base Staff codenames. Split into "firstname lastname" entries for unique staff such as Silent Basilisk, Doom Kangaroo and Laughing Wallaby, and two sets of random generator staff name for first, then last codenames, for each gender. | | tpp_announce_log | List of all the text that goes into the Log tab of the iDroid (All the messages displayed on the left hand side of the screen during gameplay). Includes, but not limited to: Buddy status messages, FOB status messages (espionage points), obtaining/developing equipment messages, Diamond Dogs Unit level increases and decreases, Platform construction heroism points messages, etc, etc. | | tpp_cassette | Contains all info tape titles ("Afghanistan Today \[3\]"), in-game/licensed music tape titles ("MGO Trailer Music") and ambient/collectable tape titles ("Quiet's Humming") | | tpp_cast_staff | Contains the names displayed during the opening mission credits roll. ("Benedict "Kazuhira" Miller", ""SKULLS" Parasite Unit"). | | tpp_common | Catch-all for many different things, both UI and game-world such as:
- Title of the bases/outposts when viewing them in the iDroid map or entering them in-game
- Unit Suitability dialog in Staff Management
- Info dialog about each Unit's function and staff skills (troublemaker, etc)
- "DMG", "ZZZ", "SMK" text, as well as weapon type, attachments, ammo types and grenade type text
- Vehicle descriptions
- Resource names, for materials and plants

Generally a lot of the sortie prep text is here | | tpp_dialog | Contains the text for the pop-up dialog and confirmation boxes players will encounter. Platform/item development confirmation boxes, reassigning staff dialog boxes, etc. | | tpp_emblem | Contains a list of all the names of the emblems when creating a new emblem. | | tpp_gmp_mission | Contains all text for dispatch mission types. Both the short "outpost defense" and "plants gathering" ones, and the "main"/riskier dispatch missions, including long description text for them. | | tpp_hud | Contains the hud text items when playing missions or in free-roam. Includes Buddy/Interrogation actions (and long text descriptions of the actions), compass directions, commencing/stopping side ops/FOB alert text and long text descriptions of licensed songs. | | tpp_item | Contains a list of every single developable item and its long text description, as well as Key Items, Photos and Blueprint names. Uniforms, buddy equipment are all here, as are the Codenames attained during mission completion. | | tpp_mb | Contains Motherbase Staff assignment text, all the buddy markers text (Quiet, D-Dog, D-Horse) and iDroid map text ("Enemy Predicted FOM"), including intel/d-dog finds such as Cassette Tapes, Trucks, Materials, etc. Also includes the text for the tape player, and some FOB help text. Of note is the log_speaker and marker_chara entries, which define what text will appear when certain characters' actions get put into the iDroid's Log tab. | | tpp_menu | Contains the descriptions for the Options menu settings, Game Over screen text. Mother Base staff assignment/reassignment and Unit levels and lots and lots of the iDroid text descriptions for resupply, buddy drop points and menu text for the iDroid itself/sub-menus of the iDroid. | | tpp_mission | Contains all main mission text from the "Missions" tab of the iDroid. Mission name, mission description and all mission tasks are listed here. | | tpp_quest | Contains all side-ops text from the "Side-ops" tab of the iDroid. Mission name and mission description are listed here. | | tpp_record | Contains all the text for the "Records" tab of the iDroid. | | tpp_tips | Lists the title of all the tips displayed in the pause or loading screen menus. | | tpp_tutorial | Tutorial text (toggleable from the Options menu). short in-game text prompts for open/close iDroid, first aid, climb up/down ladder, etc. | | tpp_weapon | Contains a list of every developable gun and its long text description is here. This includes throwable explosives, deployable decoys/mines and grenade/rocket launchers too, along with ammo types and the special characteristics ("Live round conversion (Attack Type: Lethal)"). Suppressors are here too along with their durability rating, as are the various scope and barrel attachments. | ###### Lngs in Assets\\lang\\ui: | name | note | |---|---| | tpp_database | Contains all descriptions of Key Items, Photos and Codenames in the database. | ###### Mod examples - [Arabic localization](https://www.nexusmods.com/metalgearsolidvtpp/mods/2224) ### `wiki:wiki/Life.md` Player max life can be set in script via Player.ChangeLifeMaxValue(value) Default player life is defined as 6000 in \*player(s)\_game\_obj.fox2/TppPlayer2Parameter/lifeMax however this is only the value during the early game (as shown by vars.playerLifeMax) after mission 2 (first mother base visit) it bumps up to 6600 (6000\*1.1?) With medical hand grade 2 or higher (as snake or avatar), or with a DD soldier with the Tough guy skill this increases to 7801, which is a bit over 6000\*1.3 - 1.300166666666667 65535 is max of an unsigned 16 bit integer so the overflow to 0 makes sense. Scaling is 1.1 for ALL NORMAL soldiers (and scaling does exist) Scaling is 1.300166666666667 for "Tough Guys" (it's actually the same as Snake's) In free roam/missions, ALL NORMAL soldiers gain 1.1 first but "Tough Guys" (and Snake) then gain 1.300166666666667 on base 6000. Scaling downscale with damage/flies(time=stinky) will only drop by MAX x0.1 in 5 steps of x0.02 each So ALL NORMAL soldiers downscale to 1.0 "Tough Guys" (and Snake) downscale to 1.2 Downscale applies to all areas "Tough Guys" (and Snake) on MB gain 1.200166666666667 scale for some reason (even with scaling downscale NOT applied) while NORMAL soldiers do not gain a boost at all (it remains 1.0) I think the shower increases the scale itself so on MB "Tough Guys" (and Snake) get 1.2 max so it can become 1.3 after shower while NORMAL soldiers get 1.0 so it can become 1.1 after shower Once scaling decreases for one soldier, it remains decreased for ALL soldiers, meaning changing to any other character does not reset it and one does need to visit the shower on MB ### `wiki:wiki/Links_to_Useful_Github_Repos.md` Below is a list of useful links to GitHub repositories, mostly for historical and documentation purposes. | User | Description | Link | |---|---|---| | Atvaark | Contains latest releases of GzsTool, FtexTool, FoxEngineTranslationTool, and FoxTool. It also has an older reference of file formats in MGSV. | [Repo](https://github.com/Atvaark?tab=repositories) | | BobDoleOwndU | Responsible for containing the most extensive listing of tools and references in the community. Most notably, FMDL-Studio-v2, AutoPftxsTool, updated versions of FoxTool, FncpTool, FvTwool, and many useful references. Most active member in the scene. | [Repo](https://github.com/BobDoleOwndU?tab=repositories) | | emoose | Links to MGSV-QAR-Dictionary-Project, other than that no other focus on FOX Engine reversing. Seems to be involved with various games. | [Repo](https://github.com/emoose/MGSV-QAR-Dictionary-Project) | | Mobidslinky | Forks of commonly used tools in the modding scene. Contributed FileMonolith which is the most practical all-in-one tool for FOX Engine modification, as well as Side-Ops Companion enabling accessibility to modding to the community. Some experimental research has been displayed. User on an indefinite hiatus. | [Repo](https://github.com/JosephZoeller) | | TinManTex | Contains links to the most practical tools used for modding MGSV, such as SnakeBite, IHExt, validated dictionaries, older forks of FMDL-Studio and MtarTool, and plentiful utilities. Good reference material and history. | [Repo](https://github.com/TinManTex) | | Yazed0071 | Source for V Framework, a modding framework that bridges Lua and the game's executable, exposing native Fox Engine features (UI, sound, soldiers, bosses, vehicles) to Lua scripts. | [Repo](https://github.com/Yazed0071/V_Framework) | ### `wiki:wiki/Loading_Lua_files_externally_using_IH.md` ##### Using IH to load lua files externally (in MGS_TPP\\mod) instead of internally (in dat or fpkd) These methods should only be used to speed up developing a mod, when building a release version you should revert to using the lua files loaded normally/internally. ###### in-dat lua files: Simply copy the in-dat lua file to `MGS_TPP\mod` , while retaining the internal path ex copy: `-Whatever folder you extracted dat to-\Assets\tpp\motherbase\script\MbmCommonSetting.lua` to `MGS_TPP\mod\Assets\tpp\motherbase\script\MbmCommonSetting.lua` Edit your external lua, then quit and start the game again and IH should load the external lua. If there's an error IH should log that to `MGS_TPP\mod\ih_log.txt` , search for: 'ERROR' ###### in-fpkd lua files: Fox automatically loads the lua files in the fpkd when it loads it, so these need a workaround to get them to load an external lua file instead. 1\. Make a 'dev' folder in `MGS_TPP\mod\`, ex: `MGS_TPP\mod\dev\` 2\. Copy the fpkd lua you want to work on into that dev folder, rename it, just add something to the end of the name like f30050_sequence.lua to f30050_sequence_dev.lua 3\. At top of the existing in-fpkd lua file add: ```lua local loadExternal=true if loadExternal then   local fileName="f30050_sequence_dev.lua"   return InfCore.PCall(function()return InfCore.LoadSimpleModule(InfCore.paths.dev,fileName)end) end ``` Making sure the `fileName=` matches the external lua filename. 4\. Copy the same block of code from `local loadExtenal` to the `end` to the top of the external dev lua. Changing to `loadExternal=false` or you'll get an infinite recursion of loading until it fails lol 6\. Build/install your .mgsv Then whenever the game loads the in-fpkd lua that will load the external dev lua, and (if you have debugMode on, via IH debug menu) it will log parsing errors to ih_log.txt when it first loads. When you're ready to do a release build just copy the \_dev lua back over the in-fpkd lua (and double check the in-fpk lua has the `loadExternal=false` from the external lua) This method is useful depending on when the game loads/unloads the fpk. For mission scripts it means you can just quit the game (or quit to ACC), edit your \_dev lua in MGS_TPP\\mod\\dev\\ then restart the game and it will used the edited lua. For sideops scripts just exit the sideops loadArea, edit your external lua then return to the sideop loadArea, and it should load your external lua. ### `wiki:wiki/Localization.md` This guide will teach you how to localize *Metal Gear Solid V: The Phantom Pain* and *Metal Gear Solid V: Ground Zeroes*. #### Getting Started Currently, there is no straightforward way to *add* an entirely new language as an option in the game. This is due to the fact that language-related assets are embedded in `.exe` files and some UI components that have not yet been fully reversed. This guide will focus on what is achievable, such as modifying existing language packs and text files. ##### Needed Tools ###### To unpack game files We recommend using the [File Monolith Modmaker Toolset (Recommended)](https://www.nexusmods.com/metalgearsolidvtpp/mods/739) to unpack The Phantom Pain’s files. Alternatively, use the latest version of [GzTool](https://github.com/Atvaark/GzsTool/releases/tag/v0.6.0) to unpack and repack `FPK/FPKD` and `.dat` files for The Phantom Pain. For *Ground Zeroes*, use [GzTool v0.2](https://github.com/Atvaark/GzsTool/releases/tag/v0.2). For more detailed instructions, see [Unpacking and Organizing Game Files](https://mgsvmoddingwiki.github.io/Unpacking_and_Organizing_Game_Files/). ###### To unpack/repack `.ffnt`, `.subp`, `.lng/lng2` files Use [FoxEngine.TranslationTool](https://github.com/kapuragu/FoxEngine.TranslationTool/releases/tag/v0.2.9) to unpack `.ffnt`, `.subp`, and `.lng/lng2` files in *The Phantom Pain*. For *Ground Zeroes*, you can use the same tool except for `.lng` files, where only version [FoxEngine.TranslationTool v0.1.3](https://github.com/Atvaark/FoxEngine.TranslationTool/releases/tag/v0.1.3) works. ###### To unpack/repack `.fox2` files Use [FoxTool](https://github.com/Atvaark/FoxTool/releases/tag/v0.2.6) to unpack `.Fox2` (DataSetFile2). ###### Tip Always refer to the `README` section inside each tool for specific instructions on how to use the tool and additional details on the files it can unpack. #### Editing Fonts The game uses two types of font files: x 1. **`.ffnt` (Fox Font)** - This is the default font file, found in `\Assets\tpp\font\`. 2. **`.fnt` (Font)** - These are additional fonts used for specific UI elements (e.g., ZZZ, STN, or LOCKED during homing missile use). ##### `.ffnt` (Fox Font) To edit `.ffnt` files, use *FfntTool* found in [FoxEngine.TranslationTool](https://github.com/kapuragu/FoxEngine.TranslationTool/releases/tag/v0.2.9). ###### Another Way to Use FfntTool First, create an empty folder with the exact same name as the `.ffnt` file you want to edit. ![Empty Folder Example for .ffnt](/assets/Localization/Ffnt_Contents_Folder_Example.png) Then, drag and drop the `.ffnt` file into the *FfntTool*’s `.exe`. The contents of the `.ffnt` file will appear inside the folder. ![Contents of .ffnt file](/assets/Localization/Ffnt_Empty_Folder_Example.png) ###### GlyphMap The `GlyphMap` stores data about individual glyphs (characters like letters, numbers, punctuation, etc.). Each glyph entry includes properties like `Character`, `XOffset`, `YOffset`, `Width`, `Height`, and other spacing parameters. Example: ```xml ``` ![Example](/assets/Localization/Glyph_Example.png) ##### `.fnt` (Font) > *This section is TBA (To Be Added)*. {:.needs-revision} ##### Tip Some display text properties are stored in `.fox2` files, which can be found in `\Assets\tpp\pack\ui\ui_resident_data_fpkd\Assets\tpp\ui\GraphAsset\Common\data`. For more details, check out the [UiFontDataElement](/Entity_Reference/?/Fox/Ui/UiFontDataElement/) documentation. #### Subtitles Subtitles are stored in `.subp` files. These files are placed in specific paths, and their locations are set within a `.fox2` (DataSetFile2) file inside the `fpkd` files. When you open the `.fox2` file, you’ll find a class called `SubtitlesPackage` with two important properties: 1. `subtitlesPackage`: Loads the `.subp` files located inside the `fpk` (Fox Package) file with the same name. 2. `subtitlesStreamPath`: Loads `.subp` files from `\Assets\tpp\ui\Subtitles\`. To edit `.subp` files, use *SubpTool* from [FoxEngine.TranslationTool](https://github.com/kapuragu/FoxEngine.TranslationTool/releases/tag/v0.2.9). *SubpTool* generates an `.xml` file with the text to edit. ##### Tip In `tape.subp`, text will appear as `[C=XX]`, where `XX` represents the speaker’s name. For example: ```xml ``` The `[C=16]` represents the name of the speaker that will be displayed in the `Logs` from the idroid menu. So... don't remove it ;). ![Speaker Example](/assets/Localization/Log_Speaker_Ocelot.png) #### UI Unlike `.subp` files, `.lng` and `.lng2` files are stored within `\Assets\tpp\pack\` and scattered across directories like `\Assets\tpp\pack\mission2\common\`, `\Assets\tpp\pack\ui\`, or `\Assets\tpp\pack\ui\lang`. You’ll need to locate and edit these files manually. ### `wiki:wiki/Locations.md` A location is part of the system that represents a map/playspace. For a given location there may be one or more [Missions](/MissionCodes "wikilink"). See also [Custom Locations List](/Custom_Locations_List "wikilink") ##### Quick lookup More details for each location after the table. | locationId | locationName | name | | ---------- | ------------ | --------------------------------- | | 1 | init | | | 5 | title | | | 10 | afgh | Afghanistan | | 20 | mafr | Middle Africa | | 30 | cypr | Cyprus | | 40 | gntn | | | 45 | ombs | Old Mother Base / MSF Mother Base | | 50 | mtbs | Mother Base | | 55 | mbqf | Mother Base Quarantine Facility | | 60 | hlsp | helispace | | 70 | flyk | Kingdom of the flies | | 91 | sand_afgh | sandbox | | 92 | sand_mafr | sandbox | | 95 | sand_mtbs | sandbox | | mgo | | | | 101-105 | | mgo release maps | | 111-115 | | mgo dlc maps | | 150 | | mgo sandbox | | 200 | store | store_in_freeplay | | ssd | | | | 15-95 | TODO | Are in between tpp location ids | ##### Afghanistan/afgh ![Afghanistan. Location id 10. White areas are auto fulton traps (leaving them triggers fulton of NPCs within 5m of player). Numbers are LRRP indices.](/assets/afgh_cp_ob_fltn_lrrpNum.png){:.thumb .right} Afghanistan uses the standard **StageBlockControllerData**-class entity block streaming system. TBA ###### Large Blocks/Command Posts (cp) | Name | In-game name | LRRP number | | ---- | ------------ | ----------- | | bridge | Mountain Relay Base | 33 | | citadel | OKB Zero | 30 | | cliffTown | Sakhra Ee Village (Qarya Sakhra Ee) | 23 | | commFacility | Eastern Communications Post | 34 | | enemyBase | Wakh Sind Barracks | 36 | | field | Shago Village (Da Shago Kallai) | 29 | | fort | Smasei Fort (Da Smasei Laman) | 31 | | powerPlant | Serak Power Plant | 26 | | remnants | Lamar Khaate Palace | 28 | | ruins | Spugmay Keep | n/a | | slopedTown | Ghwandai Town (Da Ghwandai Khar) | 35 | | sovietBase | Afghanistan Central Base Camp | 27 | | tent | Yakho Oboo Supply Outpost | 24 | | village | Wialo Village (Da Wialo Kallai) | 32 | | waterway | Aabe Shifap Ruins | 25 | ###### Guard Posts/Observation Posts (ob) | Name | In-game name | LRRP number | | ---- | ------------ | ----------- | | citadelSouth | 01: Afghanistan Central Base Camp, East | n/a | | sovietSouth | 02: Afghanistan Central Base Camp, South | 39 | | plantWest | 03: Serak Power Plant, NW | 19 | | waterwayEast | 04: Aabe Shifap Ruins, East | 18 | | tentNorth | 05: Yakho Oboo Supply Outpost, NE | 22 | | enemyNorth | 06: Wakh Sind Barracks, NE | 07 | | cliffWest | 07: Sakhra Ee Village, NW | 08 | | tentEast | 08: Yakho Oboo Supply Outpost, SE | 06 | | enemyEast | 09: Wakh Sind Barracks, East | 38 | | cliffEast | 10: Sakhra Ee Village, East | 09 | | slopedWest | 11: Ghwandai Town, NW | 15 | | remnantsNorth | 12: Lamar Khaate Palace, North | 21 | | cliffSouth | 13: Sakhra Ee Village, South | 03 | | fortWest | 14: Smasei Fort, West | 10 | | villageWest | 15: Wialo Village, West | 04 | | slopedEast | 16: Ghwandai Town, SE | 11 | | fortSouth | 17: Smasei Fort, SW | 12 | | villageNorth | 18: Wialo Village, NE | 14 | | commWest | 19: Eastern Comm. Post, West | 02 | | bridgeWest | 20: Mountain Relay Base, West | 05 | | bridgeNorth | 21: Mountain Relay Base, SE | 37 | | fieldWest | 22: Shago Village, North | 20 | | villageEast | 23: Wialo Village, SE | 01 | | ruinsNorth | 24: Spugmay Keep, East | 13 | | fieldEast | 25: Shago Village, East | 16 | | plantSouth | n/a (removed) | 17 | ##### Middle Africa/mafr ![Middle Africa. Location id 20. White areas are auto fulton traps (leaving them triggers fulton of NPCs within 5m of player). Numbers are LRRP indices.](/assets/mafr_cp_ob_fltn_lrrpNum.png){:.thumb .right} Central Africa uses the standard **StageBlockControllerData**-class entity block streaming system. TBA ###### Large Blocks/Command Posts (cp) | Name | In-game name | LRRP number | | ---- | ------------ | ----------- | | banana | Bampeve Plantation | 25 | | diamond | Kungenga Mine | 26 | | factory | Ngumba Industrial Zone | 28 | | flowStation | Mfinda Oilfield | 21 | | hill | Munoko ya Nioka Station | 27 | | lab | Lufwa Valley | 29 | | outland | Bwala ya Masa | 20 | | pfCamp | Nova Braga Airport | 23 | | savannah | Ditadi Abandoned Village | 24 | | swamp | Kiziba Camp | 22 | | chicoVil | n/a (removed) | 34 | ###### Guard Posts/Observation Posts (ob) | Name | In-game name | LRRP number | | ---- | ------------ | ----------- | | swampWest | 01: Kiziba Camp, NW | 02 | | diamondNorth | 02: Kungenga Mine, NE | 18 | | bananaEast | 03: Bampeve Plantation, SE | 08 | | bananaSouth | 04: Bampeve Plantation, SW | 04 | | savannahNorth | 05: Ditadi Abandoned Village, NE | 09 | | outlandNorth | 06: Masa Village, North | 01 | | diamondWest | 07: Kungenga Mine, West | 10 | | labWest | 08: Lufwa Valley, NW | 19 | | savannahWest | 09: Ditadi Abandoned Village, North | 07 | | swampEast | 10: Kiziba Camp, SE | 06 | | outlandEast | 11: Masa Village, East | 03 | | swampSouth | 12: Kiziba Camp, South | 05 | | diamondSouth | 13: Kungenga Mine, SW | 11 | | pfCampNorth | 14: Nova Braga Airport, NE | 16 | | savannahEast | 15: Ditadi Abandoned Village, South | 13 | | hillNorth | 16: Munoko ya Nioka Station, NE | 12 | | factoryWest | 17: Ngumba Industrial Zone, West | n/a | | pfCampEast | 18: Nova Braga Airport, East | 15 | | hillWest | 19: Munoko ya Nioka Station, NW | 14 | | factorySouth | 20: Ngumba Industrial Zone, SW | 17 | | hillWestNear | 21: Munoko ya Nioka Station, West | 30 | | chicoVilWest | 22: Nova Braga Airport, South | 33 | | hillSouth | 23: Munoko ya Nioka Station, SW | 31 | | swampWestNear | n/a (removed) | 32 | ##### Cyprus/cypr Cyprus uses a unique **CyprusBlockControllerData**-class entity for its block streaming system. TBA locationId - 30 ##### Guantanamo/gntn The U.S. Naval Prison Facility uses the standard **StageBlockControllerData**-class entity block streaming system, however unlike TPP's maps, it does not utilize small blocks at all. TBA locationid - 40 ##### Old Mother Base/ombs Old Mother Base uses the standard **StageBlockControllerData**-class entity block streaming system, however unlike TPP's maps, it does not utilize small blocks at all. TBA locationId - 45 ##### Mother Base/mtbs Mother Base uses a unique **TppMotherBaseStageBlockControllerData**-class entity for its dynamic platform placement. TBA locationId - 50 ##### Mother Base Quarantine Facility/mbqf The Mother Base Quarantine Facility interior, unlike the main Mother Base map, instead utilizes the standard **StageBlockControllerData**-class entity block streaming system, however it uses only a 2x2 grid of small blocks aside from the common block, which only seem to contain [Nav2](/Nav2 "wikilink") navmeshes. TBA locationId - 55 ##### Helispace/hlsp Assets do not exist. All that exists is some orphaned mentions in a few scripts. TBA locationId - 60 ##### Kingdom of the Flies/flyk Assets do not exist. All that exists is some orphaned mentions in a few scripts and some environmental models in Metal Gear Survive. TBA locationId - 70 ### `wiki:wiki/NAV2.md` NAV2 (.nav2) is a navigation file associated with NPC "navmesh" map navigation. These filetypes are specifically present in Metal Gear Solid V: Ground Zeroes (2014), Metal Gear Solid V: The Phantom Pain (2015), and Metal Gear Survive (2018). Tools for editing NAV2 are available. ### `wiki:wiki/NTA.md` A **.nta** file specifies the locations of traversal actions in the world. ##### Format ###### Header - 0x0 - 0x3 (char\[4\]): 'FNTA.' Format signature. - 0x4 - 0x5 (uint16): Magic number. Always 1. - 0x6 - 0x7 (uint16): Magic number. Always 1. - 0x8 - 0xB (uint32): Size of header in bytes. Always 12. ###### Metadata section - 0xC - 0x13 (uint64): StrCode64 hash. Usually empty string "" hash. - 0x14 - 0x15 (uint32): Number of entries. - 0x16 - 0x19 (uint32): Magic number. Always 24. - 0x1C - 0x1F (uint32): Hash table offset. Must add header size to get the actual offset. - 0x20 - 0x24 (uint32): Size of the file, excluding the header. ###### Entry section The number of entries is equal to the "number of entries" value in the metadata section. ###### Entry struct - 0x0 - 0xB (float3): Entry position. - 0xC - 0xF (uint32): StrCode32 hash of enter action (e.g., StepOn 1277978017). - 0x10 - 0x1B (float3): Exit position. - 0x1C - 0x1F (uint32): StrCode32 hash of exit action (e.g., StepDown 1139911476). - 0x20 - 0x27 (uint64): StrCode64 hash. Connection action? Most times empty string "" hash, but has exceptions like gntn_common.nta. - 0x28 - 0x29 (int16): Flags? The most used one, ranging from -1 to 1000s - 0x2A - 0x2B (int16): Flags? - 0x2C - 0x2D (int16): Flags? - 0x2E - 0x2F (int16): Flags? ###### Hash table There is one StrCode64 hash for each entry here. Perhaps a name for each entry?