
CHANGELOG
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.1.0] - 2025-05-07
Added
- R.E.P.O. Beta Compatibility:
- Full support for R.E.P.O. Open Beta
0.1.2_22beta
alongside stable0.1.2
. - Implemented dynamic game version detection (
GameVersionSupport.cs
) to correctly interface with differentSteamManager.UnlockLobby()
signatures (parameterless for stable,UnlockLobby(bool open)
for beta). This ensures proper Steam lobby visibility control across game versions.
- Full support for R.E.P.O. Open Beta
- Museum Map (
Module
) Support:- Introduced synchronization for
Module
components (LateJoinManager.SyncModuleConnectionStatesForPlayer
). - Late joiners will now correctly see the connection states (Top, Bottom, Left, Right, First) of map modules, crucial for new maps like "Museum" that utilize this system. This is achieved by re-sending the
ModuleConnectionSetRPC
to the joining player. - Added reflection helpers for
Module
fields (SetupDone
,ConnectingTop
, etc.) inUtilities.cs
.
- Introduced synchronization for
- Early Lobby Locking Mechanism:
- The game lobby is now locked earlier during level transitions initiated from the truck screen (e.g., when "Start Game" or "Return to Lobby with Loot" is confirmed).
- This is achieved by new prefix patches on
TruckScreenText.PlayerChatBoxStateLockedDestroySlackers
andTruckScreenText.PlayerChatBoxStateLockedStartingTruck
. - This proactive locking (
EarlyLobbyLockHelper.TryLockLobby
) prevents players from joining during potentially unstable mid-transition phases, beforeRunManager.ChangeLevel
fully manages the lobby state.
- Lobby Unlock Failsafe:
- Implemented a coroutine-based failsafe (
Patches.LobbyUnlockFailsafeCoroutine
) to ensure the game lobby unlocks if the intended mechanism (viaGameDirector.SetStart
) is prevented from running (e.g., due to another mod's interference). - If the lobby is meant to be open but remains locked after a timeout, the failsafe will force it open. This is armed during
RunManager_ChangeLevelHook_Postfix
and disarmed byGameDirector_SetStart_Postfix
.
- Implemented a coroutine-based failsafe (
- Configurable Lobby Lock on Level Generation Failure:
- Added a new configuration option:
Lock Lobby On Level Generation Failure
(Default:true
) under the "Late Join Behavior" section. - When
true
(default), if a level reports a generation failure (and doesn't transition to the Arena), the lobby will be locked, preventing late joins. - When
false
, if a modded level reports a generation failure but the game continues (i.e., doesn't crash to Arena), L.A.T.E. will still evaluate normal scene-based join rules (Shop, Truck, Level) as if the failure didn't occur. This can be useful for modded levels that might incorrectly flag a failure but still load. This setting does not affect true failures that lead to the Arena scene.
- Added a new configuration option:
Changed
- Enhanced Hinge/Door Synchronization:
- Improved synchronization for
PhysGrabHinge
objects (e.g., doors, lockers, cabinets). - In addition to the existing
broken
state sync (HingeBreakRPC
), the mod now also syncs the open/closed state for late joiners using thePhysGrabHinge.closed
field andOpenImpulseRPC
. (Ref:DestructionManager.SyncHingeStatesForPlayer
) - This provides a more consistent visual and interactive state for these objects.
- Improved synchronization for
- Lobby Open/Close Logic Refinement:
- The
Patches.ShouldAllowLobbyJoin
logic now uses directRunManager
level instance comparisons (e.g.,runManager.levelCurrent == runManager.levelArena
) instead of relying solely onSemiFunc
helper methods. This offers more precise control over lobby joinability based on the current scene, especially during level transitions. GameDirector.SetStart
(postfix patch) is now the definitive point for unlocking the lobby after level generation and loading, if conditions permit. It also handles disarming the new lobby unlock failsafe.
- The
- Mod Incompatibility Documentation:
- Updated
README.md
to reflect successful testing and support for R.E.P.O.0.1.2_22beta
. - Added new known mod incompatibilities to
README.md
:FastStartup
Imperium_Repo
(due to patchingLevelAnimationCompleted
)
- Updated
Fixed
- Resolved
BerserkerEnemies
Incompatibility: Addressed a previous incompatibility withBerserkerEnemies
that could cause issues with level generation completion hooks (e.g., preventing L.A.T.E.'sGameDirector.SetStart
postfix from running).- This was fixed by adjusting Harmony patch execution order, specifically by applying
[HarmonyPriority(Priority.Last)]
to L.A.T.E.'sGameDirector_SetStart_Postfix
andPlayerAvatar_LoadingLevelAnimationCompletedRPC_Prefix
patches. - This ensures L.A.T.E.'s critical lobby management and synchronization logic executes after potentially conflicting modifications from other mods that hook into the same game methods.
- This was fixed by adjusting Harmony patch execution order, specifically by applying
[1.0.0] - 2025-05-05
Initial Release
Added
- Core functionality allowing players to join games already in progress (Late Joining).
- Host-Only operation: Mod logic runs entirely on the host.
- Configuration options (
BepInEx/config/LATE.cfg
):- Enable/disable joining in Shop, Truck, Level, Arena scenes.
- Option to re-kill players who died before leaving/rejoining the same level instance (
Kill If Previously Dead
). - Option to spawn rejoining players at their last known position or death head (
Spawn At Last Position
). - Advanced option to force a level reload for everyone on late join (
Force Level Reload on Late Join
). - Configurable log level for debugging (
Log Level
).
- Comprehensive state synchronization for late joiners:
- Level state (
RunManager
: level name, completion status, game over). - Level generation completion (
LevelGenerator
). - Extraction Point state (
ExtractionPoint
: state, goal fetched, current goal value, surplus value, shop status, active/inactive status). - Valuable Objects (
ValuableObject
: current dollar value). - Shop Items (
ItemAttributes
: current value). - Player Death Status (
PlayerStateManager
,PlayerAvatar.PlayerDeathRPC
). - Truck Screen (
TruckScreenText
: initialization, current page). - Prop Switch setup trigger (
ValuableDirector
). - Destroyed Physics Objects (
PhysGrabObject.DestroyPhysGrabObjectRPC
). - Destroyed Impact Objects (
PhysGrabObjectImpactDetector.DestroyObjectRPC
). - Broken Hinges (
PhysGrabHinge.DestroyHingeRPC
,HingeBreakRPC
). - Item States via specific RPCs:
ItemToggle
:ToggleItemRPC
(On/Off),ToggleDisableRPC
(Interactable).ItemBattery
:BatteryFullPercentChangeRPC
.ItemMine
:StateSetRPC
.ItemMelee
:MeleeBreakRPC
,MeleeFixRPC
.ItemDrone
:ButtonToggleRPC
.ItemHealthPack
:UsedRPC
.ItemGrenade
:TickStartRPC
.ItemTracker
:SetTargetRPC
.
- Enemy synchronization:
- Spawn/Despawn status via
EnemyParent
(SpawnRPC
,DespawnRPC
). - Target Player View ID (
Enemy.TargetPlayerViewID
,UpdatePlayerTargetRPC
, etc.). - Frozen status (
Enemy.FreezeRPC
). - Specific states/targets for numerous enemy types (Animal, Bang, Beamer, etc. - see README for full list).
- Notifies enemies when players join (
PlayerAdded
) or leave (PlayerRemoved
).
- Spawn/Despawn status via
- Arena-specific state (
Arena
):DestroyCrownCageRPC
,CrownGrabRPC
(Winner),PlayerKilledRPC
(Pedestal Count). - Voice chat state initialization (
VoiceManager
,PlayerAvatar.UpdateMyPlayerVoiceChat
).
- Level state (
- Player Position Tracking (
PlayerPositionManager
) forSpawn At Last Position
feature. - Patching Mechanisms:
- Uses HarmonyLib (Attribute and Explicit patches) and MonoMod Hooks.
- Patches
NetworkManager
,RunManager
,PlayerAvatar
,PhysGrabObject
,PhysGrabObjectImpactDetector
,PhysGrabHinge
,EnemyVision
,EnemyTriggerAttack
,NetworkConnect
,GameDirector
.
- Utilities class (
Utilities
) for caching reflected members and helper functions. - Fix for potential
EnemyVision
dictionary errors when late joiners trigger vision/attacks. - Forces
PhotonNetwork.AutomaticallySyncScene = true
early for joining clients viaNetworkConnect
patch. - Extraction Point Item Resync: Teleports items in the EP out and back to force clients to re-evaluate their state (addresses potential value desync).