11 ms·
Show HN: Moongate – Ultima Online server emulator in .NET 10 with Lua scripting
I've been building a modern Ultima Online server emulator from scratch. It's not feature-complete (no combat, no skills yet), but the foundation is solid and I wanted to share it early.
What it does today:
- Full packet layer for the classic UO client (login, movement, items, mobiles)
- Lua scripting for item behaviors (double-click a potion, open a door — all defined in Lua, no C# recompile)
- Spatial world partitioned into sectors with delta sync (only sends packets for new sectors when crossing boundaries)
- Snapshot-based persistence with MessagePack
- Source generators for automatic DI wiring, packet handler registration, and Lua module exposure
- NativeAOT support — the server compiles to a single native binary
- Embedded HTTP admin API + React management UI
- Auto-generated doors from map statics (same algorithm as ModernUO/RunUO)
Tech stack: .NET 10, NativeAOT, NLua, MessagePack, DryIoc, Kestrel
What's missing: Combat, skills, weather integration, NPC AI. This is still early — the focus so far has been on getting the architecture right so adding those systems doesn't require rewiring everything.
Why not just use ModernUO/RunUO? Those are mature and battle-tested. I started this because I wanted to rethink the architecture from scratch: strict network/domain separation, event-driven game loop, no
inheritance-heavy item hierarchies, and Lua for rapid iteration on game logic without recompiling.
GitHub: https://github.com/moongate-community/moongatev2 https://github.com/moongate-community/moongatev2
- onlyrealcuzzo 7mo agoI love your logo. Do you have a YouTube that shows off the progress of what's complete?
- squidleon 7mo agoThanks! The logo was a happy accident. I wanted something simple that felt like the moongates (so and so :) from the original game. I'm not really a video person. But here's what's working today: login flow, character creation, world movement with delta sector sync, auto-generated doors from map statics (that actually open), Lua scripting for item behaviors, snapshot persistence, and a React admin UI for server management. I'll probably add a short demo gif or video to the README at some point, but for now the best way to see it is to clone it and run it
- devin 7mo agoCongratulations! I don't know how busy player-run shards are these days, but I look forward to exploring this once you've gotten it a bit further.
- squidleon 7mo agoThanks! There are still a few active shards out there, mostly us "old guys" in our 40s chasing the nostalgia of our teenage years. UO has a way of never really dying. Combat and skills are still a ways off, but the foundation is solid enough that I'm adding features every week (in spare times,) I'll keep pushing updates!
- D13Fd 7mo agoUO was such a big part of my life back then, it’s great to hear that it’s still going. Maybe I’ll set up a server to play with my kids - although they’ll never be able to get the full experience with player killers, trolls, scammers, people hawking their stuff at the bank, dragon trainers, etc.
- Fokamul 7mo agoThere are several PvE UO servers, which are heavily against griefing. So I would say, pretty safe environment to play there with your kids and still with other people.
- squidleon 7mo agoThat's a great idea, UO is honestly perfect for playing with kids. The crafting, housing, exploring dungeons together. And who knows, maybe you become the dragon trainer this time around!
- HanClinto 7mo agoI've been tinkering with the same thing -- wanting to set up a little server so that we can all play together as a family. We've enjoyed Diablo 2, Minecraft, and Terraria as a family, but I feel like it would be fun to set up a little UO server. I'd really like to find a good tutorial for how to set up a chill / casual-friendly server (I like there to be some grind, but I don't want it to feel like "stock" UO) -- so something with accelerated skill gains and whatnot. I don't know if there are "family-friendly" presets for such things, but so far Copilot has been reasonably helpful at helping me along -- I just don't have it all working yet. If you have any resources you come across, I would be interested in comparing notes. :)
- zdware 7mo agoAhhh this takes me back to playing on various private UO and DAoC servers. Part of that experience is why I am a developer today. Cool name for a project like this along with the art!
- squidleon 7mo agoSame here! tinkering with private servers is what got me into programmig in the first place. There's something about reverse-engineering a game protocol at 15 that hooks you for life. Thanks for the kind words on the name and art!
- eclipticplane 7mo agoMost of my sick days in high school were after big Ultima Online patches dropped, I believe, usually on Tuesdays. A neighbor had much faster internet - I think his dad did work from home? - so I'd download the patch onto a ZIP drive and sprint back home. Then spent the day debugging changes (client changes and network/protocol changes) with others on IRC to get SphereServer to connect again. Learned so much.
- jghn 7mo ago> A neighbor had much faster internet In the very, very early days I had a 6ms ping to my server on a then high bandwidth connection. This was when most players were at best on a 28.8 modem with multihundred ms ping times. I remember being able to easily outrun people who were on horses. My roommate and I could sit next to each other and between the combination of our connection and the advantage voice communication provided for coordination was an enormous advantage. We spent a lot of time in PK hot spots pretending to be lagged newbies, only to give the PK gangs a rude awakening when they'd come to grief us. Turns out a pair of toons who were multi-GMs when most weren't a single GM yet, who were lighting fast compared to others, and with perfect coordination made short work of your average PK gang back then
- picklepete 7mo agoThis is so cool! I used to love playing around with RunUO back ~2003, it's great to see the community stay alive.
- squidleon 7mo agoThank you! RunUO in 2003 was the golden era. I started little bit early (1999 with 56k). The community is small but still alive, and projects like ModernUO have kept things moving forward. Moongate is my take on rethinking the architecture from scratch while keeping the same spirit. Glad to see people still care about this stuff! :*
- kethinov 7mo agoI'm a fan of UO and I love seeing more projects like this. Nice work! Obligatory nitpicky aside, a time-honored tradition of HN: I've long been irritated by the use of the term "server emulator" in gaming contexts. Technically these projects are just reimplementations of a proprietary networking protocol. Nobody calls Samba a "server emulator" because it reimplements the Windows file sharing protocol, because Samba isn't "emulating" anything from the perspective of the traditional definition of "emulator" in computer science. But for some reason, I guess because "emulator" has colloquially been redefined by non-CS nerd gamer normies as a term for software that lets you play proprietary games on platforms they were not designed for, we have ended up in this new status quo where the term's definition has expanded in this game of telephone way that annoys mainly me and not many other people. And what's kinda funny is I say that it is a "new" status quo, but it's not even that new. I recall, what, like 20 years ago now I was in an edit war on Wikipedia fighting with people over the "server emulator" article, insisting that the term was technically inaccurate and should not be used. Unsurprisingly in retrospect, I lost that edit war. Nowadays the whole thing feels like my first "old man yells at cloud" moment, of which I'm sure I'll experience more as I age. I certainly do find new slang introduced by gen Z like "he got the riz!" to be quite cringey, so it looks like I'm well on my way to getting crotchety and terrible about the natural evolution of language! ;)
- daeken 7mo ago> I certainly do find new slang introduced by gen Z like "he got the riz!" to be quite cringey This is interesting to me, if only because it's such a natural bit of slang. Given that it's a shortened form of "charisma", this one just Makes Sense to me! I figure it'd be incredibly cringe for me to use at my age, but it's a good term IMO.
- kethinov 7mo agoYou're right, it absolutely does make sense. And yet it annoys me anyway. There's been research by linguists (John McWhorter comes to mind) analyzing this phenomenon and it basically just comes down to the fact that as we age, we get more set in our ways, so the linguistic innovations that younger people do just have a tendency to annoy us, even when they logically follow or are objectively useful. I try not to let it bother me, because it's irrational to feel that way, but it just does lol
- p0w3n3d 7mo agoI remember PvPGN. I believe it's still out there https://github.com/D2GSE/pvpgn-server https://github.com/D2GSE/pvpgn-server
- haolez 7mo agoUO was the only game that I've ever played where you had "commoner" players. A lot of players failed to scale up, or to obtain top notch equipment. But the game was fun even for underpowered players, so they kept playing. The really powerful players were famous, like celebrities. It's very different from modern games, where each player looks like the fantasy version of a Marvel super hero.
- squidleon 7mo agoThis is such a good observation. UO had a real economy and social hierarchy because power wasn't handed to you. You could spend months as a fisherman or tailor and still have a meaningful experience. The gap between a grandmaster swordsman in full plate and a guy selling fish at the Britain bank was enormous, and both of them were having fun. Modern MMOs are theme parks where everyone gets the same ride (with pay per win). UO was a living world where your role emerged from what you chose to do, not from a quest marker telling you where to go next.
- haolez 7mo agoIf starting from scratch, what would an MMO need to replicate that? I've experienced it first hand, but I can't grasp why it worked well like it did.
- NDizzle 7mo agoWell, it was kind of the only game in town. Sure, you had Dark Sun Online and Meridian 59, but in 96/97 you were playing UO if you liked the idea of online worlds. I think the barrier to entry is the equivalent of several complete, fun, balanced single player games operating together in balanced harmony. Not impossible, but highly improbable.
- haolez 7mo agoBtw, I've never met a player of Meridian 59, but seeing YouTube videos about it, it might have been popular in my community if we had access to it at the time. Looks super interesting, although it didn't age well, of course.
- DeathArrow 7mo agoI like seeing how more projects use .NET, which is a great platform.
- squidleon 7mo agoThanks! I've been developing in .NET for 20 years and it's come a long way , from the Windows-only Framework days to what it is now. NativeAOT, cross-platform, incredible performance. And if you've never tried it on Apple Silicon the M4 chips are absolutely insane. The server compiles to a single native binary and runs like a dream on ARM.
- oblio 7mo agoHave you built mobile apps with it?
- nebezb 7mo agoWow! This is no small feat... am I reading the contribution graph[0] correctly, you've done all this yourself? This endeavour sounds a whole lot like a server emulator for Infantry Online that was started by an incredibly talented developed 16 years ago ("aaerox"). I found the original svn commit on Sourceforge [1]. It's since moved to GitHub but has been active for 16 years and it has much of the same functionality you've already built, but done by more than a dozen developers over a decade-and-a-half. Kudos to you. You've gotta explain how you've managed to do so much all by yourself. [0] https://github.com/moongate-community/moongatev2/graphs/contributors https://github.com/moongate-community/moongatev2/graphs/cont... [1] https://sourceforge.net/p/infserver/code/1/ https://sourceforge.net/p/infserver/code/1/
- squidleon 7mo agoSo: I took most of the infrastructure from the my first attempt at moongate (https://github.com/moongate-community/moongate https://github.com/moongate-community/moongate, which failed miserably along with https://github.com/tgiachi/Prima https://github.com/tgiachi/Prima). From there, I had a good starting point to quickly build the foundations. I had already done the Lua scripting part in another project (https://github.com/tgiachi/Lilly.Engine https://github.com/tgiachi/Lilly.Engine). Codex helped me with all the testing, implementing functionality and creating tests, so at least I have a good sparring pattern. For the data import part (which I called FileLoaders), I took the logic from ModernUO. For the items part, I created a script (scripts/dfn_*.sh) to import items from POL! Thanks for the compliments! The way I am, if I fixate on something, it becomes an obsession!
- doctorpangloss 7mo agowhile i understand the motivation to have codex like, do this problem for you, that's fine. what is the ethos of corresponding with people on Hacker News through the chatbot too? like i get that this particular comment i am replying to, you authored, but ChatGPT authored your post, and your documentation, and some of your other comments. the big picture question is, if you can mess around with the bot to do anything, why spend it on this game? why not make your own original game instead?
- bhekanik 7mo ago[flagged]
- squidleon 7mo agohank you! That separation was a very deliberate choice I've seen firsthand how quickly things degrade when packet handling leaks into game logic. You're touching on a real pain point. Right now the Lua boundary does show measurable overhead under load, especially with per-tick callbacks across many entities (doors, spawners, etc.). MoonSharp's interop cost adds up when you're calling into Lua thousands of times per tick. I'm actively looking at batching script invocations per tick and capping the budget so a heavy script wave can't blow up tail latency. The goal is to keep the game loop deterministic if Lua eats too much of the tick budget, defer the rest to the next tick rather than letting the whole loop stall. It's one of those problems where the architecture gives you a clean place to solve it (the boundary is explicit, so you can meter it), but the solution still needs work. Appreciate you calling it out — good toknow others think about the same tradeoffs.
- jasonjayr 7mo agoLuanti(previously Minetest) does a similar trick: c++ core/game engine, but all the game logic is in lua.
- gverrilla 7mo agohad great fun for years on Neverlands shard. best mmorpg ever, by a largeeeee margin.
- swaminarayan 7mo agoVery cool project. MMO server codebases tend to accumulate a lot of architectural complexity over time, so starting fresh with a cleaner separation between networking and game logic makes a lot of sense. Curious about the sector-based delta sync — how do you avoid packet bursts when a player enters a busy area with lots of items and mobiles? Also interesting to see NativeAOT used here. Was that mainly for deployment simplicity or performance?
- serf 7mo ago>Curious about the sector-based delta sync — how do you avoid packet bursts when a player enters a busy area with lots of items and mobiles? doesn't look like there is much going on to protect packet bursts there aside from smart-ish proximity sector loading. the work is done at boundry. dove into it because i have been recently working on frustrum spawning to reduce net burst in a similar project, was kind of curious if something similar was used as a method to pre-warm the upcoming sector but I didn't catch anything. fun and easy to read. thanks op and parent for getting me to look through it.
- squidleon 7mo agoThanks! 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.).
- stackghost 7mo agoImpressive work! Does it support the smooth boat movement packets from the newer clients?
- jajuuka 7mo agoThis is super cool. Never played UO myself, but had friends who did. I'll be keeping an eye on this as someone interested in the private MMO server community. Hope others can contribute and build this up even more.
- kpw228 7mo agopanda king
- kpw228 7mo ago[flagged]
- carverauto 7mo agothe original moongate (moongate.net 4000) was a MUD written by Vassago and still exists today as Materia Magica
- nottorp 7mo agoThe sad thing is i see this and think: "Who owns the UO IP now and how litigious are they?"
- eclipticplane 7mo agoUltima Online emulators have existed almost since the launch of Ultima Online, and are arguably a reason the core game is still running today. Ultima Online launched in September 1997. The first "offline emulator" launched in October. Emulators became playable by mid 1998. https://www.uox3.org/history/timeline.txt https://www.uox3.org/history/timeline.txt
- MisterTea 7mo agoThis must be an omen given how I just this week watched a bunch of the Majuular videos on youtube (Highly recommend them) about the Ultima series of games, particularly Ultima Underworld The Stygian Abyss, and Ultima VII and VIII. That lead to me buying Underworld and VII last night on GOG as feel like I missed out on something wonderful in the 90's (Also need to grab System Shock and Crusader no remorse.) My brother and I bought IX when it was released but it was a buggy nightmare so we gave up and never experienced Ultima proper. However, my brother and his friend got into UO and played a ton. His friend was a greifer at the time going by the name SirDarkSpell and supposedly made a bit of a name for himself. This was around 2000 or so? I bet the two of them would love to hear about this project as both of them have fond memories of UO. Anyway. Might just throw my weekend into the Stygian Abyss...
- mkehrt 7mo agoUltima Underworld is a fantastic game.
- thetoon 7mo agoGreat news. Haven't played UO in forever. What kind of client are people using on modern systems, these days? Is there a client working well on linux?
- ongedierte 7mo agoUO outlands (most popular shard) has pretty alright support and guides for linux
- yangosoft 7mo agoImpressive! I spent many many hours in UO when I was young. It was so great playing in some shards with hundreds of real persons.
- elevaet 7mo agoCool, nice work! I've been building a MORPG version of a kind of Ultima 3.5 on the side in spurts for the last 5 years using Go, postgres, and React on the frontend. Top view tile graphics, old school keyboard control/commands. It's pretty janky still, but I hope to do a Show HN at some point. I think I need to take some inspiration from you and partition the world into sectors, I have a n^2 scaling problem right now as there are more PC and NPC in the world.
- jdwithit 7mo agoVery cool work! This is giving me a big nostalgia hit, as a LONG time ago (when UO was a current game ;) I maintained a C++ UO emulator called UOX3. To be clear I absolutely did not initially develop it or even write any particularly large or difficult features. I just took over maintaining the codebase, taking patches and cutting releases, managing the community, that sort of thing. The original author decided to step away and I had apparently been enough of a busybody in the tool's community that he tapped me to lead it for a while. I also helped some Canadian guy with money, hardware, and bandwidth to burn run a private server based on UOX. Both were delightful experiences and I learned a ton. In hindsight I am very glad Origin was not overly litigious and didn't send the FBI to my house for "hacking" their game.
- squidleon 7mo agoThat’s awesome to hear! Actually UOX3 is one of the inspirations behind Moongate. The way it approached the server architecture and scripting was really interesting and it influenced some of the ideas I’m exploring in the project. Projects like UOX3 are a big part of the history of the Ultima Online emulator scene, so it’s great to hear from someone who helped maintain it.
- pixelmonkey 7mo agoHey, I am just reaching out to say: "thank you." When I was in high school, I played a lot of UO. It was actually the last computer/video game I ever played regularly, because I convinced myself as a teenager that I was addicted to it and needed to drop it "cold turkey" to focus on academics and extracurriculars. (A sign of the times for the late-1990s nostalgics: I sold my UO account on eBay for a few thousand dollars and an MTG Mox Pearl. I owned a bunch of virtual real estate, e.g. a UO tower on an island only accessible via moongate. The high bidder "threw in" a Mox Pearl as a kind of informal escrow, to make sure I completed the account transfer after getting paid.) Before I dropped UO from my life, I discovered UOX. I was learning C++ and UOX was a great way for me to practice my emerging C++ skills. My clearest memory of feeling the power of programming was when I created a mod for my UOX server that allowed me to drop an unlimited number of interconnected and color-coded moongates all over my server, creating something akin to the feeling of the game "Portal," but long before Valve released "Portal." It was after having a blast with UOX that I decided to dig into programming much more. Somehow, the UOX server mod made programming feel "real" for me in the way my prior forays into coding simply didn't. That led to me learning Python -- as a way of toying around with the Slackware Linux server I had in my basement. I left C++ behind, but it was an important stepping stone for me. Now, decades later, learning Python was probably the single most important decision of my life in childhood. (See e.g. https://amontalenti.com/about https://amontalenti.com/about) UOX is such a cool project. UO was a really ahead-of-its time internet game, as well. Great memories. Thank you.
- tamat 7mo agoIs the UO protocol documented? Are there UO clients besides the official one?
- DigiEggz 7mo ago[dead]
- godrae369 7mo agoHey man, read your breakdown on the Moongate architecture. Using Source Generators for DI and Lua for behavior decoupling so you never have to recompile C# is a beautiful setup. Strict domain separation is the way to go. I saw your 'What's missing' list includes NPC AI. I build AI agent workflows. Instead of building traditional, boring finite-state machines for NPCs, what if we plugged an LLM microservice into your Lua scripts? We could give key NPCs actual contextual memory and dynamic dialogue. Players could physically type to a merchant, negotiate prices, or ask for rumors, and the NPC would generate a response strictly within the lore of Ultima, triggering the correct Lua events (like handing over an item or opening a door). Since you have the packet layer and Lua environment solid, the integration would be incredibly clean. I'd love to contribute and map out the AI logic for this if you're open to exploring it.
- squidleon 7mo agoI am interested please write me on GitHub!
- mungoman2 7mo agoThis is a very fun idea. Would also be very interesting to see if one could have a system where talking to an NPC could alter the world. One maybe obvious way would be that asking for rumors will actually creates the scenario that the NPC describes.
- 7bit 7mo agoCool Project. How did you know how to talk to clients?
- zorm 7mo agoVery cool to see! I was active in the UO emulator communities back in the day but mostly with SphereServer. It is interesting to see here in the comments how many people were inspired to programming because of UO! All the recent LLM advances would make for very interesting and very fun NPC interactions in a MMORPG today too. Even small player community servers could be viable long term because of the ability to seed complex interactions with NPCs into on-going story lines.
- eclipticplane 7mo ago> SphereServer Throwback! Pretty sure I still have the source to SphereServer sitting somewhere on my NAS. It was my first exposure -- in early high school -- to coding in a group and operating a Linux server.
- GardenLetter27 7mo agoI love the Ultima renaissance now with Ultima VII: Revisited and the Ultima Online servers.
- whyenot 7mo agoWow, this brings back memories. I bough a little house and had a bakery outside Trinsic. You could hire a vendor NPC who would sell your wares while you were away. One of my friends had a tower or something, all decorated on the inside with furniture. It has taken 20+ years for World of Warcraft to have housing, and while the current setup is very good, it's instanced and not alive and part of the world the way UO's housing was.
- Benjamin_Dobell 7mo agoSomewhat coincidentally, MoonSharp (the scripting engine Moongate based their Lua runtime on) is alive and kicking again. There hasn't been a release in ~10 years, but I published a beta for v3.0.0 a few days ago. https://github.com/moonsharp-devs/moonsharp/releases https://github.com/moonsharp-devs/moonsharp/releases I'm not the creator of MoonSharp, just a maintainer on Github (who has honestly done very little). However, I consult for Berserk Games, and we have use MoonSharp as the scripting runtime for Tabletop Simulator.
- ParadisoShlee 7mo agoI will absolutely host one of these servers.. I used to be the admin of Sphereservers 15+ years ago and I've lost all of my scripts, and world files... and graphics. But I would love to play some old school UO again with people
- pwdonald 7mo agoFirst mention of Sphere server I have seen in the wild in quite some time. I too had a lot of custom scripts for my instance that I have lost. Sphere server is what finally got me to learn how to script.
- heliumtera 7mo agoWhy did you choose C# for this project? Does it have something to do with the fact that we already have plenty well established Ultima online server emulators in the training set of your llm of choice despite you claiming it is from scratch?
- knicholes 7mo agoCan you make it so multiple computers can connect from the same IP address? I really want to play with my kids!