## Technical Details of Modular Resources ### 1. Manifest Configuration I updated `ResourceManifestData.cs` to support a new field, a dictionary called `ModularResources` (serialized as `resources` in YAML). * **Key (VFS Path):** The virtual path where the game expects to see the files (e.g., `ModResources`). * **Value (Disk Path):** The actual folder name on the hard drive relative to the executable. **manifest.yml:** ```yaml resources: ModResources: GoobResources ``` ### 2. VFS Mounting In `ProgramShared.cs`, logic was added to iterate through these modular resources and mount them. * It explicitly checks for the physical directory location (handling both Debug `../../` paths and Release `./` paths). ### 3. Prototype & Resource Loading `ClientPrototypeManager` and `ServerPrototypeManager` were updated to iterate over the modular roots defined in the manifest and load prototypes from them. Additionally, `ResourceCache` preloading logic was updated to scan these new paths for textures. ### 4. Absolute Path Support (The Core Logic) Currently the engine forces `/Textures/` or `/Audio/` prefixes onto all paths. This broke any attempt to load resources from a custom root. Introduced `PathHelpers.ApparentPath(ResPath path)`, which is now used across `SpriteComponent`, `SpriteSystem`, and various Serializers. * **Logic:** If a path is "rooted" (starts with `/`), the engine now respects it as an absolute path. * **Legacy:** If a path is relative (e.g., `Objects/Tool.rsi`), it defaults to the standard `/Textures/` prefix, preserving backward compatibility. ### 5. Packaging I updated `RobustClientPackaging.cs`. Previously, it flattened all resources into the root of the ZIP. I added logic to inject modular resources into their own subdirectories within the ZIP, ensuring the VFS structure in Release builds matches Debug builds. ### 6. Hot Reloading `ReloadManager.cs` was updated to watch these external physical folders. It maps file changes back to their configured VFS mount points, ensuring hot reload works for modular content just as it does for standard content. ## Example Usage **Old Way (The Underscore Hack):** * File: `Resources/Textures/_Goobstation/Weapon.rsi` * YAML: `sprite: _Goobstation/Weapon.rsi` **New Way (Modular):** * File: `GoobResources/Textures/Weapon.rsi` (Clean separation on disk) * YAML: `sprite: /Goobstation/Textures/Weapon.rsi`