In the original LPC land, the driver was the only way you could create an in-game object. Along with this came several little things like:
- The driver knew where every object was.
- you could say new_object(“/path/to/object.cs”) and that’s how the driver knew where to grab its source.
- the created objects were of two flavors – “/std/room/lobby” for example was the room that everybody would go to, but if you did a new_object on it, you’d get “/std/room/lobby#45”, which was a different object. (this is called “prototyping”, and is also used by Javascript and Ruby)
- you could USUALLY refer to an object by this string that represented the object.
- Because of this deferment (string became an object), not everything in the mud loaded at the same time – there was some JIT loading going on.
- The code was compiled at that point, so you could change the definition of the object and then create a new one of it.
In my DotNet world, I’m not limited by who can create which objects. What to do?
Solution #1 – Don’t Manage it
Don’t Jit-Load anything. If users want a singleton, they have to implement Instance. All assemblies are loaded into the same appdomain. To change code, have to restart the mud.
This is doable, like a Diku, but not where I want to go. Writing that Instance stuff over and over gets old. Granted, there’s all kinds of C# stuff you could do, but the target audience for LPC was beginner programmers and game designers, not code poets. Less code the better..
Solution #2 – Overmanage it
I could go with “all code is on disk and I run the compiler against it to generate it and then suck it in”. Not going there yet either.
Solution #3 – Put in a layer of Find_Object etc.
This is the route I went.
- I decided that rather than “/path/to/object.cs”, I’d use a URI scheme.
- I’m using “builtin://TYPENAME” as my current implementation of “yo, go find me an object”.
- I’m giving two different methods in the driver – one to find a “singleton” (if it already exists, reuse it, else create it), and another to create a new one every time.
- I’ve set up some internal properties in StdObject that (supposedly) on the driver (and other responsible code) should set.
What I’m doing is leaving open some possibilities:
- realm://sunnywiz/classname — this could be a per-wizard realm pointer. maps to an assembly, that might be loaded into an appdomain. (appdomain = .Net version of forget this code and reload it)
- persistent://DotNetMud.Mudlib.Room/WizardingHallway57 – this could be a stub that creates a standard thing of sort and then rehydrates it based on a tag stored in a database.
I’m also not saying “Everybody must use the driver to create their in-game objects.” No, I’m saying “if you want to use the driver, you can, and I’ll track things, but if you don’t, I can’t guarantee I can keep track of it.”
The code referenced by this blog post is at this diff: https://github.com/sunnywiz/dotnetmud2015/compare/blog20160106…blog20160107
Here’s some of it running: