Initial public release of rem-essentials

This commit is contained in:
2026-08-11 16:48:50 +02:00
commit d611924a5e
161 changed files with 9792 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
# Architecture
`rem-essentials` is intentionally feature-first. Every migrated behavior should
live in its own module and be registered as a named feature in `src/main.cpp`.
## Feature registration
Each feature has:
- a stable config key
- an init function
- an optional cleanup function
- a runtime side: `Client`, `Server`, or `Always`
- a code default
The INI file can override each default. Missing INI entries keep the compiled
default.
## Current feature keys
The full key list lives in `rem-essentials.ini`. Feature switches live in
`[rem-essentials]`; typed parameters used by the graphics, saves, and
screenshots behavior live in the `[flplusplus]` section.
## Design rules
- Prefer one feature flag per behavior, even when multiple behaviors share one
option.
- Keep client and server hooks in separate files.
- Resolve optional Freelancer imports at runtime when practical.
- Keep adapted third-party code isolated under `third_party/` and wrap it with
thin REM adapters instead of adding a second plugin entry point.
## Proton-sensitive fixes
Mouse features stay split because Wine/Proton can handle cursor APIs
differently from native Windows. The current conservative defaults are:
- `cursor_visibility_fix = true`
- `cursor_border_flicker_fix = false`
- `mouse_warp_fix = false`
These can be enabled per player in `rem-essentials.ini` after testing.
+37
View File
@@ -0,0 +1,37 @@
# Build
The migrated hooks currently require 32-bit MSVC because some patches use
`__declspec(naked)` and MSVC inline assembly.
## Requirements
- Visual Studio with C++ tools
- CMake 3.20 or newer; the Visual Studio bundled CMake works
- 32-bit/x86 compiler environment
## Configure and build
From this workspace, the verified command is:
```powershell
cmd /s /c '"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" && "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -S . -B build-nmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release && "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build build-nmake'
```
The DLL is written to:
```text
build-nmake/bin/rem-essentials.dll
```
Copy `rem-essentials.dll` and `rem-essentials.ini` to Freelancer's `EXE`
directory and add the DLL to the `[Libraries]` section of `dacom.ini` and, for
server-side features, `dacomsrv.ini`.
## Current local verification status
Verified on this machine with Visual Studio 2022 Community's x86 developer
environment. The produced DLL was:
```text
build-nmake/bin/rem-essentials.dll
```
+138
View File
@@ -0,0 +1,138 @@
# Configuration
`rem-essentials` uses one active runtime configuration and, when the REM
Launcher is used, one persistent user override file.
## Configuration files
### Active game configuration
The DLL reads only this file at game startup:
```text
Freelancer/EXE/rem-essentials.ini
```
The file is shipped with the mod and contains the complete setting schema,
descriptions, metadata, and release defaults. A manual installation only needs
this INI and `rem-essentials.dll` in the `EXE` directory.
If the active INI is missing, the DLL uses its compiled defaults. The compiled
defaults intentionally match the shipped INI, but distributing the INI is
recommended because it exposes every feature and typed parameter.
### Launcher user overrides
The REM Launcher stores player choices separately:
```text
My Games/REM/rem-essentials.user.ini
```
On Wine or Proton, `My Games` is inside the Windows user profile of the active
prefix. Its exact Linux path depends on how the Launcher or game prefix was
created.
The DLL does not read this user file. The Launcher merges matching values from
the user file into `Freelancer/EXE/rem-essentials.ini`:
- after a game/mod update
- after saving settings in the Launcher
- immediately before starting Freelancer
This allows an update to replace the shipped schema while retaining player
choices. New settings from an updated default INI appear automatically. Values
from the user override win when the same section and key exist in both files.
## Value precedence
At runtime, the effective value is determined in this order:
1. The compiled DLL fallback is used when no setting can be read.
2. `Freelancer/EXE/rem-essentials.ini` overrides the compiled fallback.
3. Before launch, the Launcher materializes values from
`rem-essentials.user.ini` into the active INI.
For a manual installation without the Launcher, only the first two levels
apply. Editing the active INI is therefore sufficient.
## Sections and value types
Feature switches live in `[rem-essentials]`. Parameters used by the graphics,
saves, and screenshots behavior live in `[flplusplus]`.
Boolean values accept:
```text
true / false
1 / 0
yes / no
on / off
```
Integer, float, and string settings are described by the comments immediately
above each key. Metadata such as `type`, `min`, `max`, `default`, `group`, and
`risk` is also used by the Launcher to build the settings UI.
## Save directory behavior
REM keeps the historical installation-local save directory as its default:
```ini
[rem-essentials]
save_path_feature = true
[flplusplus]
save_in_directory = true
save_folder_name = Freelancer
```
With `save_in_directory = true`, the patched path is calculated relative to
`Freelancer.exe`:
```text
Freelancer/EXE/../SAVE
```
For an installation such as:
```text
/home/<user>/RemLauncher_AppData/current/Freelancer/EXE/Freelancer.exe
```
the effective save directory is:
```text
/home/<user>/RemLauncher_AppData/current/Freelancer/SAVE
```
With `save_in_directory = false`, the plugin instead uses the Windows
Documents folder exposed by Windows, Wine, or Proton and appends:
```text
My Games/<save_folder_name>
```
`save_folder_name` is therefore only relevant when
`save_in_directory = false`. Setting `save_path_feature = false` disables this
hook completely and restores Freelancer's unpatched path behavior.
Changing the setting does not move existing saves. Move existing files to the
selected directory before launching when switching between layouts.
## Manual installation
1. Copy `rem-essentials.dll` and `rem-essentials.ini` into `Freelancer/EXE`.
2. Add `rem-essentials.dll` to the appropriate `[Libraries]` section in
`dacom.ini` and, for FLServer features, `dacomsrv.ini`.
3. Ensure `save_path_feature = true` and `save_in_directory = true` for the REM
installation-local `SAVE` layout.
4. Fully restart Freelancer after changing the INI. Settings are read when the
DLL is loaded.
## Launcher-managed installation
Use the Game Settings page to change supported values. Saving creates or
updates `My Games/REM/rem-essentials.user.ini`. Avoid manually changing the
active INI while a conflicting user override exists, because the Launcher will
materialize the user value again before game startup.
+40
View File
@@ -0,0 +1,40 @@
# Deployment
## Build and package
Run the x86 build from the Visual Studio developer environment described in
`docs/build.md`, then package the verified output:
```powershell
.\tools\package-release.ps1
```
The command verifies that:
- every registered feature has exactly one INI toggle
- the Launcher and DLL ship the same default INI
- `direct_ips` is not compiled
- the release DLL is x86 and matches the current build
- the Launcher bridge and post-update merge are present
The generated artifacts are:
```text
release/rem-essentials.dll
release/rem-essentials-release.zip
```
The ZIP can be overlaid on the Freelancer installation. It contains the DLL and
default INI under `EXE/`, plus configuration documentation.
## Loader configuration
Add `rem-essentials.dll` to the `[Libraries]` section in client `dacom.ini` and
server `dacomsrv.ini`.
The Launcher keeps player overrides in
`My Games/REM/rem-essentials.user.ini`. It reapplies them after patching and
immediately before starting Freelancer.
The complete INI lifecycle, precedence rules, and save-directory mapping are
documented in [configuration.md](configuration.md).