ID:151554
 
So somebody came into Chatters recently and it ended up in a conversation about creating an NPC Parser within BYOND. Essentially what would happen is you'd create an oversimplified language that allowed you type up a quick NPC in a text file and BYOND would parse it and load it in game for you to interact with. It'd have all the features of a hardcoded NPC - it'd just be more manageable and easier to edit (due to the simplification of things like input/output.)

Figured I'd give it a shot and spent 40 minutes or so to demonstrate the idea. The result is here: http://www.2shared.com/file/12884782/7a163098/ NPCParsing.html
(NPC that spawns is in NPCs/ and all it can do now is read its type, name, location, and perform OUT)


Any thoughts on actually implementing a system like this one? It'd take a lot of introductory work, but implemented right you'd be able to make as many NPCs as you like for a variety of situations quickly and easily. Not to mention you'd be able to load and unload 'em on the fly. Do you think it'd slow anything down? I don't, simply because the command structure is implemented into the NPC. Might take up more space as it has to load up NPC text files.

Edit:

Small note, just got IF statements to work (not in file I uploaded) and it was quite an adventure. Still haven't figured out how to merge || with && quite yet. Got just && to work though!
Haven't downloaded the file, but I believe I was present for this conversation.

What you're describing sounds to me like a built-in scripting language (and I believe that's the solution Stephen was discussing). If that is what you're looking for, I'd suggest doing some study on Context-free grammars. Good tools for writing parsers and lexers for a language are 'lex', which generates a lexer on the basis of regular expressions you provide for the tokens in the language, and 'yacc' (Yet Another Compiler Compiler) which creates a parser from a description of the language being parsed in EBNF form. 'lex' and 'yacc' are the original names of the program - there are lots of descendants. The variants I use are called 'flex' and 'bison'. There are variants that produce lexers/parsers in Java or Python or most any language - the originals produce C code.

Obviously parser-generators that produce C code aren't directly applicable to DM, but they provide a useful way for you to test out various ideas RE: grammar theory and specifying a grammar for a language. This stuff is pretty hard.

If you've got access to a fancy-pants library, I'd suggest looking up some books on compiler-writing and the like. A university library will likely have ones available - internet a bit to find something useful. If you're actually in tertiary education, talk to some of the Computer Science lecturers to see what they recommend.

If I'm on Chatters, feel free to bug me with questions about this stuff - I've done a little study in the area at uni, and I've fiddled with the problem a little (in the context of parsing DM, rather than parsing my own scripting language).

Incidental note: The really cheap way to solve all this might just be to use DM's external-call facilities to call out to a Python/Perl/Lua/Ruby/YourFavouriteScriptingLanguage parser.
In response to Jp
Well, that's a neat thought, but I was more interested in a conversation on whether or not such a thing would be worth the trouble to implement. I have no doubts as to my personal ability to get it to work (although proper control of parenthesis grouping in IF/FOR/ETC statements are throwing me for a loop.) After all, it's for something so simple that the scripting grammar need not be particularly strict.

As for running external calls, I could see it being fairly useful. Only thing is you'd essentially end up breaking down all the statements in the TXT file yourself to pass the appropriate variables anyways. Seems to me like you may as well just finish the job in DM. Then again, tools like you mentioned are specifically built for a job like this and will be able to create code that's essentially bug-free. But what's the fun in that?

Anyways, I've gotten nested IFs to work, I just can't figure out how the heck I'm going to group by ()s and implement || in an IF statement. I suppose I could break the statement apart into ()s, analyze each internal piece, and then take the returns from each internal piece and pass those numerical values again. I'd just need to find a way to run that through a loop to handle infinite nested parenthesis-grouped items, not to mention decide how to handle || or statements. The only part of || I see messing things up is Var1==Var2&&Var2==Var3||Var2. Should that be treated as (Var1==Var2&&Var2==Var3)||Var2 or Var1==Var2&&(Var2==Var3||Var2)
You might be interested in this library I released a while ago. Since that post was written, I added support for another less C-like language as shown on the library's hub entry. I haven't received much feedback on it, but am willing to provide updates if anyone finds bugs or has suggestions.

I also started a game called Automata using the library, but haven't done much work on it recently.
I don't know if your aware of this but by using such a thing as this you could make NPCs that evolve behaviour based upon a situation. Look up Genetic Programming.
The idea of dynamically parsing scripts can be used for more than just NPCs - many games base the majority (if not entirety) of their content on engine-parsed scripts. Things such as events, item effects, and character abilities are possible applications as well. That said: the question we should be asking is not whether it is feasible, but whether it is worthwhile.

A game scripting language would allow you to generate and modify content at runtime. Depending on how extensive the language is, you could change a lot of the game world without needing a hard reboot and the such. Not only you; you could volunteer other people to do this as well. Perhaps 'GMs' could be elected, who generate content and run adventurers for the players to participate in.

Done effectively, a scripting language wholly enhances the game experience. Just take a look at WoW, which allows players to completely change their interface through scripts. Or NwN, which has a content creator that allows players to create their own adventurers w/ the game engine. I think much of the reason for both these title's successes, in particular, the latter (it was probably the most popular feature in NwN), are exactly this feature. That said, I could name several games where the scripting language was so out of place, or so horribly implemented, that it contributed nothing and, occasionally, actually made development more difficult.

Furthermore, the process of effectively designing and implementing it is a concern. I had the time to check out Nickr's library, and it looks quite promising; you could probably use it to ease the implementation part, to an extent. Of course, the library only handles some syntax and logic areas for you, and you will still have a lot of work before it can be effectively used in your game.

Another question that is waiting to be raised is, do you need a fully-fledged scripting language? It would be considerably easier to create a more linear NPC file, say an XML document, where you fill in various fields and flags and the game handles the logic for you. It's a given that this system wouldn't be as allowing as a scripting language, but we should also consider how much we value the breadth of application over the ease of implementation.

Finally, everything possible with a scripting language, and much more, can be done in the language's mother. In this case, you can do anything you'd do with the scripting language in DM, far more easily and, in many cases, more elegantly.

So the end question is really one of time and applicability. Do you have the time and energy to do something like this? If so, are the benefits appealing enough that you would choose it over alternatives (such as the ones I mentioned)? I'd imagine the answer to the latter is wholly dependant on the kind of game you're making. Some games could definitely use a scripting language, others not so much.
In response to Mendon
Once again, this is where formal grammar theory is useful.

if_statement := IF '(' expression ')' INDENT statements DEDENT
expression := variable | literal | '(' expression ')' | expression OR expression | expression AND expression | expression EQUALS expression

That has a number of shift-reduce conflicts that correspond to the precedence issues you've brought up - is a == b || c (a == b) || c or a == (b || c)? You can embed the precedence specifically in the grammar, but it's sort of ugly and stupid. Parser generators generally allow you to specify precedence with special macros.

Of course, given that you're hand-coding a recursive-descent parser (Or should be, anyway), you'll want to look up how to embed it in the grammar.