Fix: Add periodic villager position sync from server
- Server syncs villager positions every ~3 seconds to clients - Only syncs villagers that moved more than 0.5 units (bandwidth optimization) - Maintains position cache to detect movement - Clears cache on lobby leave to prevent stale data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
86
Main.cs
86
Main.cs
@@ -182,43 +182,75 @@ namespace KCM
|
||||
#endregion
|
||||
|
||||
public static int FixedUpdateInterval = 0;
|
||||
private static Dictionary<Guid, Vector3> lastVillagerPositions = new Dictionary<Guid, Vector3>();
|
||||
|
||||
public static void ClearVillagerPositionCache()
|
||||
{
|
||||
lastVillagerPositions.Clear();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
// send batched building placement info
|
||||
/*if (PlaceHook.QueuedBuildings.Count > 0 && (FixedUpdateInterval % 25 == 0))
|
||||
// Periodic villager position sync from server to clients
|
||||
// Sync every 150 frames (~3 seconds at 50 FPS) to reduce bandwidth
|
||||
if (KCServer.IsRunning && KCClient.client.IsConnected && FixedUpdateInterval % 150 == 0)
|
||||
{
|
||||
foreach (Building building in PlaceHook.QueuedBuildings)
|
||||
try
|
||||
{
|
||||
new WorldPlace()
|
||||
{
|
||||
uniqueName = building.UniqueName,
|
||||
customName = building.customName,
|
||||
guid = building.guid,
|
||||
rotation = building.transform.GetChild(0).rotation,
|
||||
globalPosition = building.transform.position,
|
||||
localPosition = building.transform.GetChild(0).localPosition,
|
||||
built = building.IsBuilt(),
|
||||
placed = building.IsPlaced(),
|
||||
open = building.Open,
|
||||
doBuildAnimation = building.doBuildAnimation,
|
||||
constructionPaused = building.constructionPaused,
|
||||
constructionProgress = building.constructionProgress,
|
||||
life = building.Life,
|
||||
ModifiedMaxLife = building.ModifiedMaxLife,
|
||||
//CollectForBuild = CollectForBuild,
|
||||
yearBuilt = building.YearBuilt,
|
||||
decayProtection = building.decayProtection,
|
||||
seenByPlayer = building.seenByPlayer
|
||||
}.Send();
|
||||
SyncVillagerPositions();
|
||||
}
|
||||
|
||||
PlaceHook.QueuedBuildings.Clear();
|
||||
}*/
|
||||
catch (Exception e)
|
||||
{
|
||||
helper.Log($"Error in villager sync: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
FixedUpdateInterval++;
|
||||
}
|
||||
|
||||
private void SyncVillagerPositions()
|
||||
{
|
||||
// Only sync villagers that have moved significantly
|
||||
const float movementThreshold = 0.5f;
|
||||
|
||||
foreach (var kcPlayer in kCPlayers.Values)
|
||||
{
|
||||
if (kcPlayer.inst == null) continue;
|
||||
|
||||
for (int i = 0; i < kcPlayer.inst.Workers.Count; i++)
|
||||
{
|
||||
var villager = kcPlayer.inst.Workers.data[i];
|
||||
if (villager == null) continue;
|
||||
|
||||
Vector3 currentPos = villager.Pos;
|
||||
Vector3 lastPos;
|
||||
|
||||
bool shouldSync = false;
|
||||
if (!lastVillagerPositions.TryGetValue(villager.guid, out lastPos))
|
||||
{
|
||||
// First time seeing this villager
|
||||
lastVillagerPositions[villager.guid] = currentPos;
|
||||
shouldSync = true;
|
||||
}
|
||||
else if (Vector3.Distance(currentPos, lastPos) > movementThreshold)
|
||||
{
|
||||
// Villager has moved significantly
|
||||
lastVillagerPositions[villager.guid] = currentPos;
|
||||
shouldSync = true;
|
||||
}
|
||||
|
||||
if (shouldSync)
|
||||
{
|
||||
new Packets.Game.GameVillager.VillagerTeleportTo()
|
||||
{
|
||||
guid = villager.guid,
|
||||
pos = currentPos
|
||||
}.SendToAll(KCClient.client.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region "TransitionTo"
|
||||
public static void TransitionTo(MenuState state)
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ namespace Riptide.Demos.Steam.PlayerHosted
|
||||
Main.helper.Log("clear players");
|
||||
Main.kCPlayers.Clear();
|
||||
Main.clientSteamIds.Clear(); // Clear client-to-steam ID mapping
|
||||
Main.ClearVillagerPositionCache(); // Clear villager sync cache
|
||||
LobbyHandler.ClearPlayerList();
|
||||
LobbyHandler.ClearChatEntries();
|
||||
Main.helper.Log("end clear players");
|
||||
|
||||
Reference in New Issue
Block a user