A non-destructive Virtual File System (VFS) modloader for Bully: Scholarship Edition. Inspired by thelink2012's GTA Modloader.
Replace, resize, and add files inside .img archives and the game's root directory — without ever modifying the original game files. Simply drop your mods into organized folders, set priorities, and launch the game. Removing a mod is as easy as deleting its folder.
- 100% Non-Destructive: Original
.img,.dir, and loose files are never modified. Remove a mod folder and the game reverts to vanilla instantly. - Archive Virtualization: Replace or add files inside any
.imgarchive (e.g.,Stream/world.img) by simply mirroring the folder structure. - Larger Files & New Additions: Automatically generates a custom
.dirfile when your replacement is larger than the original or is a brand-new file. No manual IMG editing required. - Root Directory Emulation: Each mod folder acts as a virtual game root. Drop any loose file (
.ini,.col,.ipl, etc.) and it transparently replaces the original. - Priority System: Control load order via
priority.ini. Higher number = higher priority. Equal priorities fall back to the earliest "Date Modified". - Toggleable Debug Logging: Enable or disable the log file via
modloader.inito keep your game directory clean. - Thread-Safe: All hooks use a critical section to prevent race conditions during Bully's asynchronous streaming.
- Bully: Scholarship Edition (PC, version 1.200 — Steam/GOG default)
- Ultimate ASI Loader (
dinput8.dll)
- Place
dinput8.dllin your Bully game directory (whereBully.exeis). - Place
modloader_bully.asiin the same directory. - Create a folder named
modloaderin the game directory. - Launch the game. The modloader will auto-generate its config files on first run.
-
Sometimes some mods might not work or the game might crash : to solve this try deleting the
.dirfolder inmodloaderfolder. -
Upon updating the modloader , sometimes you might wanna delete the
.datafolder too (since I would have added modifications to it) but note this removes the priority list you made in the previous version -
This is a possible perceived bug I found , if you're making an
.nft(Texture) modification : it will not show any changes if you don't also provide the.nif(3d Model) with it. And the opposite goes to if you are making an.nifmod , you must provide also the.nftfile with it or else no texture will show. That's why the mod works best with.nif + .nftcombination -
Some mods may crash the game if you add them (tried with
PS2 and Wii Trees by EpigreZrandBeautiful HD Retextured Radar Map by SkillaG), although if you add only some parts of the mod into the game then no crash might happen (I tried addingG_ClimbTree.nftandTreeClimb.niffiles from thePS2 and Wii Trees by EpigreZrmod -> that would be the climbing tree at the football stadium at school in case you wanna test it yourself). Maybe it has to do with the amount of things added inside a specific modfolder , or it has to do with specific files in particular, or the issue is completely unrelated to both.
Bully/
├── Bully.exe
├── dinput8.dll
├── modloader_bully.asi <-- The modloader
└── modloader/
├── modloader.ini <-- Global settings (Debug toggle)
├── .data/
│ └── mods.ini <-- Mod load order and status of each mod
├── .dir/
│ └── Stream/
│ └── world.dir <-- Auto-generated custom .dir (do not edit)
├── MyMod/ <-- A mod folder (acts as virtual game root)
│ └── Stream/
│ └── world.img/
│ ├── X.nif
│ └── X.nft
├── MyOtherMod/ <-- Another mod folder
│ └── Stream/
│ └── world.img/
│ ├── Y.nif
│ └── Y.nft
├── ...
- Find the file you want to replace (e.g.,
foreign.nifinsideStream/world.img). - Create a mod folder:
modloader/MyMod/Stream/world.img/. - Place your replacement
foreign.nifinside that folder. - Launch the game. Done.
Follow the same steps as above. If the filename doesn't exist in the original .dir, the modloader automatically appends it to a generated custom .dir file.
Open modloader/.data/priority.ini:
[Priorities]
MyTextureMod=50
MyConfigMod=60- Higher number = wins conflicts.
- Equal numbers = earliest "Date Modified" wins.
- New mod folders are auto-added with a default priority of
50.
Open modloader/modloader.ini:
[Settings]
Debug=0Set to 1 to enable modloader.txt logging. Set to 0 to disable it and save disk I/O.
| Phase | What Happens |
|---|---|
| Startup | Reads modloader.ini for settings. Recursively scans all mod folders. Resolves conflicts via priority/date. |
.dir Generation |
If any file is larger than the original or is a new addition, a custom .dir is written to modloader/.dir/. |
| Hooking | Hooks CreateFileA/W, ReadFile, SetFilePointer/Ex, GetFileSize/Ex, and GetFileAttributesA/W via MinHook. |
| Runtime – Loose Files | When the game requests a file, the hook checks if a mod folder provides a replacement. If yes, the path is silently redirected. |
Runtime – .img Files |
When the game seeks to an offset inside an .img, the hook checks if that offset maps to a modded file. If yes, data is read from the mod folder instead. |
| Runtime – Fake Offsets | For larger/new files, the custom .dir points to a "fake" sector offset (starting at 1GB) beyond the real .img size. The hook intercepts reads at that offset and serves the mod file. GetFileSize is spoofed to prevent "file too small" crashes. |
- Visual Studio 2019/2022 (C++ Desktop workload)
- MinHook (add source files directly to the project)
- Platform: x86 (32-bit) — Bully is a 32-bit game
- Configuration: Release
- Open
Modloader-Bully/Modloader-Bully.slnx. - Right Click Project in Solution Explorer -> Go To Properties -> Configuration Manager => Set platform to x86 and configuration to Release.
- Disable Precompiled Headers if it's not already disabled: Project Properties → C/C++ → Precompiled Headers → Not Using Precompiled Headers.
- Add all MinHook
.csource files (src/*.candsrc/hde/*.c) to the project if they're not already added. (Right Click Project-> Add -> Existing Item) - Add MinHook's
include/folder to Additional Include Directories.(Right Click Project -> Properties -> C/C++ -> General) - Change Target File Extension to .asi
(Properties -> Configuration Properties -> Advanced -> Target File Extension) - Change Target Name to "modloader_bully"
(Properties -> Configuration Properties -> General -> Target Name) - To Build , Go Build (from Top Bar) / Clean Solution then Build/Rebuild Solution
- You Will Find the .asi in the Release Folder, Drop it to the root directory of Bully
- thelink2012 – GTA Modloader: Architectural inspiration for the VFS approach.
- TsudaKageyu – MinHook: The inline hooking library that makes this possible.
- ThirteenAG – Ultimate ASI Loader: ASI injection.
- CookiePLMonster – SilentPatchBully: Reference for Bully's internal memory layout and RenderWare structures.
- The Bully modding community.
This project is still in Development , So you might expect some bugs. I am still new at modding Bully and I used AI to help me build this system, I just thought about sharing this system because it helped me manage my own Bully Mods.
This project is provided as-is for educational and personal modding purposes. Bully: Scholarship Edition is © Rockstar Games.