|
| 1 | +# Infinity Engine - Better Random Library |
| 2 | +A better random for Infinity Engine Games |
| 3 | + |
| 4 | +This repository provides a solution for injecting a "better random" library into the Infinity Engine game executables using a batch file and a custom DLL. |
| 5 | +The DLL hooks the `rand()` function and replaces it with a custom implementation that generates more robust random numbers. |
| 6 | + |
| 7 | +The custom DLL utilizes the C++ standard library's random number generation facilities. It includes the following components: |
| 8 | + |
| 9 | +- `std::random_device rd`: This is a non-deterministic random number generator that provides a source of true randomness from the operating system or hardware. |
| 10 | +- `std::uniform_int_distribution<> dist(0, RAND_MAX)`: This distribution object defines a range between 0 and `RAND_MAX` (the maximum value returned by `rand()`), |
| 11 | + ensuring that the generated numbers are uniformly distributed within this range. |
| 12 | +- `std::mt19937 gen(rd())`: This line seeds the Mersenne Twister pseudo-random number generator (`mt19937`) with random values obtained from `std::random_device rd`. |
| 13 | + The Mersenne Twister is a widely-used pseudo-random number generator that produces high-quality random numbers with a long period. |
| 14 | + |
| 15 | +By utilizing these components, the custom implementation of the `rand()` function improves the randomness and unpredictability of the random numbers generated during gameplay. |
| 16 | + |
| 17 | +## Original Infinity Engine Random Implementation |
| 18 | +```C++ |
| 19 | +__int64 __fastcall rand() |
| 20 | +{ |
| 21 | + __acrt_ptd *v0; |
| 22 | + unsigned int v1; |
| 23 | + |
| 24 | + v0 = _acrt_getptd(); |
| 25 | + v1 = 214013 * v0->_rand_state + 2531011; |
| 26 | + v0->_rand_state = v1; |
| 27 | + return HIWORD(v1) & 0x7FFF; |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +The original implementation of random for the Infinity Engine uses the specific variant of a [linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator) shown above. |
| 32 | + |
| 33 | +In EE game versions, other platforms outside of Windows (E.g. Linux) don't utilize this implementation, but instead perform library calls to a system level rand() function; thus, they don't necessarily |
| 34 | +suffer from the same defects. |
| 35 | + |
| 36 | +## Prerequisites |
| 37 | + |
| 38 | +- Windows operating system |
| 39 | +- An infinity engine game |
| 40 | + - Baldur's Gate (BGMain2.exe) |
| 41 | + - Baldur's Gate II (BGmain.exe) |
| 42 | + - Icewind Dale (IDMain.exe) |
| 43 | + - Planescape Torment (Torment.exe) |
| 44 | + - Baldur's Gate EE (Baldur.exe) |
| 45 | + - Baldur's Gate II EE (Baldur.exe) |
| 46 | + - Icewind Dale EE (Icewind.exe) |
| 47 | + - Planescape Torment EE (Torment.exe) |
| 48 | + |
| 49 | +## Usage |
| 50 | + |
| 51 | +1. Copy the files to the directory where the Infinity Engine game executable is located. |
| 52 | + |
| 53 | +2. Double-click on the `BetterRandom.bat` file to run it. |
| 54 | + |
| 55 | +3. The batch script will display a menu with the following options: |
| 56 | + |
| 57 | + - `1. Add BetterRandom library to {EXE Name}` |
| 58 | + - `2. Remove BetterRandom library from {EXE Name]` |
| 59 | + |
| 60 | +4. Choose an action by entering the corresponding number and press Enter. |
| 61 | + |
| 62 | +## Implementation Details |
| 63 | + |
| 64 | +The custom DLL included in this repository utilizes the Detours library for DLL injection and function hooking. Detours is a powerful library developed by |
| 65 | +Microsoft Research that allows for the interception and redirection of function calls within a target executable. |
| 66 | + |
| 67 | +The Better Random library hooks the `rand()` function in the Baldur's Gate game executable using Detours. It intercepts calls to `rand()` and replaces them with |
| 68 | +a custom implementation that generates random numbers using a more robust algorithm. This enhances the randomness and unpredictability of in-game events that rely |
| 69 | +on the random number generator. |
| 70 | + |
| 71 | +The batch file `BetterRandom.bat` included in this repository simplifies the process of adding or removing the `BetterRandom` library from the Baldur's Gate game executable. |
| 72 | +It utilizes the Detours library's `setdll.exe` tool to perform the DLL injection and removal. |
| 73 | + |
| 74 | +When you run the `BetterRandom.bat` script and choose the option to add the better random library, it uses `setdll.exe` to add `BetterRandom_x64.dll` or `BetterRandom_x86.dll` |
| 75 | +into the game executable's imports table. This allows the DLL to redirect calls to `rand()` to the custom implementation during gameplay. |
| 76 | + |
| 77 | +Similarly, when you choose the option to remove the better random library, the `BetterRandom.bat` script utilizes `setdll.exe` to remove the `BetterRandom_x64.dll` or |
| 78 | +`BetterRandom_x86.dll` from the game executable's imports table, restoring the original `rand()` function. |
0 commit comments