Comment by squidleon
15 hours ago
Thanks! Yeah, one of the main motivations was exactly that — after years working with legacy UO codebases where networking, persistence, and game logic were deeply intertwined, I wanted to see what a clean-slate approach would look like with modern .NET.
On sector sync bursts — this is something I'm actively tuning. Right now when a player enters a new sector, we sync all ground items and mobiles in the surrounding sectors (configurable radius). For busy areas that can mean a lot of packets at once. The current approach is:
- Sector enter sync only sends the delta sectors the player wasn't already seeing, so a simple move into an adjacent sector doesn't resync everything
- Sectors close to the player (within 1 of center) are always resynced because the UO client silently drops items beyond its visual range (~18 tiles), so you need to re-send them when the player comes back
- The outgoing packet queue handles the actual send, so the game loop isn't blocked waiting for network I/O
That said, there's definitely room for prioritization (mobiles first, then nearby items, then distant items) and spreading the sync across multiple ticks instead of one burst. It's on the roadmap.
On NativeAOT — honestly, both. The single-binary deployment is great for Docker (small image, instant startup), but the real win is predictable performance. No JIT warmup, no tiered compilation surprises
mid-session. For a game server where you care about consistent tick timing, eliminating that variable is worth it. The tradeoff is you lose some runtime flexibility, but source generators fill most of that gap
(packet registration, serialization, etc.).
No comments yet
Contribute on Hacker News ↗