Brian Lovin
/
Hacker News

Show HN: Moongate – Ultima Online server emulator in .NET 10 with Lua scripting

github.com

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

Daily Digest email

Get the top HN stories in your inbox every day.

haolez

UO 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

This 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.

codezero

My friends mocked me for spending months as a llama herder, until I could tame dragons and grief people by pulling them through portals.

DonHopkins

Oh yeah, you could tame animals to make them your pets.

One Halloween I logged into UO, and my character had been transformed into a deer, as some kind of a sick joke! All my inventory was gone, and all I could do was deer stuff.

Then some bastard came along and TAMED ME. That totally sucked! I had to follow him around obediently all day. I guess I'm lucky he didn't skin me and make me into leather armor.

eclipticplane

Core memories of carefully setting my fisherman on a boat with `ezmacro` before I got ready for school. I'd come home to either a boat full of fish (to later cook into fish steaks), or be dead from a player killer who found my boat and killed my macroing guy to try and steal the boat.

SenHeng

I always forgot where I parked my boats. Or that I even had one.

jghn

> UO had a real economy

Sort of. They disabled big parts of the "real economy" in beta. Turned out that players didn't like it that NPC shopkeepers kept standard working hours and didn't want to buy their 5000 skullcaps from their skill grinding.

Likewise they even more quickly got rid of the real ecology feature, both because it was computationally intensive but also because players would strip mine the ecology.

chongli

They disabled NPC participation in the real economy. This gave way to the real player economy which took place in player-run shops built inside player-owned and customized housing.

Players didn't buy those 5000 junk skullcaps either. They wanted stuff that was actually valuable, which meant those practice items were recycled or thrown in the trash.

I remember when the UO team added trash barrels and created the "Clean up Brittania" event. The game's servers were struggling to deal with large numbers of these junk objects that people littered on the ground so the devs decided to enlist the players' help cleaning it up, just like a real-life public park cleanup project! Players got rewarded special items based on the amount of junk they cleaned up.

haolez

If 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.

codezero

I say this unironically, but a lot of bugs. The bugs are what made UO fun, and the team often treated the bugs as features because the community demanded it. The most famous example (I think) is the "true black" dye. Another bug I ran into was when a certain shade of brown hair got turned "true white," I was able to petition a game master to let me keep my true white hair after the bug was fixed because I made it part of my "persona" at the time.

Also there was a whole niche industry of collecting non-droppable items which spawned in the game world but were not fixed on the map (we think they were added post map creation), so they could be "pick pocketed" off the surfaces they were on and taken back to your home every wipe. There was a huge rush after servers came back on after a wipe for folks to go find the most rare items to stock up their towers and keeps.

shiftpgdn

I still think 90% of what made UO unique is the fact there was no Google or central repository of expert knowledge. Yes, UOStratics existed, but it wasn't perfect. A lot of the fun was in the fact basically nobody knew the BEST way to play, and therefore everyone was just doing whatever they thought was fun.

vunderba

You’d need to start with the premise that combat shouldn’t necessarily be the focus of the game. Work on making other aspects (farming, hunting, taming animals, etc) to be equally compelling mechanics.

ajxs

Unfortunately the missing ingredient to recreating UO is a playerbase that can see the virtual world with innocent eyes. This HN post[1] always comes to mind.

By complete coincidence, yesterday I was just looking at the website for a guild I was in 25 years ago on Oceania [2], which is somehow still online! I had a great time playing UO back then, but I don't think the experience can be recreated today. The people have changed.

1: https://news.ycombinator.com/item?id=33189823 2: http://tdr.iwarp.com/main_nfl.html

nzeid

UO didn't have a global concept of a level. You had a maximum number of points per character, which you allocated to skills by doing the corresponding activity. This is how you can skill cap your character without killing monsters or players.

deadbabe

It’s largely impossible now, it’s not a technical problem, it’s cultural.

UO forced many different types of players to coexist in the same world that simply do not mix anymore. You had peaceful dungeon crawlers and craftsmen coexisting alongside killers, rapists, thieves (wild that stealing items from other players inventory was actually a thing, probably unheard of in today’s MMOs).

The friction between these different types of players is where the magic happened, it’s what created real conflict and higher stakes in the world. When you stepped out of your house, there was always a risk that killers could be lurking ready to murder you and loot your house dry. And if you forget to lock the door, someone passing by will clean your house out for anything valuable.

In a way, old school UO was a true Middle Ages type MMO, everything since then has only grown more civilized, more enshittified. People don’t want to pay for a world that doesn’t give a shit if they have a bad experience. The truth is though there was no “bad experience”, it was all just an experience.

NDizzle

Well, 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.

havblue

Is scarcity part of it? Making sure there are some jobs people have to do that don't involve combat but still drive the in-game economy?

andrepd

UO and Star Wars Galaxies were both MMOs with that experience you describe, and I really can't think of any others. For my money the only ones to truly live to the promise of a virtual persistent alternate world.

WoW in 2004 truly scorched the field; after that MMO became synonymous with WoW clone. The same action bar, the same pov, the same control, the same short "kill 10 kobolds" quests with an exclamation mark, the same progression...

I was big into MMOs a long time ago. But I never imagined that 22 years after WoW the field still wouldn't have produced another gem in the level of UO or SWG.

idiotsecant

UO only had this experience because there was nothing else like it, exactly. PVE and PVP players and casual and sweaty tryhard and everyone was in one world, and the game actually forced interaction between those players, often to the detriment of one party. People say they want experiences like that, but they don't. They want a walled garden that isn't too hard and will give them new shoulder pads for spending 2.5 hours grinding after work.

UO was the last MMO that made the mistake of trying to be a world for everyone to live in.

mbonnet

This is why I enjoyed EVE Online. You had to earn it, and if you lost it, that was that.

reactordev

Being a legendary blacksmith was the whole point. Where crafting was the end game state for crafters. The gear produced was max durability, max dmg, max armor rating. The furniture for your castle had to come from someone, somewhere.

The whole point of the game was to live in this fantasy world, not beat it. There were no quests. No antagonist. Just good and evil and everyone in between. For once I wish a studio would take this to heart and build something like that again. Minecraft exploded due to this sandbox nature. However, you still got to give players a shovel and a bucket.

tarellel

UO Outlands has been pretty popular for a few years. They’ve implemented a lot of custom aspects (specialties), craft, new dungeons, land, as well as weekly quests and events. My brother and I play it a few hours a week. It’s incredibly popular for the nostalgia and its player base seems to be pretty consistent. It reminds me of early UO where your exploring, learning, and dying a lot. And there tends to be players everywhere you go.

reactordev

A decade or more ago I ran a custom shard with a custom map and world. There was no “map”. No guide. No quests. Tons of dungeons and bad guy areas. Shops. Towns. Etc. I also contributed to RunUO. I’m a fan of UO:Renaissance. I still have the CD and the old statics files.

_doctor_love

UO was the best online game for me. All others stand in its shadow. It was the most "free" in terms of what you could do and the appeal was the non-gamification.

I loved Everquest and World of Warcraft but those didn't feel "raw" enough for me.

The Realm is my dark horse submission for best MMO. (Yea, yea, yeah Meridian 59 and Underlight too)

knicholes

Right!? Skill loss for dying while red ruined everything for me. Ganking and being ganked is what gave that adrenaline rush.

throwway120385

I still remember those dumb combat clouds.

knicholes

I'll forever chase the dragon that is the joy of playing UO. I want to quit my job and play it 24/7.

reactordev

Which ones? The wyrms or the big baddies? Dragons one-shot. I remember you needed protection, resistance to fire, and a healer/mage who could heal you consistently between volleys to stand a chance at taming, let alone killing one.

I think this changed during the Mondrian era but in my favorite era, SA/Renaissance, those were the baddies that made you run.

Lich King as well.

knicholes

Oh, lol, not a literal dragon. "Chasing the dragon" refers to inhaling vaporized drugs (like heroin or fentanyl) from heated aluminum foil, creating a moving, "dragon-like" trail of smoke. It is also an idiom for the elusive, futile pursuit of a high that matches the initial, intense experience, which becomes impossible due to tolerance.

wellthisisgreat

yes, this really nails it. UO didn't chase "endgame content" which, imo, is the bane of today's multiplayer games. Designers expect everyone to max out and reach the end of the road so everyone is the same in the end.

jghn

This is a big cultural issue. UO was not designed to have a goal. Most players demand they be presented with a goal.

In an odd sort of way I suspect UO would have been better off had it come out a year or two earlier. It'd not have been remotely as popular, but wouldn't have attracted such a large crowd. And because they drew from a much larger crowd than the intended audience there were a lot of people who got disgruntled. But it makes sense because the game was literally not designed with their desires in mind.

doctorwho42

> to reach the end of the road...

This is honestly the best way I have ever heard this described! It really is that 'end of the road' feeling that I get, once I have experienced a large chunk of the game loop, that has me disconnect from games and feel hollow.

This is probably why I keep going back to huge modpacks for Minecraft with a friend. It is so open and expansive, with so much to do, that you never really feel like it's the end... You just feel like you have had your fill, until next time.

I personally only got to watch my older brother play UO, and then he brought me into the launch of WoW which was a pivotal experience. But the end game always felt like it falls flat.

general_reveal

Sounds like Vanilla WoW before Blizzard killed 40 man hardcore raiding. Only a few guilds on the whole server had the top gear.

theultdev

Yup. Tibia you had this too. People begging in the depot for gold and "itens plx"

squidleon

I've never heard of Tibia, I'll check it out!

theultdev

I haven't played in 10 years or so, but it's still going.

That game was my life. It's how I learned how to code among many other skills.

SenHeng

Was it actually that hard?

I played on the JP/KR asian servers in a PK/APK/PVP guild so maybe it was just my bubble but it was pretty common to see players with 7 skills maxed out. If I remember correctly

- sparring

- swordsman or fencing

- magic

- magic resistance

I don't remember the rest. It's not quick or easy like modern games, but we would regularly power level each other's alts and it took maybe 2 weeks to max out all 7 skills? We had a bear trapped in the guild house so we could power level wrestling and other combat skills.

tyjen

Once you figured out a training system, it was easy to pump out 7x GMs. UOAssist was incredibly helpful to reduce the tedium and automate it.

nebezb

Wow! 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/cont... [1] https://sourceforge.net/p/infserver/code/1/

squidleon

So: I took most of the infrastructure from the my first attempt at moongate (https://github.com/moongate-community/moongate, which failed miserably along with 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). 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

while 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?

squidleon

the Hacker News post itself was written by me.

I do use ChatGPT sometimes as a tool while working on the project (similar to using documentation, Stack Overflow, or an IDE assistant), but the post and the project direction are my own. So what?

squidleon

I forgot to mention, the entire web part in React was done by Codex. I hate developing frontends!

freedomben

Did you have to massage/guide the UI quite a bit? I've had terrible luck with codex, claude, and gemini at doing frontend. It's always so close but so far at the same time

squidleon

I build first Web API then create a plan with codex. But I choose Web Api endopoins!

gopher_space

I just have them stub out something I can open in a more specialized tool. Sometimes I can use the results as an example.

jdwithit

Very 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.

pixelmonkey

Hey, 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)

UOX is such a cool project. UO was a really ahead-of-its time internet game, as well. Great memories. Thank you.

squidleon

That’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.

swaminarayan

Very 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?

squidleon

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.).

serf

>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.

godrae369

Hey 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.

mungoman2

This 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.

squidleon

I am interested please write me on GitHub!

onlyrealcuzzo

I love your logo.

Do you have a YouTube that shows off the progress of what's complete?

squidleon

Thanks! 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

whyenot

Wow, 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.

MisterTea

This 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

Ultima Underworld is a fantastic game.

GardenLetter27

I love the Ultima renaissance now with Ultima VII: Revisited and the Ultima Online servers.

Benjamin_Dobell

Somewhat 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

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.

jajuuka

This 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.

p0w3n3d

I remember PvPGN. I believe it's still out there https://github.com/D2GSE/pvpgn-server

Daily Digest email

Get the top HN stories in your inbox every day.

Show HN: Moongate – Ultima Online server emulator in .NET 10 with Lua scripting - Hacker News