@@ -22,6 +22,8 @@ public sealed class PeerSimulation : IPeerSimulation
2222 private const uint PEER_DISCONNECTION_CLEAN_TIMEOUT = 5000 ;
2323 private const uint PEER_PENDING_AUTH_CLEAN_TIMEOUT = 30000 ;
2424
25+ public const string SELF_MIRROR_WALLET_ID = "self_mirror" ;
26+
2527 private readonly IAreaOfInterest areaOfInterest ;
2628 private readonly SnapshotBoard snapshotBoard ;
2729 private readonly SpatialGrid spatialGrid ;
@@ -33,6 +35,8 @@ public sealed class PeerSimulation : IPeerSimulation
3335 private readonly ProfileBoard profileBoard ;
3436 private readonly EmoteBoard emoteBoard ;
3537 private readonly ILogger < PeerSimulation > logger ;
38+ private readonly bool selfMirrorEnabled ;
39+ private readonly PeerViewSimulationTier selfMirrorTier ;
3640
3741 /// <summary>
3842 /// Per-observer views: observer PeerIndex → (subject PeerIndex → view).
@@ -71,7 +75,9 @@ public PeerSimulation(
7175 ITransport transport ,
7276 ProfileBoard profileBoard ,
7377 EmoteBoard emoteBoard ,
74- ILogger < PeerSimulation > logger )
78+ ILogger < PeerSimulation > logger ,
79+ bool selfMirrorEnabled = false ,
80+ int selfMirrorTier = 0 )
7581 {
7682 this . areaOfInterest = areaOfInterest ;
7783 this . snapshotBoard = snapshotBoard ;
@@ -84,6 +90,8 @@ public PeerSimulation(
8490 this . profileBoard = profileBoard ;
8591 this . emoteBoard = emoteBoard ;
8692 this . logger = logger ;
93+ this . selfMirrorEnabled = selfMirrorEnabled ;
94+ this . selfMirrorTier = new PeerViewSimulationTier ( ( byte ) selfMirrorTier ) ;
8795
8896 BaseTickMs = simulationSteps [ 0 ] ;
8997 tierDivisors = new uint [ simulationSteps . Length ] ;
@@ -145,6 +153,9 @@ public void SimulateTick(Dictionary<PeerIndex, PeerState> peers, uint tickCounte
145153 collector . Clear ( ) ;
146154 areaOfInterest . GetVisibleSubjects ( observerId , in observerSnapshot , collector ) ;
147155
156+ if ( selfMirrorEnabled )
157+ collector . Add ( observerId , selfMirrorTier ) ;
158+
148159 ProcessVisibleSubjects ( observerId , views , observerState . ResyncRequests , tickCounter ) ;
149160
150161 observerState . ResyncRequests ? . Clear ( ) ;
@@ -177,7 +188,9 @@ private void ProcessVisibleSubjects(
177188 {
178189 InterestEntry entry = collector . Entries [ i ] ;
179190
180- if ( entry . Subject == observerId )
191+ bool isSelfMirror = entry . Subject == observerId ;
192+
193+ if ( isSelfMirror && ! selfMirrorEnabled )
181194 continue ;
182195
183196 bool isNew = ! views . TryGetValue ( entry . Subject , out PeerToPeerView view ) ;
@@ -213,11 +226,15 @@ private void ProcessVisibleSubjects(
213226
214227 int profileVersion = profileBoard . Get ( entry . Subject ) ;
215228
229+ string ? userId = isSelfMirror
230+ ? SELF_MIRROR_WALLET_ID
231+ : identityBoard . GetWalletIdByPeerIndex ( entry . Subject ) ;
232+
216233 messagePipe . Send ( new OutgoingMessage ( observerId , new ServerMessage
217234 {
218235 PlayerJoined = new PlayerJoined
219236 {
220- UserId = identityBoard . GetWalletIdByPeerIndex ( entry . Subject ) ,
237+ UserId = userId ,
221238 ProfileVersion = profileVersion ,
222239 State = CreateFullState ( entry . Subject , subjectSnapshot ) ,
223240 } ,
@@ -277,7 +294,7 @@ void TryAnnounceProfile()
277294
278295 void SyncEmoteState ( )
279296 {
280- // If the emote completion has not been process by the peer's worker yet, try to complete it now
297+ // If the emote completion has not been processed by the peer's worker yet, try to complete it now
281298 emoteBoard . TryComplete ( entry . Subject , timeProvider . MonotonicTime ) ;
282299
283300 EmoteState ? emoteState = emoteBoard . Get ( entry . Subject ) ;
0 commit comments