First, a small aside. Why are VB6 and lower going to use the same forums as VB.Net and higher? VB.Net and C# are much closer to each other than VB and VB.Net are.
So I'm working on a game scripting solution in VB9 at the moment and recently ran into a problem.
I figured out the solution but it was so amazingly frustrating that I feel I just have to rant for a while.
I was using the .Net CodeDOM to compile some source code at runtime. This is the heart and soul of my scripting system. Apparently, once you compile code this way, the new assembly that is created is automatically integrated with the running application and cannot be unloaded. This isn't any good for me, since I'm building a MUD and I want to be able to reload the scripts at runtime without shutting down the server. So, I learned how to use another tool called AppDomains. AppDomains, for all intents, create a new running process that uses the same thread as the process that creates them. If the source code is compiled in a new AppDomain then the whole domain can be destroyed safely and completely when the script needs reloaded.
Well, after some testing, this worked fine. A small problem though. I can't pass arguments to the functions described in the scripts without playing with .Net Remoting (basicly, the two AppDomains act as clients in a client/server system, more or less). This wasn't too terribly painful, but it took a fair bit of reading.
So now I can call the functions in my scripts. Then another problem. I have no way for my scripts to call functions of objects in the engine without passing every object they could possibly need to every script. That's a lot of arguments to include on EVERY function and subroutine. I couldn't do that. So I (naively) decided I would try creating a static set of functions that I could call. (In VB the keyword is Shared, not Static. Static is a C language term and should be more familiar with most people though.) Now I can call the static functions. It works.
Next problem. Apparently the code for my static functions is being executed in the new AppDomain. The domain keeps it's own complete set of static variables instead of using a reference to the copy from the main domain. Thus, I can set up a small collection of rooms, for instance, and have my scripts call the GetAllRooms function that is declared static. It works fine. Except it kept returning Null. When called from my main code it would return the rooms as it was supposed to. I worked this over in my head for FIVE hours before figuring out what was going on. Well actually, I ended up giving up and went to bed feeling disgusted and beaten. When I woke up I just suddenly figured it out.
Solution: Each of my scripted classes are going to inherit from a ScriptBase class. This class will have a subroutine called by the engine that will give each script refences to all of the objects it needs for the various generic functions. Finding an object/player/room by ID or whatever will be trivial, and I can keep all that background crud hidden from future developers who are working with the scripts. They call a function and it will auto-magically work, with just one line of code extra on their part, "Inherits ScriptBase". I think they can handle that.
Long story short. I set out to learn ONE specific technology, dynamically compiling source code at runtime with CodeDOM, and ended up having to learn Remoting, AppDomain control, efficient use of Static functions/variables, and more, through a vary annoying chain reaction of undocumented hell, because of Microsoft intending certain technologies to be used together and not allowing more intuitive alternatives. Grrr.
At least it works.
Until I break it again trying to do something else to make it work the way I want.
Which will require a dozen more hours to understand and implement.
Maybe I should have just learned Lua…