Last Update: 2023-07-06
Case Study: Global Position CompleteSync Mod
This case study examines the implementation of the Global Position CompleteSync mod, which enhances multiplayer gameplay in Don't Starve Together by providing complete map synchronization and player position tracking.
Overview
The Global Position CompleteSync mod extends the original Global Positions functionality with comprehensive map synchronization between players. Unlike the basic position sharing, this mod ensures that:
- New players joining a server can see areas previously explored by other players
- Players moving between cave and surface worlds can see areas explored by others before they arrived
- Map discoveries from special events (like reading a Message in a Bottle) are shared with all players
- Players can place ping markers on the map for communication
Key Components
Component Architecture
The mod uses several key components to manage position tracking and map synchronization:
Component | Purpose |
---|---|
globalposition | Manages individual entity positions on the map |
globalpositions | Central system that tracks all entities with position data |
shard_isgpsnewlyadded | Handles cross-shard (world) communication for map updates |
smokeemitter | Visual effect for entities visible on the map |
UI Elements
The mod implements several custom UI widgets:
pingwheel
: Radial menu for selecting ping typespingbadge
: Visual representation of pings on the mapmaphoverer
: Tooltip system for map elements
Network Architecture
The implementation uses classified objects for network synchronization, with carefully managed authority:
function GlobalPosition:OnUpdate(dt)
local pos = self.inst:GetPosition()
if self._x ~= pos.x or self._z ~= pos.z then
self._x = pos.x
self._z = pos.z
self.classified.Transform:SetPosition(pos:Get())
end
end
Implementation Details
Map Data Synchronization
The mod's core functionality is complete map synchronization across players and shards. This is achieved through:
- A map buffer system that stores exploration data
- Cross-shard RPC handlers for map data transfer
- Player-join detection to trigger map synchronization for new players
local function player2player_via_buffer(world, player_from, player_to)
save_to_buffer(world, player_from)
learn_from_buffer(world, player_to)
end
Performance Optimization
The mod includes optimizations to prevent lag when traversing between shards:
local STOPSAVEMAPEXPLORER = GetModConfigData("STOPSAVEMAPEXPLORER") and is_dedicated
if STOPSAVEMAPEXPLORER then
-- Custom implementation of SerializeUserSession to avoid saving map data redundantly
GLOBAL.SerializeUserSession = function (player, isnewspawn)
-- Implementation details...
end
end
Ping System
The ping system allows players to mark locations on the map with different meanings:
- Generic ping (rally point)
- "Go here" ping
- "Explore" ping
- "Danger" ping
- "On my way" ping
Each ping type has custom visuals and can be placed using a radial menu accessible by Alt+clicking on the map.
Integration with Game Systems
Entity Component System
The mod leverages Don't Starve Together's entity component system by:
- Adding components to entities that need position tracking
- Using prefabs for visual representations on the map
- Hooking into the game's event system for updates
Minimap Integration
Integration with the game's minimap is achieved through:
function AddGlobalIcon(inst, isplayer, classified)
if not (_GLOBALPOSITIONS_MAP_ICONS[inst.prefab] or inst.MiniMapEntity) then return end
classified.icon = SpawnPrefab("globalmapicon_noproxy")
classified.icon.MiniMapEntity:SetPriority(10)
classified.icon.MiniMapEntity:SetRestriction("player")
-- Additional configuration...
end
Cross-Shard Communication
The mod handles communication between different world shards (surface/caves) using:
AddShardModRPCHandler(modname, "ShardIncreaseCounter", function()
if GLOBAL.TheWorld.ismastershard then
GLOBAL.TheWorld.shard.components.shard_isgpsnewlyadded:IncreaseCounter()
else
return
end
end)
Learning Points
Effective Uses of Components
The mod demonstrates how to create and use components for:
- Tracking entity positions (
globalposition
) - Managing shared state (
globalpositions
) - Cross-shard communication (
shard_isgpsnewlyadded
)
Network Optimization
The mod employs several techniques for network efficiency:
- Using classified entities for network variables
- Buffering map data to minimize network traffic
- Conditional updates that only send data when needed
UI Implementation
The custom UI elements showcase:
- Creating interactive widgets (the ping wheel)
- Following input from different control schemes (mouse/controller)
- Creating tooltips and informational UI elements
See Also
- Component System - For understanding how components work
- Network System - For details on network synchronization
- Client-Server Synchronization - For best practices in networking
- Map API - For map-related functionality
- UI System - For creating UI elements
Further Reading
- Event System - For understanding event handling used in the mod
- EntityScript - For entity manipulation techniques
- Custom UI Elements - For more examples of UI implementation