It's dead here - let's do a post mortem!

Coordinator
May 14, 2008 at 7:54 PM
Hi all,

Contributions to the codebase have dropped to near zero, me included. Seems to be lack of interest in general. I think we can call it dead and move on.

For those who still follow the project, I'd like to hear from you. Any feedback on what we could have done differently to keep it alive here? 

I'd like to understand better the successes/mistakes we made if just for educational value, since Tigermud itself was meant as an educational exercise anyways. However, if you don't think it's dead and have ideas, let's hear them, too!

cheers
Adam
Developer
May 14, 2008 at 9:39 PM
As an educational tool, it definitely did its job.

As a project...  Some things that would extend its life, even now I think:

Some goals.  'Be a mud server' is already there...  Once we got to that point, it stagnated.
Use it.  Make a MUD with it that is designed to be played, not just a test MUD. 
Better code hosting.  I never liked the way it was handled on CP.  I was much happier on Sourceforge, despite its issues.
Linux (and OSX) compatibility.  I never fire up my Windows machine, so I never code.  (I know this existed at one point, but it fell by the wayside...  And compatibility with a Linux-based compiler was never very good, either.)

I'm more likely to try to code a Ruby-based MUD server now.  The cross-platform compatibility and the learning of a language I don't know well yet are a draw for that.  I really don't even have time right now for that, though.
May 25, 2008 at 4:31 AM
I agree. How hard would it be to make it into a MUD that was designed to be played? From what I noticed as far as core programming is concerned. A good deal of work was already done. Depending on the type of game it would be really is the factor that determines the next step in design.
Coordinator
May 25, 2008 at 10:37 PM


kaosoe wrote:
I agree. How hard would it be to make it into a MUD that was designed to be played? From what I noticed as far as core programming is concerned. A good deal of work was already done. Depending on the type of game it would be really is the factor that determines the next step in design.



I think we assumed that if we build a good codebase with a flexible architecture, people would just come in and start building MUDs with it. They would provide great input from the running of their MUDs and we would have fodder for more coding. As a result, we wouldn't have to run our own MUD and we would just be in 'the codebase business' per say.

Since things didn't happen that way, it leads me to these questions: (your thoughts here?):

Were our assumptions about the coding skills of potential MUD owners too high? I know most potential mud admins who sent me email didn't have any clue about coding, nor any interest to learn. Was that just a problem with admin quality or a legitimate problem that a codebase must solve? It did seem that the skill required to extend tigermud were nearly the same level of skills needed to build it from scratch almost.
Was the Windows platform too limiting for success? How many Windows-platform MUDs are actually in use?
Was a functional MUD with a live user base absolutely necessary for the uptake of the codebase?
Is a complex and flexible architecture too complicated for people to handle?

We had reasons for all of the choices we made that were mentioned above, but most of them were for educational reasons and what makes fun coding, not necessarily trying to create the codebase that would take over the world. However, with zero adoption I was just wanting to explore those questions a bit to understand what slight changes we could have made to get higher adoption. Thoughts?

Cheers!
Adam

Developer
May 26, 2008 at 2:05 AM
Short answer:  Yes.

Long answer:  Code that doesn't get used doesn't have a purpose.  Without a purpose, there's nothing to shape the code.  I had originally planned to use it to write a MUD (hence my original questions) but never quite got around to it.  As far as I know, nobody else got around to it, either.

What exists right now isn't fleshed out enough to make a MUD from.  Combat is sparse, there's no real tools for creation, and there's no examples of how to create.  Whenever I added something, I tried to make an example of its use as well (the cart and windchime, for example) but I only made enough for other programmers to really understand.   I always assumed there would be more later.

Usage of code always drives new features, too.  I had some in mind, but I couldn't really make the real until I'd tried to make them happen. 
Coordinator
May 26, 2008 at 8:04 AM
Good points. For me I started losing interest after having spent so long in graphical MMOGs like Asheron's Call, Wow, Everquest, etc. that going back to text was not anywhere near as fun as the first time back in 93-94. Maybe it's not possible to recapture that first impression when you've had so many more experiences afterwards.

Most of the time I was thinking to restart a project based on a 3d engine, but what kept me from moving forward is how much of a black hole the 3d development can be. Past the learning curve itself, you can code for years on the look and feel and not even begin writing a world engine. There is just so much complexity there in appearance alone.

adam
Developer
May 26, 2008 at 11:18 AM
Interesting, my motivation was the opposite.  I'd been to the fancy graphical MUDs (aka MMOs) and gotten bored, and played the best (imho) MUDs and was ready to make a better one combining the best ideas of both worlds.

The graphics don't actually make it any more fun for me, but the gameplay does.  MUD writers are stuck in a certain mindset and can't break free, where MMO developers are forced to start from scratch because there are no free engines out there.

To be honest, the ideal game would be 3D, because it's more accessible and easy to 'just play', instead of having to spend time reading constantly.  But the amount of artwork and development is prohibitive.
May 27, 2008 at 11:20 AM
Hello everyone,

Was browsing your forum here and decided to chime in.

I'm the head coder on a mud called Aeonian Dreams. It's originally Circle based, but we're considering starting off fresh on a new codebase. I do development work on Windows software with C#, and would love a MUD written in C#. Garbage collector, string class, references instead of pointers... would feel much more at ease giving someone inexperienced a job coding in C# than in regular C. I'm not afraid to say that Circle is horrible, and I hate it. C is a good language, but it's not meant for MUDs.

My point is, I'm glad to see that there's an interesting C# base out there. I will be giving the code a look-through and booting it up here soon. Would have to get it to work on Linux though, as our server machine is Linux. One of the pages mentioned that it'd work on Mono. Is this true?

Lack of advanced features isn't a problem, as we'll most likely be modelling a lot of it after our current MUD. So long as the foundations are solid.
May 27, 2008 at 11:50 AM
Edited May 27, 2008 at 1:13 PM
Um, okay, that was weird. Apparently refreshing repopsts.
May 27, 2008 at 1:12 PM
Edited May 27, 2008 at 1:14 PM
Did it twice before I noticed... heh.
Developer
May 27, 2008 at 1:18 PM
Long ago, I used to run it on Linux.  There have been some pretty major code changes since then, though, so I can't promise it'll be even close to working now.

Question though:  You would prefer C# to Ruby, even on Linux?  The benefits you listed over C apply to both languages.  Ruby has the whole 'works perfectly on Linux' thing and C# has the 'works like a normal programming language' thing.  (Learning Ruby is guaranteed to make you a better programmer, even if you never use it again afterwards because it forces you to stretch your thinking.)
May 27, 2008 at 2:24 PM
I suppose my only reason to think about C# is the fact that I know it very well, and of all the languages I've used, I like it the most. Not to mention the fact that learning a new language and all it's quirks and tweaks is a task in itself.

I'll have to look at Ruby though. Never tried Ruby before, but I've heard of it. It's only a relevant question if there's a good codebase written with it though, because as much as I'd like to create a new base, I just don't have the time. Not to mention reinventing the wheel once again is a bit silly when there are so many code bases out there already.

Know of any good Ruby codebases?
Coordinator
May 27, 2008 at 3:45 PM
So here's the million dollar question from me: You're running on Circle, but what ultimately makes you want to move to a new codebase? (whether C# or otherwise)? I want to understand the scenario really well.

Thanks!
Adam
May 27, 2008 at 4:13 PM
Edited May 27, 2008 at 4:45 PM
There are several reasons. Most importantly, I hate Circle and the current code is a bit of a mess. C combined with inexperienced coders has resulted in a bit of a monstrosity. Circle in itself is already a pain in the backside in my opinion. C is unnecessarily low-level for a MUD, and with Circle's way of trying to fix that using weird defined and macros, it's just a big headache.

The other big reason is that we've been planning big structural changes to the mud mechanics. Combine that with what I just mentioned, it's a nice opportunity to switch to a better base. And ultimately it'll be easier to code new stuff on the longer run with a more advanced language, and a better planned foundation.

Most our non-stock area work has been made with an offline builder I wrote, and the builder's area files are portable between MUDs (through an export module), so most our areas can be transferred quite easily to any code base (for those curious: VisualMUD.NET).
May 28, 2008 at 4:12 PM
I'm happy to report that it runs perfectly on Mono.
Coordinator
May 29, 2008 at 10:02 PM


orblog wrote:
I'm happy to report that it runs perfectly on Mono.



That's good news. Definitely thanks to William and his work getting it to run on Mono in the first place. I guess we didn't touch anything that affected that portion and it helps that Mono has matured so much since we first touched it as well.

cheers
adam
Jun 4, 2008 at 1:35 AM
Hello there everyone.

I was happy when I came across this project.  I'm a seasoned LPMUD creator and, in real life, an independent software developer (C#).  My current MUD, Rise of Praxis, has fallen prey to the common blight of new projects:  Development Stagnation.  I actually inherited Rise of Praxis (which is spawned from the original Nightmare LPMud) from it's original administrators and they seemed to disappear.

With the stall in the current progress of the LPC code, I've had some time to re-evaluate how the entire MUD and implementation is done.  I do have a some suggestions/thoughts for your team of developers:
1)  Build the MUD to support a web front-end using AJAX.  The prototype I was working with had this and it works very nicely.  It gives the MUD a larger appeal instead of straight text-based MUDs and also gives other people options for different front-ends.  The PoC (proof-of-concept) front end that I put together was completely HTML/JS based.  I'm now working on a real implementation of that idea.

2)  Build the MUD driver so that it simply is a host environment for the actual MUD library.  This means that the MUD driver compiles all the MUD code when it starts up and, via System.Reflection.Assembly, System.Type, and System.Reflection.MethodInfo objects, you can call these defined functions in your objects.  The MUD library should be responsible for handling all game logic down to player, object, room, NPC, etc implementation.  The driver is simply a mechanism for a real person's input to get to the virtual MUD environment and for it to send information back to that person.

3)  I've tried and failed to come up with a good C# scripting mechanism.  How have you tried to approach this?  The whole AppDomain and Assembly is often too limiting since you can't unload an Assembly if you want to recompile a particular type of class during runtime, like in LPC.  I'm still looking into it, but thinks are not looking too promising right now.

Also, I wouldn't worry about this being a .NET app.  Mono runs well for many .NET apps.


Developer
Jun 4, 2008 at 2:12 AM
It's been a while, but the approach to deal with unloading and re-loading the scripts (dynamically compiled C# code) was to put them in a seperate appdomain.   The disadvantage to this was that it was much slower to access data across the appdomain.  If I had it to do over, I'd put almost everything in that second appdomain and reload it all, instead of trying to avoid reloading all the code that isn't specific to that MUD 'library' as you're calling it.  I'm not sure where all this ended up, as just after I stopped actively coding, someone was complaining about it and I don't know if they rewrote it or not. 
Jun 4, 2008 at 2:20 PM
My experience/background comes from the MudOS driver and LPMud style of doing things.  Basically an LPMud has 2 parts:  The driver and the MUD library.  The driver is a native machine code running a sort of virtual machine that the MUD library is hosted in that provides core system functionality such as a virtual filesystem, memory management, and socket management, and (of course) the LPC interpreter to compile on the file all LPC code.  The MUD library contains all game logic. and I mean ALL game logic, including user authentication, command implementation, and verb (i.e. action commands such as say, get, go) definition.  The driver does communicate with the library through pre-defined functions, but it's a small amount of interaction and so the performance (if done in C# and a separate AppDomain) should not be that bad.

I've looked into the separate AppDomain implementation.  I did have some problems with that.  First, and most importantly, every time you recompile a class/script, you'd have to reload a new AppDomain.  In my experience, there are 1000s of classes that would need to be reloaded and that will drag performance down very quickly.  Also, serializing/de-serializing objects so that they can persist in the new AppDomain would probably be so slow that it would make recompiling on the fly almost useless.  While I would love to see this style of MUD scripting implemented in a C# platform, it's just not currently possible.  I am going to look into the possibility of running the IL generated code differently than what most of us have seen examples of.  You can inherit from CSharpCodeProvider so I'm wondering if there is a way to capture the IL and then simply pump the generated IL through a class somewhere in the System.Reflection.Emit namespace (like DynamicMethod introduced in the 2.0 Framework).  That might be the trick.  Don't know yet.  Haven't gotten that far.

If it is possible, then what I would recommend is that you read up on your LPC/MudOS documentation and take a few ideas from there.  Ideas such as having certain pre-defined functions in your script that act as entry points to the MUD library, but then allows the MUD library to execute the rest of the code in it's virtual OS.

Coordinator
Jun 4, 2008 at 4:32 PM
If you read the code, you'll see that Tigermud works similarly to LPMUD as you described, just doesn't go as far with it. We have the server (socket driver), library (game objects), and a collection of commands (verbs) that you can rewrite and recompile online without dropping users or restarting the server. The segmentation is there, and we just treat C# compiled on demand like a scripting language. However, we implement much more code in the core server itself than lpmud does.

We actually implemented separate appdomains and then saw the performance problems with it, thats why we backed out that architecture. Loading and unloading appdomains wasn't the problem, it was perf due to .NET Remoting (communication between app domains) being horribly slow and is pretty much a dead end for anything as realtime as a mud needs. Don't separate the objects from the data they need to access quickly and often, otherwise you pay dearly in perf.

Jun 5, 2008 at 2:11 AM
Sounds like your team was on the right track.  I did a little more reading into possible other options and found the use of DynamicAssembly, DynamicMethod, and System.Reflection.Emit promising.  However, in my opinion, it would require a whole lot more work.  You will need to implement a virtual machine to host the IL code in so that you can control the execution of code more efficiently.

What I'm thinking is that you still use the CSharpCodeProvider to do the actual compiling and then extract that IL and store it, along with some meta-data, in another file that your virtual machine can quickly and easily reference and load.  That might be the trick around the AppDomain loading/unloading and also provide you some connection points for your driver to intercept some function calls (i.e. file system calls can be redirected to a virtual filesystem class).  It would take some work, but the end result would basically be the LPC interpreter/processor and your MUD would have a very cool scripting engine.

Then again, you could just go the route of using an already developed scripting language that works with .NET... but what fun is that. :)
Developer
Jun 5, 2008 at 12:21 PM
I had actually suggested at one point that we use another language for scripting, but after some research we all decided that C# was already known, could be done dynamically, and was probably the best way to go.

And if I remember right, we were compiling to disc and then loading the class...  And only recompiling if the source code was newer than the compiled code.  I may be thinking of something else, but I'm pretty sure that was TigerMUD.

BTW, it's possibly to reload a class without destroying and creating a new AppDomain, but the memory isn't freed from the previous copy of the class.  This could be used to reload small things without reloading everything, and then reloading everything once the memory leak is big enough.  We actually did it that way at first until we discovered the memory leak. 
Jun 5, 2008 at 2:53 PM
While I completely support the idea of using C# to be the scripting language of your MUD, I would have to say, from what I've been reading, that it is not a very useful option for games that do go through frequent recompilations of classes/scripts (like a MUD).  The next option, if you are set on using C# as your scripting language, is to come up with a custom parser/interpreter that can read and process C# code.  If you design it properly, you can probably even support native vs. script based code (one gives you performance where the other gives you flexibility).  I guess the only way of doing that is using a separate AppDomain, and using remoting to interact with only critical objects (i.e. a Master controller object) and then loading the appropriate assembly (i.e. Tiger.Loader.Lib.ScriptLoader vs Tiger.Loader.Lib.NativeLoader) to manage the in-game objects.

Any thoughts on writing your own C# parser/interpreter?  I'm sure you can find plenty of examples on the web of these type of projects.  I do know that the CSharpCodeProvide is useless because it doesn't really provide a nice way to hook into a scanner/parser -> token stream process.  Maybe the older implementations might be better.

Coordinator
Jun 5, 2008 at 3:36 PM
I don't understand the need to write your own interpreter when you can compile C# source into the command queue and then execute any code from there. That all being handled by the core server.
Basically we do this today in tigermud except we only run Command and Action objects (which represent over half of the code), when you could extend that idea to include almost any code in the mud server. Then you have almost any server code that can be recompiled on demand and run. I don't see a need for app domains there either.
Jun 5, 2008 at 4:56 PM
Edited Jun 5, 2008 at 4:58 PM
First and foremost, I don't want anyone to get the impression that I'm trying to tell you what to do, just having a tech discussion with people who have been down this road before.  :)  I completely respect your decisions and way of implementing them.  Just throwing out some other ideas there for you that might be of use.
Now....

When you compile and execute code into the command queue, it's being ran under the context of the current domain, which means that the compiled code would have access to assemblies it should not (Security Issue). 
If you set up a different domain, then there is the whole issue of not being able to unload an assembly when you recompile unless you unload the entire AppDomain (Performance Issue). 
Then there is the possible issue when someone is taking too much time to process their command, especially if you open scripting up to in-game players like most MUDs do. (Performance Issue). 
Finally, there is the idea (which is where I'm coming from) that all game logic should be written in the 'scripts' themselves and no game logic should reside in the driver. 

You can't compile/recompile without impacting memory or performance using the CSharpCodeProvider -> execute code methodology (not to mention marshalling problems).  Maybe if you cache the CodeCompileUnit results of each file and then recompile everything using the GenerateAssemblyFromDom, it might be better, but I'm not sure.

As an experience MUD developer and an Admin, I can tell you that there is a lot of compiling/recompiling that goes on during the initial stages of a release and possibly even during stable stages unless you set up a different server to do your MUD development on.  If you do that, then there is a whole migration system that you'll need to abide by otherwise deploying the new domain/object/NPC will make the system unstable.

So what is the purpose of the interpreter? 
First, and foremost, it does provide you the mechanisms for complete control over the code being executed and the objects/functions/assemblies that it tries to execute.  You can lock-down the script version of C# so that only assemblies/classes you approve of can be referenced.  Second, you can provide time-slicing techniques that avoid a function from taking too much time.  Third, given that it's interpreted and not actual binary code, there is no need to worry about load/unloading AppDomains and assemblies.  It can run inside if virtual machine class that the driver manages and allows for quick loading/unloading of new scripts. 

Now there are downsides to this, mainly being the complexity of implementing your own interpreter/parser.  There are plenty of examples, but it might not be the best option for you.  It will never run as quickly as a IL to JIT process.  Did I mention the complexity?

I guess with the GenerateAssemblyFromDom method on the CodeDomProvider and the use of cached CodeCompileUnit objects, I could be wrong about several of the points above.  I guess I should do some proof-of-concepts and see what I get.  I'm just not sure how well this will work.  The marshalling of the persisted objects from the old AppDomain to the new AppDomain might be a performance hit, but who really knows.  I don't even know how you are doing persisted objects so I could be completely wrong on everything. :)



Oct 9, 2008 at 12:05 AM
Of course, nowadays, there's IronPython to fill in our scripting needs. It does an excellent job of handling all that stuff and it's fairly easy(er) now in its late beta stages to set it up on its own AppDomain so as to sandbox potentially harmful code. I'm a little sad that there hasn't been a single successful\still alive C# codebase to date, C# and the .NET runtime is almost made for this kind of stuff.

All it takes is one, then I'm sure we'll see more. Here's hoping.
Coordinator
Oct 9, 2008 at 2:32 AM
I agree it is an interesting phenomenon that there has been no long-term C# MUD. There are plenty of good ideas and people who have the knowledge to implement them, but the will to complete the work is just not there I guess. $0$0$0$0I stopped coding at the point where all the architecture decisions were academic and the outcomes were too predictable to be interesting anymore. Playing World of Warcraft sucked all the creative energy out of me I think.$0$0$0$0$0Cheers!$0$0Adam$0$0$0$0$0$0$0$0$0$0