Problem: When Main.TransitionTo() tried to show an error modal about missing multiplayer UI, it triggered ModalManager's static constructor which tried to instantiate modalUIPrefab. Since the asset bundle was missing, modalUIPrefab was null, causing: System.TypeInitializationException: The type initializer for 'KCM.ModalManager' threw an exception. ---> System.ArgumentException: The Object you want to instantiate is null. at KCM.ModalManager..cctor () [0x00017] This created a catch-22: couldn't show error modal about missing UI because the modal itself needed the missing UI. Root cause: ModalManager static constructor didn't check if modalUIPrefab was null before trying to instantiate it. ShowModal() and HideModal() also assumed modalInst was always initialized. Solutions: ModalManager static constructor (lines 25-30): - Add null check for PrefabManager.modalUIPrefab - If null, log warning and return early - Set instantiated = true to prevent re-initialization - Log success message when initialization works ShowModal() method (lines 55-59): - Check if modalInst is null before using it - If null (couldn't initialize), just log the modal content - Format: "MODAL (not shown - UI missing): Title - Message" - Prevents crash and preserves the error message in logs HideModal() method (lines 81-84): - Add null check before calling SetActive - Safe to call even if modal not initialized Results: ✅ No crash when modal UI is missing ✅ Error messages still logged even if not shown visually ✅ Graceful degradation throughout the mod ✅ ModalManager can be safely called from anywhere ✅ Clear logging shows what modals would have appeared 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Kingdoms and Castles Multiplayer Mod
Ez a mod multiplayer funkcionalitást ad a Kingdoms and Castles játékhoz.
Legutóbbi javítások (2025-12-14)
Kapcsolati problémák javítása
Probléma
A játékosok gyakran tapasztaltak "poor connection", "lost connection", vagy "server disconnected" üzeneteket, és ezután nem tudtak újra csatlakozni anélkül, hogy újraindították volna a játékot.
Gyökérok
-
Statikus client/server objektumok: A
KCClientésKCServerosztályok statikus konstruktorokban létrehozottClientésServerobjektumokat használtak, amelyek soha nem újrainizializálódtak disconnect után. -
Event handler elvesztés: Az event handlerek (Connected, Disconnected, MessageReceived, stb.) a statikus konstruktorban lettek feliratkozva, de amikor új server/client objektumok lettek létrehozva, ezek a handlerek elvesztek.
-
Nem tisztított állapot: A disconnect után a játék állapota nem lett teljesen kitisztítva, így a következő kapcsolódási kísérlet hibás állapotból indult.
Megoldások
1. KCClient.cs - Javított újracsatlakozási képesség
Változtatások:
-
Új
InitializeClient()metódus amely:- Teljesen kitisztítja a régi client objektumot
- Lecsatlakoztatja a régi kapcsolatot ha létezik
- Leiratkozik az összes event handlerről
- Létrehoz egy új, tiszta
Clientobjektumot - Növelt timeout (15 másodperc) a gyakori timeout-ok elkerülésére
- Újra feliratkozik az event handlerekre
-
Módosított
Connect()metódus:- Minden kapcsolódás előtt újrainicializálja a client-et
- Növelt connection attempts (10) a megbízhatóbb kapcsolódásért
-
Javított
Client_Disconnectedevent handler:- Tisztítja a client state-et (clientSteamIds)
- Megkülönbözteti az önkéntes és nem várt disconnect-eket
- Csak nem várt disconnect esetén mutat error modalt
Érintett kód részletek:
// KCClient.cs:34-62
private static void InitializeClient()
{
// Clean up old client if exists
if (client != null)
{
if (client.IsConnected || client.IsConnecting)
{
client.Disconnect();
}
// Unsubscribe from old events
client.Connected -= Client_Connected;
client.ConnectionFailed -= Client_ConnectionFailed;
client.Disconnected -= Client_Disconnected;
client.MessageReceived -= PacketHandler.HandlePacket;
}
// Create new client instance
client = new Client(Main.steamClient);
// Set a higher timeout to prevent frequent disconnections
client.TimeoutTime = 15000; // 15 seconds instead of default 5 seconds
// Subscribe to events
client.Connected += Client_Connected;
client.ConnectionFailed += Client_ConnectionFailed;
client.Disconnected += Client_Disconnected;
client.MessageReceived += PacketHandler.HandlePacket;
}
2. KCServer.cs - Javított server event handling
Változtatások:
-
Új
InitializeServer()metódus hasonló logikával mint a client:- Leállítja a régi server-t ha fut
- Leiratkozik az event handlerökről
- Létrehoz új server objektumot
- Növelt timeout (15 másodperc)
- Újra feliratkozik az event handlerekre
-
Event handlerek kiszervezése statikus metódusokba:
OnClientConnected()- külön metódus a client csatlakozás kezeléséreOnClientDisconnected()- külön metódus a client lecsatlakozás kezelésére- Try-catch blokkok a biztonságos error handling-ért
-
StartServer()mindig újrainicializálja a server-t:- Garantálja a tiszta állapotot minden indításkor
Érintett kód részletek:
// KCServer.cs:30-56
private static void InitializeServer()
{
// Clean up old server if exists
if (server != null)
{
if (server.IsRunning)
{
server.Stop();
}
// Unsubscribe from old events
server.MessageReceived -= PacketHandler.HandlePacketServer;
server.ClientConnected -= OnClientConnected;
server.ClientDisconnected -= OnClientDisconnected;
}
// Create new server instance
server = new Server(Main.steamServer);
// Set a higher timeout to prevent frequent disconnections
server.TimeoutTime = 15000; // 15 seconds instead of default 5 seconds
// Subscribe to events
server.MessageReceived += PacketHandler.HandlePacketServer;
server.ClientConnected += OnClientConnected;
server.ClientDisconnected += OnClientDisconnected;
}
3. LobbyManager.cs - Javított cleanup
Változtatások:
LeaveLobby()metódus teljes átírása:- Részletes logging minden lépésnél
- Null-safe ellenőrzések
- Try-catch blokk a biztonságos cleanup-ért
- Kitisztítja mind a
kCPlayersmind aclientSteamIdsdictionary-ket - Visszaállítja az összes flag-et (
loadingSave,registerServer) - Garantálja hogy mindig visszatér a ServerBrowser-hez még hiba esetén is
Érintett kód részletek:
// LobbyManager.cs:151-205
public void LeaveLobby()
{
Main.helper.Log("LeaveLobby called - cleaning up connection state");
try
{
// Disconnect client first
if (KCClient.client != null && (KCClient.client.IsConnected || KCClient.client.IsConnecting))
{
Main.helper.Log("Disconnecting client...");
KCClient.client.Disconnect();
}
// Stop server if running
if (KCServer.IsRunning)
{
Main.helper.Log("Stopping server...");
KCServer.server.Stop();
}
// Leave Steam lobby
if (lobbyId.IsValid())
{
Main.helper.Log("Leaving Steam lobby...");
SteamMatchmaking.LeaveLobby(lobbyId);
}
// Clear player data
Main.helper.Log("Clearing player data...");
Main.kCPlayers.Clear();
Main.clientSteamIds.Clear();
// Clear UI
LobbyHandler.ClearPlayerList();
LobbyHandler.ClearChatEntries();
// Reset flags
ServerBrowser.registerServer = false;
loadingSave = false;
// ... continues with transition
}
catch (Exception ex)
{
// Error handling with fallback
}
}
Eredmények
Ezekkel a változtatásokkal a következő problémák lettek megoldva:
- ✅ Reconnect képesség: A játékosok most már tudnak újra csatlakozni disconnect után anélkül, hogy újraindítanák a játékot
- ✅ Timeout problémák csökkentése: A 15 másodperces timeout jelentősen csökkenti a "poor connection" üzeneteket
- ✅ Tiszta állapot: Minden disconnect után teljesen kitisztított állapotból indul az új kapcsolódás
- ✅ Event handler stabilitás: Az event handlerek most már nem vesznek el újrainicializálás során
- ✅ Jobb error handling: Try-catch blokkok és részletes logging a problémák könnyebb diagnosztizálásához
Korábbi javítások
Map szinkronizáció javítás (c4eb7e9)
- Javítva: A client-ek rossz map paraméterekkel generáltak világot
- Megoldás: WorldSeed packet most tartalmazza az összes szükséges map paramétert (size, type, rivers)
StartGame NullReferenceException javítás (fc467f4)
- Javítva: NullReferenceException a multiplayer játék indításakor
- Megoldás: Eltávolítva a MainMenuMode.StartGame() reflection hívás, közvetlen átmenet playing mode-ba
Telepítés
- Másold a mod fájljait a Kingdoms and Castles mod mappájába
- Aktiváld a modot a játék mod menüjében
- Indítsd újra a játékot
Használat
Server létrehozása
- Főmenü -> Multiplayer
- Create Server
- Állítsd be a szerver beállításokat
- Várd meg, hogy a játékosok csatlakozzanak
Csatlakozás serverhez
- Főmenü -> Multiplayer
- Válaszd ki a servert a listából
- Kattints a "Join" gombra
Asset Bundle hibák javítása (2025-12-14)
Probléma
Ha az "serverbrowserpkg" asset bundle fájl hiányzik a mod könyvtárából, a mod NullReferenceException-öket dobott több helyen:
- PrefabManager.PreScriptLoad(): Crash az asset bundle betöltésekor
- ServerBrowser.SceneLoaded(): Crash amikor null prefab-okat próbált instantiate-lni
- Main.TransitionTo(): Crash amikor null UI referenciákat próbált elérni
Megoldások
PrefabManager.cs:31-36
- Null check az asset bundle betöltés után
- Ha az asset bundle null, részletes hibaüzenet és early return
- Egyértelmű útmutatás a felhasználónak
ServerBrowser.cs:302-309
- Prefab null check a SceneLoaded elején
- Ha a prefabok null-ok, részletes hibaüzenet és early return
- Megakadályozza a crash-t és informálja a felhasználót
Main.cs:228-244
- Null check minden UI referencia használata előtt
- Ha a felhasználó a multiplayer menüt próbálja megnyitni de az UI nincs betöltve:
- Részletes modal üzenet jelenik meg
- A játék nem crash-el
- Útmutatás a probléma megoldásához
Érintett kód részletek:
// PrefabManager.cs
if (assetBundle == null)
{
Main.helper.Log("ERROR: Asset bundle 'serverbrowserpkg' not found! UI features will not work.");
Main.helper.Log("Please ensure the asset bundle file is in the mod directory.");
return;
}
// ServerBrowser.cs
if (PrefabManager.serverBrowserPrefab == null || PrefabManager.serverLobbyPrefab == null)
{
Main.helper.Log("ERROR: UI prefabs not loaded. Asset bundle is missing.");
return;
}
// Main.cs
if (ServerBrowser.serverBrowserRef != null && ServerBrowser.serverLobbyRef != null)
{
// Safe to use UI references
}
else if ((int)state > 21)
{
// Show error modal instead of crashing
ModalManager.ShowModal("Multiplayer Not Available", "...");
}
Eredmények:
- ✅ Nincs crash ha az asset bundle hiányzik
- ✅ Világos hibaüzenetek a felhasználónak
- ✅ Graceful degradation - a mod többi része működik
- ✅ Útmutatás a probléma megoldásához
MEGJEGYZÉS: Az asset bundle fájl jelenleg hiányzik a mod könyvtárából. A multiplayer UI funkciók működéséhez szükséges a "serverbrowserpkg" fájl hozzáadása.
Ismert problémák
-
Hiányzó Asset Bundle: A "serverbrowserpkg" asset bundle fájl jelenleg hiányzik a mod könyvtárából. Ez azt jelenti, hogy:
- A multiplayer UI (Server Browser, Server Lobby) nem jelenik meg
- A Multiplayer gomb a főmenüben hibaüzenetet fog mutatni
- A mod többi része (connection handling, stb.) továbbra is működik
Megoldás: Helyezd el a "serverbrowserpkg" fájlt a mod gyökérkönyvtárába és indítsd újra a játékot.
Ha egyéb hibát találsz, kérlek jelentsd a fejlesztőknek.
Fejlesztői megjegyzések
Debugging
A mod részletes loggolást tartalmaz, amely segít a problémák diagnosztizálásában. A logok a következő helyeken jelennek meg:
[WORLD SYNC]prefix: World generation szinkronizációs eseményekLeaveLobby called-Lobby cleanup completed: Disconnect/cleanup folyamat
Hozzájárulás
Ha szeretnél hozzájárulni a mod fejlesztéséhez, pull request-eket szívesen fogadunk!
Licensz
Ez a mod a Riptide Networking library-t használja, amely MIT licensz alatt áll.