diff --git a/Bootstrap.cs b/Bootstrap.cs
index 132ff8f..7aa2231 100644
--- a/Bootstrap.cs
+++ b/Bootstrap.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Reflection;
using Harmony;
@@ -33,6 +33,12 @@ namespace MSCO
/// Ordner von MSCO.dll (<Spiel>\MSCO).
public static string Folder { get { return folder; } }
static bool patchedGame, patchedPlayMaker, started;
+
+ ///
+ /// Singleplayer mit Mods (Launcher: SINGLEPLAYER, "-msco-singleplayer"): nur die eigenen Mods laden - kein
+ /// MSCO-Menü, kein Multiplayer, das Spiel bleibt sonst unverändert.
+ ///
+ public static readonly bool Singleplayer = Array.IndexOf(Environment.GetCommandLineArgs(), "-msco-singleplayer") >= 0;
static StreamWriter log;
public static void Start()
@@ -43,6 +49,7 @@ namespace MSCO
log = new StreamWriter(Path.Combine(folder, "MSCO_Loader.txt"), false) { AutoFlush = true };
Log("MSCO " + MSCO.ModVersion + " loader started (standalone, without MSCLoader)");
Log("Command line: " + string.Join(" ", Environment.GetCommandLineArgs()));
+ if (Singleplayer) Log("Singleplayer mode: only mods, no multiplayer");
AppDomain.CurrentDomain.AssemblyResolve += Resolve;
AppDomain.CurrentDomain.AssemblyLoad += (_, e) => OnAssemblyLoaded(e.LoadedAssembly);
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) OnAssemblyLoaded(a);
@@ -126,7 +133,7 @@ namespace MSCO
{
host = this;
MscoLog.Info("Welcome to MSCO by mbm.wtf");
- MenuBranding.ApplyWindow();
+ if (!Bootstrap.Singleplayer) MenuBranding.ApplyWindow();
// Den Nachrichten-Bildschirm des Spiels ("Latest news ... press any key") überspringen - direkt ins Hauptmenü
string scene = Application.loadedLevelName;
Bootstrap.Log("First scene: " + scene);
@@ -142,7 +149,7 @@ namespace MSCO
AudioListener.volume = 0f;
return;
}
- MultiplayerManager.Ensure();
+ if (!Bootstrap.Singleplayer) MultiplayerManager.Ensure();
SceneChanged(scene);
}
@@ -220,9 +227,12 @@ namespace MSCO
loadingScreen = false;
if (previousVolume >= 0f) { AudioListener.volume = previousVolume; previousVolume = -1f; }
Bootstrap.Log("Level loaded: " + Application.loadedLevelName);
- MenuBranding.ApplyWindow();
- if (Application.loadedLevelName == "MainMenu") StartCoroutine(BrandMenu());
- MultiplayerManager.Ensure();
+ if (!Bootstrap.Singleplayer)
+ {
+ MenuBranding.ApplyWindow();
+ if (Application.loadedLevelName == "MainMenu") StartCoroutine(BrandMenu());
+ MultiplayerManager.Ensure();
+ }
SceneChanged(Application.loadedLevelName);
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c91f76d..eea9fe9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2.10.10
+
+- **Mods im Singleplayer:** Startet der Launcher mit SINGLEPLAYER, lädt MSCO nur noch die eigenen Mods
+ (`Mods\*.dll`) – kein MSCO-Menü, kein Multiplayer, das Spiel und der eigene Spielstand bleiben sonst unverändert
+- Für Mod-Entwickler: `IsSingleplayer` in `MscoMod`
+
## 2.10.9
- **Beta-Hinweis:** im MSCO-Menü steht „BETA“ neben dem Schriftzug und ein kurzer Hinweis, dass Fehler auftreten
diff --git a/MODDING.md b/MODDING.md
index 37144b4..4818a70 100644
--- a/MODDING.md
+++ b/MODDING.md
@@ -7,7 +7,7 @@ Klasse, die von `MSCO.MscoMod` erbt. MSCLoader-Mods laufen damit **nicht** (sie
| Ordner | |
|---|---|
-| `\MSCO\Mods\*.dll` | eigene Mods – immer aktiv, werden beim Spielstart geladen |
+| `\MSCO\Mods\*.dll` | eigene Mods – immer aktiv, werden beim Spielstart geladen (auch im Singleplayer, siehe unten) |
| `\MSCO\Mods\*.dll.off` | ausgeschaltet (Launcher → *Mods*) |
| `\MSCO\Mods\Servers\*.dll` | Mods von Servern – nur aktiv, solange man auf einem Server ist, der sie verlangt |
| Server: `data/mods/*.dll` | Mods, die der dedizierte Server an seine Spieler verteilt (Web-Panel → *Mods*) |
@@ -15,6 +15,14 @@ Klasse, die von `MSCO.MscoMod` erbt. MSCLoader-Mods laufen damit **nicht** (sie
Im Spiel: Seite **Mods** im MSCO-Menü, Konsole (F7) `mods`. Im Launcher: Seite **Mods** (hinzufügen, aus-/einschalten,
entfernen).
+## Singleplayer
+
+**SINGLEPLAYER** im Launcher lädt die eigenen Mods ebenfalls: MSCO startet dann im Singleplayer-Modus
+(`-msco-singleplayer`) – nur die Mods, kein MSCO-Menü, kein Multiplayer, der eigene Spielstand. `OnMenuLoad`,
+`OnGameLoad`, `Update`, `OnGUI` usw. laufen wie gewohnt; `IsSingleplayer` ist `true`, `IsInSession` `false` und
+`Send` tut nichts. Ohne eingeschaltete Mods (oder mit *Mods im Singleplayer* aus) startet das normale Spiel ohne MSCO.
+Die F7-Konsole gibt es dort nicht – Meldungen stehen in `output_log.txt`.
+
## Server-Mods
Liegen Mods in `data/mods` des Servers, bekommt jeder Spieler beim Beitreten die Liste (Name, Version, Größe, SHA-256).
@@ -108,6 +116,7 @@ Name und Version, die Launcher und Server-Panel anzeigen, kommen aus den Assembl
| `OnMessage(fromPlayerId, data)` | Daten, die dieselbe Mod (gleiche `ID`) bei einem anderen Spieler mit `Send` geschickt hat |
| `Send(byte[] data)` | an dieselbe Mod bei allen anderen Spielern (bis 60 KB; P2P und dedizierter Server) |
| `IsInSession`, `IsHost`, `LocalPlayerId`, `Players` | Sitzung, eigene ID, Spieler (ID → Name) |
+| `IsSingleplayer` | im Singleplayer gestartet (nur Mods, kein Multiplayer) |
| `Log(text)`, `LogWarning(text)` | in die MSCO-Konsole (F7) und `output_log.txt` |
Fehler in einer Mod fängt MSCO ab und schreibt sie ins Log. Wirft eine Mod ständig Fehler (50×), wird sie abgeschaltet.
diff --git a/MSCO.cs b/MSCO.cs
index 54c691e..8b28c24 100644
--- a/MSCO.cs
+++ b/MSCO.cs
@@ -11,7 +11,7 @@ namespace MSCO
/// Version der Mod. Kleine Updates: nur die dritte Stelle erhöhen (2.9.1, 2.9.2 ...) - sie bleiben mit
/// Servern und Mitspielern derselben ersten zwei Stellen kompatibel.
///
- public const string ModVersion = "2.10.9";
+ public const string ModVersion = "2.10.10";
///
/// Netzwerk-Version (die ersten beiden Stellen). Nur erhöhen, wenn sich das Protokoll inkompatibel ändert - dann
/// auch GameServer.ModVersion im Server.
diff --git a/ModApi.cs b/ModApi.cs
index 60ce816..1e033e1 100644
--- a/ModApi.cs
+++ b/ModApi.cs
@@ -48,6 +48,8 @@ namespace MSCO
protected void Log(string text) { MscoLog.Info("[" + Name + "] " + text); }
protected void LogWarning(string text) { MscoLog.Warning("[" + Name + "] " + text); }
+ /// Singleplayer mit Mods (Launcher: SINGLEPLAYER) - kein MSCO-Menü, kein Multiplayer, Send() geht nicht.
+ protected bool IsSingleplayer { get { return Bootstrap.Singleplayer; } }
/// In einer Sitzung (Server oder P2P)?
protected bool IsInSession { get { return MultiplayerManager.Instance != null && MultiplayerManager.Instance.IsInSession; } }
/// Selbst P2P-Host?