ID:152837
 
[Edit: This will be for a text-MUD, but could apply to any RPG]
[Edit2: This original post is pointless now. Please refer to my second post in the thread; it's much clearer (and won't make you giggle)]

Unless things really turn around and I find a lib that is very relevant to what I'm doing, or someone pops out of nowhere saying that they are currently working on a general purpose scripting language for Byond, I am going to have to handle Customized World Events in a different fashion. I don't even know what to call them...events? functions? scripts? For now I will refer to them as CustE's or 'custies', short for Custom Events.

First of all, the way these will be soft-created is by filling out forms and checking options. So, when building a room, for example, a builder would click a button that says 'Add Custom Event' which would display dialogs for the builder to choose what type of custie, and then edit its properties. An example of a room custie would be something that displays this message every 30 seconds a player is standing in the room, "Muffled shrieks and screams reach your ears from somewhere below you in these passages. The sounds are uncomortably near."

Here is where I'd like advice: how should I handle calling these things in my world? What is the best way to plug them into the compile, and similarly into the loading of the world? Should all /room custies (okay now I feel just silly, but bear with me) only be 'activated' when a player steps in the room? Or, should I have a unique /CustieCommander (this is reaching hilarity) object which is in charge of controlling all the custies in the world; mainly because many of them are time-sensitive?

Keep in mind that, due to the nature of the project, I will undoubtably be adding custies all the time, even long after the World Building project is "complete". Builders are notorious for saying things like, "Man, it sure would be cool if were able to do THIS when a player walks into a room." Also, in case you haven't guessed already, these things will be attached to the virtual objects themselves inside data files.

Thanks for your input,

=$= Big J Money =$=
BigJMoney wrote:
Unless [...] someone pops out of nowhere saying that they are currently working on a general purpose scripting language for Byond

It's on my to-do list. But it's been on my to-do list for at least a year now, so don't hold your breath. =)

Here is where I'd like advice: how should I handle calling these things in my world?

Here's how I'd do it:

Separate custies (I think I'm going to rename them to "scripts" to avoid excessive smirking =)) into conditions and actions. A condition is something like "Every X seconds", or "When a player enters this room". An action is something like "Send a message to all players in this room".

When a condition is triggered (e.g. a player enters a room), run through all scripts, looking for matching conditions. When you find one, do the actions.

Use datums for scripts, conditions, and actions. Each condition and each action should be its own subtype. Example:

script
var/condition/condition
var/list/actions = list()

condition
timed
playerEntersRoom

action
sendMessageToRoom


Should all /room custies (okay now I feel just silly, but bear with me) only be 'activated' when a player steps in the room? Or, should I have a unique /CustieCommander (this is reaching hilarity) object which is in charge of controlling all the custies in the world; mainly because many of them are time-sensitive?

Both. Time-sensitive ones (/condition/timed in my example) should be controlled by a global loop for efficiency; others can just be triggered on certain events (like /conditionPlayerEntersRoom, which is simply triggered in an Entered() proc somewhere).
I concur with what Crispy says, and I have a rudimentary library written for my project that does things in a very similar way. As far as adding them into the game without recompiling, etc, takes some work. The method I have come up with simply entails writing a new trigger or action (rather than condition and script, as Crispy called them, but it's the same meaning) for every new type of action I want. As far as writing "scripts" in-game, one method you can use is to create a list of "script" elements and corresponding code snippets, etc. As a creator adds to his/her script, the corresponding code is added to a new .DM file and the inclusion statement is added to an already-included "Scripts.dm" so that when the project is re-compiled and rebooted, the scripts will load naturally.
In response to PirateHead
You shouldn't need to recompile - just create the appropriate datums, and add them to the appropriate lists (or whatever) so that they get triggered when you want them to be. No compilation or rebooting necessary.
In response to Crispy
I only recompile or reboot when I want to add new functionality. Like, for example, if I wanted any player whose name contains the word "happy", I might have to write a new trigger for that . . . which requires recompiling, unless you have a true scripting language.
In response to PirateHead
Oh, for making new conditions and actions available, sure. I thought you meant recompiling every time a player created a new script (and by "script" I mean a new combination of conditions and actions).
You might want to look around BYONDscape, I believe Deadron wrote a very nice event library.
In response to Crispy
My internet connection has disallowed me from getting back online recently, but I'm back and I've had some time to think. First of all, thank you very much for these suggestions. I'm going to try and form my plans around this type of thing, and here is what I've got so far:

Terminology
~~~~~~~~~~~
Event: A sequence of script commands that are combined and linked to an object instance, such as a virtual Room or an Item (event data is stored right with the object data)

Trigger: The 'action' which causes the event to begin.

Command: An event is made up of its individual commands. These would be things like "showmessage", "damagehealth", etc. You combine them in one event for organization and to have them all called by a single Trigger. Other kinds of commands possible will be #if branches, #timer and #beginquest calls.

Condition: These optional pre-existing conditions must be met before the trigger will "spring". These have the same effect as if you started your Event with an #if command, and I'm not sure if they are necessary or not.
~~~~~~~~~~~~
With me so far? Taking your advice, and since my "command"s equate to your "script"s, the command prototypes will be datums. My "trigger"s are the same as your "condition"s, but since they are not tangible, I'm not sure there is a need to give them prototypes; they can simply be accounted for in the code. For example: a player walks into room #2112. The Enter() proc of the room is called, and it will check to see if any triggers were built into room #2112 by its designer. In essence, the "trigger" is simply some code that exists in the Enter() proc, plus a flag the builder added to his room which also points to the Event data also stored into room #2112's data.

My only question is if doing triggers this way has any drawbacks. They will be scattered throughout the code. I suppose I could put them all in one place and have them called from the location where they should be called from, but that seems like an unnecessary step, because I will still have to remember where those places are. Also, I wonder if down the road I will have an idea for a Trigger that won't be so easy to implement in this way.

Thoughts? Further suggestions? That last part is mainly theory, and I'm more interested in what you think about my implementation idea so far.

=$=
In response to BigJMoney
It sounds well-founded, but I think that you should continue on before asking for input and evaluation. You'll have a better understanding of the problem once you're in the process of actively solving it.