2020-06-10 23:22:53 +02:00
# Mod Organizer 2 - Simple Games Plugin
Mod Organizer 2 meta-plugin to make creating game plugins easier and faster.
## Why?
2021-02-23 11:17:22 +01:00
In order to create a MO2 game plugin, one must implement the `IPluginGame` interface.
2020-06-12 22:59:03 +02:00
This interface was initially designed for Bethesda games such as the Elder Scrolls or
Fallout series and thus contains a lot of things that are irrelevant for most games.
2020-06-10 23:22:53 +02:00
2020-06-12 22:59:03 +02:00
The goal of this meta-plugin is to allow creating game plugins for "basic" games by
2020-11-08 11:48:14 +01:00
providing a very simple python class.
2020-06-10 23:22:53 +02:00
2020-06-11 20:40:03 +02:00
## How to install?
2020-11-08 11:48:14 +01:00
Download the archive for your MO2 version and extract it directly into your MO2 `plugins` folder.
2021-02-04 10:42:14 +01:00
- Mod Organizer **2.3.2** : [Download ](https://github.com/ModOrganizer2/modorganizer-basic_games/releases/download/v0.0.3/basic_games-0.0.3.zip )
and extract in your `plugins/` folder (see below).
2021-04-24 17:55:49 -07:00
- Mod Organizer **2.4** : Basic games is included in Mod Organizer 2.4.
2021-02-04 10:42:14 +01:00
- If you want to use new game plugins that have not been included in the
release, [download the latest archive ](https://github.com/ModOrganizer2/modorganizer-basic_games/archive/master.zip ) and extract the files
in the existing `basic_games` folder, overwriting existing files.
2020-06-11 20:40:03 +02:00
**Important:** Extract the *folder* in your `plugins` folder, not the individual files. Your
`plugins` folder should look like this:
2023-09-23 14:21:14 +02:00
```text
2020-06-11 20:40:03 +02:00
dlls/
plugins/
data/
2021-02-04 10:42:14 +01:00
basic_games/
2020-06-11 20:40:03 +02:00
games/
__init__.py
...
__init__.py
basic_game.py
...
bsa_extractor.dll
...
ModOrganizer.exe
```
2020-11-08 11:48:14 +01:00
You can rename `modorganizer-basic_games-xxx` to whatever you want (e.g., `basic_games` ).
2020-06-12 22:59:03 +02:00
## Supported games
2020-06-13 21:01:24 +02:00
| Game | Author | File | Extras |
|------|--------|------|--------|
2020-11-24 11:20:51 -08:00
| The Binding of Isaac: Rebirth — [STEAM ](https://store.steampowered.com/app/250900/The_Binding_of_Isaac_Rebirth/ ) |[EzioTheDeadPoet ](https://github.com/EzioTheDeadPoet )|[game_thebindingofisaacrebirth.py ](games/game_thebindingofisaacrebirth.py )|<ul><li>profile specific ini file</li></ul>|
2021-06-18 19:42:52 +02:00
| Control — [STEAM ](https://store.steampowered.com/app/870780/Control_Ultimate_Edition/ ) / [GOG ](https://www.gog.com/game/control_ultimate_edition ) / [EGS ](https://www.epicgames.com/store/p/control ) | [Zash ](https://github.com/ZashIn ) | [game_control.py ](games/game_control.py ) | |
2021-02-25 22:07:48 +01:00
| Darkest Dungeon — [GOG ](https://www.gog.com/game/darkest_dungeon ) / [STEAM ](https://store.steampowered.com/app/262060/Darkest_Dungeon/ ) | [erri120 ](https://github.com/erri120 ) | [game_darkestdungeon.py ](games/game_darkestdungeon.py ) | <ul><li>save slot parsing</li><li>mod data checker</li></ul> |
2021-02-23 11:17:22 +01:00
| Dark Messiah of Might & Magic — [STEAM ](https://store.steampowered.com/app/2100/Dark_Messiah_of_Might__Magic/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_darkmessiahofmightandmagic.py ](games/game_darkmessiahofmightandmagic.py ) | <ul><li>save game preview</li></ul> |
2020-11-24 11:20:51 -08:00
| Dark Souls — [STEAM ](https://store.steampowered.com/app/211420/DARK_SOULS_Prepare_To_Die_Edition/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_darksouls.py ](games/game_darkestdungeon.py ) | |
2021-04-24 17:55:49 -07:00
| Divinity: Original Sin (Classic) — [STEAM ](https://store.steampowered.com/app/230230/Divinity_Original_Sin_Classic/ ) | [LostDragonist ](https://github.com/LostDragonist/ ) | [game_divinityoriginalsin.py ](games/game_divinityoriginalsin.py ) | <ul><li>save game preview</li></ul> |
| Divinity: Original Sin (Enhanced Edition) — [STEAM ](https://store.steampowered.com/app/373420/Divinity_Original_Sin__Enhanced_Edition/ ) | [LostDragonist ](https://github.com/LostDragonist/ ) | [game_divinityoriginalsinee.py ](games/game_divinityoriginalsinee.py ) | <ul><li>save game preview</li><li>mod data checker</li></ul> |
2021-04-29 02:48:55 -07:00
| Dragon's Dogma: Dark Arisen — [GOG ](https://www.gog.com/game/dragons_dogma_dark_arisen ) / [STEAM ](https://store.steampowered.com/app/367500/Dragons_Dogma_Dark_Arisen/ ) | [EzioTheDeadPoet ](https://github.com/EzioTheDeadPoet ) | [game_dragonsdogmadarkarisen.py ](games/game_dragonsdogmadarkarisen.py ) | |
2021-04-24 17:55:49 -07:00
| Dungeon Siege II — [GOG ](https://www.gog.com/game/dungeon_siege_collection ) / [STEAM ](https://store.steampowered.com/app/39200/Dungeon_Siege_II/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_dungeonsiege2.py ](games/game_dungeonsiege2.py ) | <ul><li>mod data checker</li></ul> |
2022-04-12 23:24:47 +02:00
| Kingdom Come: Deliverance — [GOG ](https://www.gog.com/game/kingdom_come_deliverance ) / [STEAM ](https://store.steampowered.com/app/379430/Kingdom_Come_Deliverance/ ) / [Epic ](https://store.epicgames.com/p/kingdom-come-deliverance ) | [Silencer711 ](https://github.com/Silencer711 ) | [game_kingdomcomedeliverance.py ](games/game_kingdomcomedeliverance.py ) | <ul><li>profile specific cfg files</li></ul>|
2024-01-28 15:21:37 -03:00
| METAL GEAR SOLID 2: Sons of Liberty — [STEAM ](https://store.steampowered.com/app/2131640/METAL_GEAR_SOLID_2_Sons_of_Liberty__Master_Collection_Version/ )|[AkiraJkr ](https://github.com/AkiraJkr )|[game_metalgearsolid2mc.py ](games/game_metalgearsolid2mc.py )| |
| METAL GEAR SOLID 3: Snake Eater — [STEAM ](https://store.steampowered.com/app/2131650/METAL_GEAR_SOLID_3_Snake_Eater__Master_Collection_Version/ )|[AkiraJkr ](https://github.com/AkiraJkr )|[game_metalgearsolid3mc.py ](games/game_metalgearsolid3mc.py )| |
2020-12-29 22:27:53 +01:00
| Mirror's Edge — [GOG ](https://www.gog.com/game/mirrors_edge ) / [STEAM ](https://store.steampowered.com/app/17410/Mirrors_Edge )|[EzioTheDeadPoet ](https://eziothedeadpoet.github.io/AboutMe/ )|[game_mirrorsedge.py ](games/game_mirrorsedge.py )| |
2020-11-24 11:20:51 -08:00
| Mount & Blade II: Bannerlord — [GOG ](https://www.gog.com/game/mount_blade_ii_bannerlord ) / [STEAM ](https://store.steampowered.com/app/261550/Mount__Blade_II_Bannerlord/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_mountandblade2.py ](games/game_mountandblade2.py ) | <ul><li>mod data checker</li></ul> |
2024-04-12 06:14:17 -03:00
| Need for Speed: High Stakes | [uwx ](https://github.com/uwx ) | [game_nfshs.py ](games/game_nfshs.py ) | |
2021-02-23 11:17:22 +01:00
| No Man's Sky - [GOG ](https://www.gog.com/game/no_mans_sky ) / [Steam ](https://store.steampowered.com/app/275850/No_Mans_Sky/ )|[EzioTheDeadPoet ](https://eziothedeadpoet.github.io/AboutMe/ )|[game_nomanssky.py ](games/game_nomanssky.py )| |
2026-04-18 17:39:51 +09:00
| Slay the Spire 2 — [STEAM ](s.team/a/2868840 ) | [Azlle ](https://github.com/Azlle ) | [game_sts2.py ](games/game_sts2.py ) | <ul><li>mod data checker</li></ul> |
2020-11-24 11:20:51 -08:00
| S.T.A.L.K.E.R. Anomaly — [MOD ](https://www.stalker-anomaly.com/ ) | [Qudix ](https://github.com/Qudix ) | [game_stalkeranomaly.py ](games/game_stalkeranomaly.py ) | <ul><li>mod data checker</li></ul> |
| Stardew Valley — [GOG ](https://www.gog.com/game/stardew_valley ) / [STEAM ](https://store.steampowered.com/app/413150/Stardew_Valley/ ) | [Syer10 ](https://github.com/Syer10 ), [Holt59 ](https://github.com/holt59/ ) | [game_stardewvalley.py ](games/game_stardewvalley.py ) | <ul><li>mod data checker</li></ul> |
2021-07-30 13:35:51 +02:00
| STAR WARS™ Empire at War: Gold Pack - [GOG ](https://www.gog.com/game/star_wars_empire_at_war_gold_pack ) / [STEAM ](https://store.steampowered.com/app/32470/ ) | [erri120 ](https://github.com/erri120 ) | <ul><li>Empire at War: [game_starwars-empire-at-war.py ](games/game_starwars-empire-at-war.py )</li><li>Force of Corruption: [game_starwars-empire-at-war-foc.py ](games/game_starwars-empire-at-war-foc.py )</li></ul> | |
2022-04-04 18:08:05 +02:00
| Subnautica — [STEAM ](https://store.steampowered.com/app/264710/ ) / [Epic ](https://store.epicgames.com/p/subnautica ) | [dekart811 ](https://github.com/dekart811 ), [Zash ](https://github.com/ZashIn ) | [game_subnautica.py ](games/game_subnautica.py ) | <ul><li>mod data checker</li><li>save game preview</li></ul> |
| Subnautica: Below Zero — [STEAM ](https://store.steampowered.com/app/848450/ ) | [dekart811 ](https://github.com/dekart811 ), [Zash ](https://github.com/ZashIn ) | [game_subnautica-below-zero.py ](games/game_subnautica-below-zero.py ) | <ul><li>mod data checker</li><li>save game preview</li></ul> |
2023-12-29 02:17:18 -08:00
| Train Simulator Classic — [STEAM ](https://store.steampowered.com/app/24010/ ) | [Ryan Young ](https://github.com/YoRyan ) | [game_trainsimulator.py ](games/game_trainsimulator.py ) | |
2022-04-03 14:06:54 +02:00
| Valheim — [STEAM ](https://store.steampowered.com/app/892970/Valheim/ ) | [Zash ](https://github.com/ZashIn ) | [game_valheim.py ](games/game_valheim.py ) | <ul><li>mod data checker</li><li>overwrite config sync</li><li>save game support (no preview)</li></ul> |
2024-04-12 06:13:50 -03:00
| Test Drive Unlimited | [uwx ](https://github.com/uwx ) | [game_tdu.py ](games/game_tdu.py ) | |
2024-04-13 05:00:35 -03:00
| Test Drive Unlimited 2 — [STEAM ](https://steamcommunity.com/app/9930/ ) | [uwx ](https://github.com/uwx ) | [game_tdu2.py ](games/game_tdu2.py ) | |
2021-11-09 10:21:02 +01:00
| The Witcher: Enhanced Edition - [GOG ](https://www.gog.com/game/the_witcher ) / [STEAM ](https://store.steampowered.com/app/20900/The_Witcher_Enhanced_Edition_Directors_Cut/ ) | [erri120 ](https://github.com/erri120 ) | [game_witcher1.py ](games/game_witcher1.py ) | <ul><li>save game parsing (no preview)</li></ul> |
2020-11-24 11:20:51 -08:00
| The Witcher 3: Wild Hunt — [GOG ](https://www.gog.com/game/the_witcher_3_wild_hunt ) / [STEAM ](https://store.steampowered.com/app/292030/The_Witcher_3_Wild_Hunt/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_witcher3.py ](games/game_witcher3.py ) | <ul><li>save game preview</li></ul> |
2024-04-13 05:00:21 -03:00
| Tony Hawk's Pro Skater 3 | [uwx ](https://github.com/uwx ) | [game_thps3.py ](games/game_thps3.py ) | |
| Tony Hawk's Pro Skater 4 | [uwx ](https://github.com/uwx ) | [game_thps4.py ](games/game_thps4.py ) | |
| Tony Hawk's Underground | [uwx ](https://github.com/uwx ) | [game_thug.py ](games/game_thug.py ) | |
| Tony Hawk's Underground 2 | [uwx ](https://github.com/uwx ) | [game_thug2.py ](games/game_thug2.py ) | |
2024-04-12 06:13:12 -03:00
| Trackmania United Forever — [STEAM ](https://store.steampowered.com/app/7200/Trackmania_United_Forever/ ) | [uwx ](https://github.com/uwx ) | [game_tmuf.py ](games/game_tmuf.py ) | |
2022-02-25 17:07:04 -06:00
| Yu-Gi-Oh! Master Duel — [STEAM ](https://store.steampowered.com/app/1449850/ ) | [The Conceptionist ](https://github.com/the-conceptionist ) & [uwx ](https://github.com/uwx ) | [game_masterduel.py ](games/game_masterduel.py ) | |
2026-05-11 09:31:04 +04:00
| Zeus and Poseidon — [GOG ](https://www.gog.com/game/zeus_poseidon ) / [STEAM ](https://store.steampowered.com/app/566050/Zeus__Poseidon/ ) | [Holt59 ](https://github.com/holt59/ ) | [game_zeusandposeidon.py ](games/game_zeusandposeidon.py ) | <ul><li>mod data checker</li></ul> |
2020-06-12 22:59:03 +02:00
2020-06-11 20:40:03 +02:00
## How to add a new game?
2020-06-10 23:22:53 +02:00
2020-11-09 20:14:05 +01:00
You can create a plugin by providing a python class in the `games` folder.
2020-06-12 22:59:03 +02:00
**Note:** If your game plugin does not load properly, you should set the log level
to debug and look at the `mo_interface.log` file.
2020-06-10 23:22:53 +02:00
2020-06-12 22:59:03 +02:00
You need to create a class that inherits `BasicGame` and put it in a `game_XX.py` in `games` .
Below is an example for The Witcher 3 (see also [games/game_witcher3.py ](games/game_witcher3.py )):
2020-06-10 23:22:53 +02:00
```python
2021-12-06 05:20:37 -06:00
from PyQt6.QtCore import QDir
2020-06-10 23:22:53 +02:00
from ..basic_game import BasicGame
class Witcher3Game ( BasicGame ):
2020-06-12 22:59:03 +02:00
Name = "Witcher 3 Support Plugin"
Author = "Holt59"
Version = "1.0.0a"
2020-06-10 23:22:53 +02:00
2020-06-12 22:59:03 +02:00
GameName = "The Witcher 3"
GameShortName = "witcher3"
GameBinary = "bin/x64/witcher3.exe"
GameDataPath = "Mods"
GameSaveExtension = "sav"
GameSteamId = 292030
2020-06-10 23:22:53 +02:00
def savesDirectory ( self ):
return QDir ( self . documentsDirectory () . absoluteFilePath ( "gamesaves" ))
```
`BasicGame` inherits `IPluginGame` so you can override methods if you need to.
Each attribute you provide corresponds to a method (e.g., `Version` corresponds
2020-06-12 22:59:03 +02:00
to the `version` method, see the table below). If you override the method, you do
not have to provide the attribute:
2020-06-10 23:22:53 +02:00
```python
2021-12-06 05:20:37 -06:00
from PyQt6.QtCore import QDir
2020-06-12 22:59:03 +02:00
from ..basic_game import BasicGame
import mobase
2020-06-10 23:22:53 +02:00
class Witcher3Game ( BasicGame ):
2020-06-12 22:59:03 +02:00
Name = "Witcher 3 Support Plugin"
Author = "Holt59"
2020-06-10 23:22:53 +02:00
2020-06-12 22:59:03 +02:00
GameName = "The Witcher 3"
GameShortName = "witcher3"
GameBinary = "bin/x64/witcher3.exe"
GameDataPath = "Mods"
GameSaveExtension = "sav"
GameSteamId = 292030
2020-06-10 23:22:53 +02:00
def version ( self ):
# Don't forget to import mobase!
return mobase . VersionInfo ( 1 , 0 , 0 , mobase . ReleaseType . final )
def savesDirectory ( self ):
return QDir ( self . documentsDirectory () . absoluteFilePath ( "gamesaves" ))
2020-06-11 21:52:01 +02:00
```
### List of valid keys
2020-11-08 11:48:14 +01:00
| Name | Description | `IPluginGame` method | Python |
|------|-------------|----------------------|--------|
| Name | Name of the plugin | `name` | `str` |
| Author | Author of the plugin | `author` | `str` |
| Version | Version of the plugin | `version` | `str` or `mobase.VersionInfo` |
| Description| Description (Optional) | `description` | `str` |
| GameName | Name of the game, as displayed by MO2 | `gameName` | `str` |
| GameShortName | Short name of the game | `gameShortName` | `str` |
| GameNexusName| Nexus name of the game (Optional, default to `GameShortName` ) | `gameNexusName` | `str` |
| GameValidShortNames | Other valid short names (Optional) | `validShortNames` | `List[str]` or comma-separated list of values |
| GameNexusId | Nexus ID of the game (Optional) | `nexusGameID` | `str` or `int` |
| GameBinary | Name of the game executable, relative to the game path | `binaryName` | `str` |
| GameLauncher | Name of the game launcher, relative to the game path (Optional) | `getLauncherName` | `str` |
| GameDataPath | Name of the folder containing mods, relative to game folder| `dataDirectory` | |
| GameDocumentsDirectory | Documents directory (Optional) | `documentsDirectory` | `str` or `QDir` |
2023-10-21 21:22:43 +02:00
| GameIniFiles | Config files in documents, for profile specific config (Optional) | `iniFiles` | `str` or `List[str]` |
2020-11-08 11:48:14 +01:00
| GameSavesDirectory | Directory containing saves (Optional, default to `GameDocumentsDirectory` ) | `savesDirectory` | `str` or `QDir` |
| GameSaveExtension | Save file extension (Optional) `savegameExtension` | `str` |
| GameSteamId | Steam ID of the game (Optional) | `steamAPPId` | `List[str]` or `str` or `int` |
| GameGogId | GOG ID of the game (Optional) | `gogAPPId` | `List[str]` or `str` or `int` |
2021-11-24 20:55:11 -07:00
| GameOriginManifestIds | Origin Manifest ID of the game (Optional) | `originManifestIds` | `List[str]` or `str` |
| GameOriginWatcherExecutables | Executables to watch for Origin DRM (Optional) | `originWatcherExecutables` | `List[str]` or `str` |
2022-04-12 14:01:38 +02:00
| GameEpicId | Epic ID (`AppName` ) of the game (Optional) | `epicAPPId` | `List[str]` or `str` |
2022-04-11 21:35:21 +02:00
| GameEaDesktopId | EA Desktop ID of the game (Optional) | `eaDesktopContentId` | `List[str]` or `str` or `int` |
2020-06-12 22:59:03 +02:00
You can use the following variables for `str` :
- `%DOCUMENTS%` will be replaced by the standard *Documents* folder.
- `%GAME_PATH%` will be replaced by the path to the game folder.
- `%GAME_DOCUMENTS%` will be replaced by the value of `GameDocumentsDirectory` .
## Extra features
The meta-plugin provides some useful extra feature:
2022-05-02 16:52:26 +02:00
1. **Automatic Steam, GOG, Origin, Epic Games and EA Desktop detection:** If you provide
Steam, GOG, Origin or Epic IDs for the game (via `GameSteamId` , `GameGogId` ,
`GameOriginManifestIds` , `GameEpicId` or `GameEaDesktopId` ), the game will be listed
in the list of available games when creating a new MO2 instance (if the game is
installed via Steam, GOG, Origin, Epic Games / Legendary or EA Desktop).
2023-10-08 18:24:33 +02:00
2. **Basic save game preview / metadata** (Python): If you can easily obtain a picture
(file) and/or metadata (like from json) for any saves, you can provide basic save-game
preview by using the `BasicGameSaveGameInfo` . See
[games/game_witcher3.py ](games/game_witcher3.py ) and
[games/game_bladeandsorcery.py ](games/game_bladeandsorcery.py ) for more details.
2023-10-08 09:12:14 +02:00
3. **Basic local save games** (Python): profile specific save games, as in [games/game_valheim.py ](games/game_valheim.py ).
4. **Basic mod data checker** (Python):
2022-04-03 14:06:54 +02:00
Check and fix different mod archive layouts for an automatic installation with the proper
file structure, using simple (glob) patterns via `BasicModDataChecker` .
2022-04-04 18:08:05 +02:00
See [games/game_valheim.py ](games/game_valheim.py ) and [game_subnautica.py ](games/game_subnautica.py ) for an example.
2020-08-06 12:16:19 +02:00
Game IDs can be found here:
- For Steam on [Steam Database ](https://steamdb.info/ )
- For GOG on [GOG Database ](https://www.gogdb.org/ )
2022-04-12 14:01:38 +02:00
- For Origin from `C:\ProgramData\Origin\LocalContent` (.mfst files)
- For Epic Games (`AppName` ) from:
- `C:\ProgramData\Epic\EpicGamesLauncher\Data\Manifests\` (.item files)
2025-01-12 12:18:08 +01:00
- or `C:\ProgramData\Epic\EpicGamesLauncher\UnrealEngineLauncher\LauncherInstalled.dat`
- or [Unofficial EGS ID DB ](https://erri120.github.io/egs-db/ )
2022-05-02 16:52:26 +02:00
- For Legendary (alt. Epic launcher) via command `legendary list-games`
2022-04-12 14:01:38 +02:00
or from: `%USERPROFILE%\.config\legendary\installed.json`
2022-04-11 21:35:21 +02:00
- For EA Desktop from `<EA Games install location>\<game title>\__Installer\installerdata.xml`
2023-09-23 14:21:14 +02:00
## Contribute
We recommend using a dedicated Python environment to write a new basic game plugins.
1. Install the required version of Python --- Currently Python 3.11 (MO2 2.5).
2. Remove the repository at `${MO2_INSTALL}/plugins/basic_games` .
3. Clone this repository at the location of the old plugin (
`${MO2_INSTALL}/plugins/basic_games` ).
4. Place yourself inside the cloned folder and:
```bash
# create a virtual environment (recommended)
py -3.11 -m venv .\venv
.\venv\scripts\Activate.ps1
# "install" poetry and the development package
pip install poetry
poetry install
` ``