Not Scripting #143
DavidRieman
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Especially after proving that "non-reboot updates" are a feasible feature to maintain for WheelMUD, we've taken a stance against having non-compiled ("scripting") code engines as part of WheelMUD. (Scripting is documented at #134 as "things we've tried".)
So here are some archived discussions from prior forums that touched on scripting topics, which I hope will help to answer any newcomers wondering "why not?"
This thread contains restored content from prior forums; see #134 for details.
[May 2009]
Ok, I went nuts with a response here. I am clearly passionate about this, but a large part is that it draws on some terrible experiences/frustrations I had with MUD development in the past. In particular if the "ridiculous tree of one-offs" point alone does not make one shiver in horror, I may need to explain that better. For the purpose of this rant, my definition of "script" is "computer instructions that are not pre-compiled" or "runtime-compiled code that is not stored in an easily accessible Visual Studio project."
IMO adding a new sense should absolutely require a compile. Any scripter/admin who is online should not have the freedom to accidentally (or purposely) screw something up and fubar important things, or worse, crash the MUD since they changed some critical "script" that's used by all kinds of things on the fly.
IMO administering a modern MUD should follow good real-world practices; one should have a "live/production" server, and a separate "development/test" server where they do any testing of pending gameplay changes. Changing basic content is probably ok to do live, but anything complicated should be tested in an isolated environment and brought over after being proven through testing. In our case, we are fortunate enough that our own dev machines can often serve as sufficient development servers on an as-needed basis.
All of the MUDs I've been that I would classify as "unstable" were all MUDs that allowed builders too much flexibility in their scripting; all it takes is one typo to enter an infinite loop and you've fubar'd the whole MUD. A worse example is where a builder messes up one pointer and boom, the whole MUD crashes. Sadly, I wouldn't even say the quality of gameplay or interaction was any better than a MUD that had that similar functionality compiled in. (Removing safety nets did not speed up development.)
My first attempt to do building for a MUD was on a MUD that required everything to be done through a scripting format. Coding a room as a "script" is so cumbersome that the barrier to entry is not only too high, but even knowing how to do it, the process itself is so slow it's ridiculous to think people had to put whole areas together that way. Needless to say, there weren't many finished areas and I abandoned the idea of building for them, even though I was a little bit of a hobby coder by then.
I later tried to develop for two different MUDs which did not provide any modern means of source control nor local building of the solution; code entry would be done through terminal. You had to edit scripts online. You couldn't even effectively copy-paste code you write in notepad since there are limitations to how much output you can cram through telnet in one go. Almost always, to create a new script, the coder/scripter would copy an existing one pretty much at random, since discovery of existing scripts was extremely difficult; this encourages "a ridiculous tree of one-offs" of copy-pasted "scripts"... new wheels are constantly sourced from bad, ancient wheels, rather than automatically inheriting the "best, appropriate, flexible, always updated" wheel available. Even if you were so inclined, if you improved on a wheel's functionality, you would have a very difficult time finding all wheel-like things and updating them.
Both times (at different MUDs), the code was eventually lost due to poor administration/tools, and the admins asked the builders/coders to redo all their work. Essentially all the builders/coders would leave in frustration instead of rebuilding everything from scratch. Sadly, this whole primitive process described, at the time, was by far the most common scenario. I talked to several other builders/coders and they generally had similar horror stories. And most admins didn't even know, or would be too stubborn to admit, just how bad they had it; especially if you weren't the minority population that was a linux freak, good luck getting local code compiled. (And good luck getting any of those behemoth C/C++ codebases compiled locally even if you are, but that's another rant!) MUD admins very rarely had a background of coding professionally, and even when they did, certainly not in the games industry.
We however have a modern codebase with modern practices. This is a large part of what attracted me to this codebase in the first place. Lets take advantage of the strengths we have: local building, a good source control mechanism, etc. Code reuse is much easier in code than in scripts. Discovery is much better in code. Across-the-board improvements are much easier in code; let's say Actions were all scripts. Now it's much harder to go back through scripts stored in a DB or whatnot to update all the echos to use BasicSensoryEvents than using the straight writes. In code it's a simple matter of ctrl-shift-f "entity.Write(" etc to review just the most-likely-to-be-relevant bits, and painless to update them. Were this in scripts (essentially being DB data), it could take magnitudes more time.
Scripts have their strength, but the vast majority of interesting functionality should be in the easily-accessible C# files. Scripts might be good at giving mobiles a sequence of things to do, for tutorial sequences, etc. But then again, even these sorts of things are probably even better served in their own .DLL that can be pushed from the development/test environment as easily as the
Actions.DLL
can now with the hot reload functionality. Why build a new scripting language, or force people to learn one that differs from what they'd use to contribute to the other code of the MUD, or have them use C# that is compiled on the fly and stored in the DB but lacks the great features they'd get from just having that C# be hosted in a proper solution? What's the difference of compiling and updating a snippet of C# on the fly and compiling a DLL that can be updated on the fly? The latter might take 1 second longer to compile but is arguably a much better practice. It takes significant effort to put in a scripting language, and IMO with the modern environment we already have established here, there is absolutely no need, so all that effort would be misdirected. Not to mention the runtime resources needed to load and run a scripting language.On another note, one big stated mission of this project is to facilitate learning good real-life-job skills and practices. Lets have them use C#, not some LUA or homebrew scripting language they're far less likely to find a good job with. Let's have them work inside a proper development environment, even if they're "scripting behaviors". If they're looking for writing skills or level design, they still have building to look forward to, and "scripting behaviors" is only not "scripting" due to the definition of "script" versus "code." (IE lots of people say writing HTML is "coding" but in fact they are "scripting" by definition due to the non-compiled nature of HTML.)
In my current, ideal administrative dream, I would run a server through VS as my "development" environment, but also have a constantly-running "test/builder" environment that could double as a place for builders to do their work and for expanded testing that needs more than one person to test it, then have the "production" server constantly running where players are playing; "Production" would only be shut down when a reboot is required to gain a new build's features, but usually various tested components would be unloaded-upgraded-reloaded on the fly.)
If there really are a few key things that should be done as actual scripts, I can probably be persuaded, but IMO as little as possible of functionality should be outside the immediate housing of Visual Studio, and the inherent benefits therein.
Time-delayed infinite loops (like an AI that is wandering just back and forth periodically between two rooms) are not my cited concern here; A script that immediately cycles to executing itself either directly or indirectly through cyclic references, or never exiting a for-loop... the kinds of things that peg the CPU making the server suddenly unresponsive are what worry me most. The kind of things you catch when actually testing code or scripts; This is not the sort of bug you should be easily able to create 'on the fly' on accident on a production server.
(ed: You can't blame house builders for failing, if the only tools you give them access to is 100 spoons. This isn't about "bad builders". Copy-pasta was the only tool available to the builder scenario I described.)
We're operating on different opinions of what all is a scripting engine. First off, general OLC is not "scripting" IMO. For instance, your flashlight example can be done with OLC support for behaviors and such, without a drop of "scripting".
If by "world is going to end" you mean game world, then yes, with over-used scripting there will be accidental and/or hostile crashes/hangs, unless extreme precautions are taken. A sufficiently-limited, very-well-considered set of commands which do not allow (for instance) looping, referencing other scripts, etc, may be safe. If powerful scripts become so key to the building experience, even worse; they sure better not be doing anything like that on the live server. Not to mention we'd be likely requiring copy-paste tactics to get anything done rather than having solid building blocks to work with. Note that this is in the context that I believe OLC Building should be accessible to anyone who wants to do it, even on the main server and none of those users should have the ability to crash the game. If a user can do data entry, they ought to be able to make a pretty decent area. Sure, programmers and/or scripters should be given tools to go above and beyond (and appropriate precautions should be taken to validate code/scripts like that before deploying to production).
An object's Behaviors and each behavior's properties should indeed be easily modifiable and viewable from the OLC interface. This does not meet the definition of "scripting" I stated at the beginning, but I suspect you may consider this "scripting" given how you responded. A rich set of powerful Behaviors makes advanced game behaviors possible, but without the problems of true scripting.
I will however cede that scripts may be the most sane way to do certain custom behaviors with little to no chance of reusage - "this mob puts something in the cauldron, pours something in it, walks over to this other room to fetch something from the cupboards and returns" may be overkill to make a custom
MyZoneNameWitchBehavior
, although even that may actually be the preferential way to do it for many. Alternatives exist: We could have a genericPicksRandomActionBehavior
to attach to mobs where the builder just enters as data a multi-line edited list of commands the attached thing will try to execute periodically. Or anActionSequenceBehavior
that similarly "lightly scripts" a mobile with a builder-sequenced set of actions to attempt, and their execution attempts should be no more "dangerous" than a connected player issuing the same commands.This is false. If you mean "without OLC" then the statement is strong IMO, and I agree that we should have a strong, usable OLC which supports cool AI and so on. As for actual scripting though, non-reboot-updates of compiled code are quite possible with modern software. We proved the concept with pure domain loading/unloading already with commands - check out the
update-actions
test harness command to see one example. (While the MUD is running, edit a command to echo something different, name the resulting DLL "NewWheelMUD.Actions.DLL" and drop that in, and use the update-actions command to see this in action.) This approach had significant drawbacks and is difficult to get right (we certainly didn't get it perfect), but word is that other extensibility frameworks (like MEF?) handle this sort of scenario well. With proper locking strategies, players won't necessarily even notice the update.[ed 2021: Yes, MEF is how we implement
update-actions
successfully today, and this will be expandable to more systems using MEF.]Ah, yes there's more evidence you're referring to "we need OLC" and I whole-heartedly agree. "We need lines of non-compiled scripting language attached to entities" is tough for me to swallow, but "eventually want" is a statement I might accept, especially if it is actually something super easy for non-coders to use and hard for them to cause badness with.
I just want to take a moment to say that it's OK for us to disagree too, and we definitely value your participation here! I like to think I take criticism well and hope my comments are taken as a constructive exploration of our thoughts too.
Miscommunications are natural, even more so in pure text. I realize that I failed to communicate with the OLC post some key concepts of the OLC design in my mind; Essentially I envision a very object-constructive, progressive, property-specifying approach, with just a few key commands to see all the valid properties and such (and their current values), ... I'll just have to write a User Story to explain best what I have in mind and where it might be stronger than a free-form "scripting" style of building an object on the fly. :)
[ed 2021: See OLC Building]
Write code to do awesome stuff. Code from any source that isn't fully-trusted of course should be reviewed before deployment. Same should hold with scripting; if the user has the ability to do 'bad stuff' then that user's trustworthiness better match or outweight their ability to do bad stuff. A normal disgruntled builder generally shouldn't have the ability to crash the game. A not-fully-trusted builder should not be able to deploy a non-reviewed lines of scripting that, upon telling the mob a magic password, spawns millions of gold, etc. On the other hand we could compensate by having a 'code review' flagging system such that a higher-level admin reviews a general builder's scripting work. Or sufficient logging to automtically catch and report, and means to rectify such issues. Of course things like RandomCommandBehavior could be used for similar evil and probably warrants review too anyway.
I just mean we need to prevent things like stack overflow from being possible (IE Foo immediately calls Bar which immediately calls Foo). Several strategies are available; disallow such things on production server on the fly by not-fully-trusted-admins, building a script-stack-overflow-detection algorithm, etc.
I absolutely agree that code reuse is very important. That was one of my main points. Scripting that I've seen, even professionally by full time designers, is usually done through lame copy-paste tactics. Average Designer Joe doesn't understand the importance of code reuse, or worse, they think "code reuse" means "copy paste". There've been a myriad of blog posts, games conference panels, and the like ranting or discussing such prevalent problems. I don't claim to have found a great solution to make scripting experience better.
Agreed. I hope you like my OLC user story then :) I think the process is much easier for Average Joe than trying to remember a ton of proprietary scripting keywords/syntaxes/etc, deciphering potentially cryptic errors, and rewriting say, a pair of triggers, without things like IntelliSense or whatnot at hand, several times until getting it to be accepted, and then still not even realize he forgot to set functionally-important properties because he didn't know about them, etc. Then it turns out not to work and he doesn't know why and puts a ticket in for a coder to look at it. Maybe you have ideas for online tools which somehow guide Designer Joe towards your rather complicated trigger line pairs, for instance. (My OLC vision still leads to situations where Designer Joe fetches a coder for help but I think it'd be less likely.) Either way, you're right, the tools are critical.
Indeed, a morally powerful argument in favor of supporting OLC (and not just a graphical world builder) AND short commands (as retyping/adjusting a command isn't necessarily trivial to the blind - I do vaguely remember a blind relative's favorite offline text-based game, but I don't claim to be an expert on accessibility there nor did I know this relative very well - I was pretty young, but I don't recall any concept of 'cursor between characters' conveyed with her hardware - which if that is normally the case, might make adjusting complicated lines of script involve an awful lot of retyping.)
Ok so I lost net connection and subsequently lost this text when I refreshed the page to check the connection (oops) but I spent the offline time to write the OLC User Story and clarify my vision. I consider that stuff "level design" work when done in such an OLC model rather than "scripting" since it's all about setting/adjusting values, creating level content, etc. Setting the "RandomCommandBehavior" 'commands' multi-line string property is kinda approaching the lines of what might be defined as scripting though even though it's just a list of commands. (More response coming)
Indeed, it's largely a social issue and such decisions (choice) should be available to the particular administrative staff. "Builder" being a boolean trust status is just one option. The more complicated superset is to allow "multiple levels of builder" permissions which scale up in responsibility as your level of trust is awarded.
In other words, IMO it should be a supported model for an administrative staff to chose: anyone can build a basic area, even if you're not a high level regular player; some people just want to contribute more than they consume - once a builder has proven value and trust has risen (perhaps through the avenue of building good content itself) then they can be elevated to gain additional builder privileges/commands/etc. If our permissions model supports the ability to custom-define roles / permissions sets (which IMO we want to do, I think we've got a good thread or two on that) then scaling down to the simpler boolean "any builder has all builder permissions" model is inherently supported too.
On virtual object heirarchy, I've been trying to decide if that's a good idea. Whether, when a base flashlight template's weight changes, should instances of that flashlight all change? Probably. Should the metal flashlight template's weight change too, and instances of the metal flashlights' weight change too automatically? Probably not as it might change in the unexpected direction or to an unexpected value, etc. If the core nature of the OnOffSwitch is expanded/improved/bugfixed (IE to add new context-sensitive command patterns like "flip switch on X") then I think all objects which use it should inherently also gain the improvement.
[ed 2021: Touched a bit on heirarchy update ideas on the OLC User Story notes since then too.]
TLDR; Our only opponent to banning "scripting" seemed to repeatedly think we were proposing to ban "rich OLC" which is not remotely the case. We really want non-technical users to log in as builder and successfully create complex, wicked cool game interactivity. We need to provide great OLC tools for this. Then they just need to learn OLC commands, not a scripting language like CS-Script or LUA.
Beta Was this translation helpful? Give feedback.
All reactions