using System.Collections.Concurrent; using Microsoft.Extensions.Options; namespace NeonSprawl.Server.Game.PositionState; /// Thread-safe in-memory positions; seeds the configured dev player on construction. public sealed class InMemoryPositionStateStore : IPositionStateStore { private readonly ConcurrentDictionary _positions = new(StringComparer.OrdinalIgnoreCase); public InMemoryPositionStateStore(IOptions options) { var o = options.Value; var id = o.DevPlayerId.Trim(); if (id.Length == 0) throw new InvalidOperationException("Game:DevPlayerId must be non-empty."); var p = o.DefaultPosition ?? new DefaultPositionOptions(); _positions[id] = new PositionSnapshot(p.X, p.Y, p.Z, 0); } public bool TryGetPosition(string playerId, out PositionSnapshot snapshot) { var key = playerId?.Trim(); if (string.IsNullOrEmpty(key)) { snapshot = default; return false; } return _positions.TryGetValue(key, out snapshot); } }