As I slowly gain ground on my not-so-rapid prototype (I can pretty much authenticate and connect, and sit ready to send commands and receive world information), my mind wanders to the meat of the game server, which is vastly more interesting than the boring-but-necessary work of having to write login code.
One of the things that I often think about is the interaction between objects in an MMO, and how the interaction takes place from a code point of view. Though I started to write this post over a week ago, it was a post on a friend's blog that finally made me come back and finish it.
Over five years ago, on this blog, I previously wrote on the idea of how to handle the goings-on in a game world, and how the many objects and the world's rules would deal with them. This was before I learned about Metaplace's extension of Lua with their Trigger functions, or the .NET implementation of Events. As I practice my C#/.NET, and continue to work on MMORF, I realize that my method for dealing with such object interaction is still my preferred one.
I have two examples that I keep in mind when I work out the details of this system, both when I was writing my Metaplace RPG subsystem and now as I work on MMORF. These examples, of course, come from UO, my seminal example of what MMORF should be able to do. The main one is simply picking up an item in the game world.
Attempting to pick up an item in UO can involve a lot more checks than might be otherwise apparent. In no specific order, you need to check: if you're close enough to the object; if the character has something in-hand (not equipped, per se, but already being held/dragged by the mouse cursor); if the object is static, that is, part of the map; if the object is locked down (in someone's house, say); if the character has line-of-sight to the object. I'm likely missing something that UO needs, too, and there could be other checks that a non-UO game might want to make such as "is the object too heavy to be lifted?" (in UO you could move mountains, provided they weren't locked down).
Each of these things are rules of the world. The close-enough check is a variable (it's two tiles in UO). The something in-hand is an oddity in UO, since it's dependent on what can be considered a hidden character slot (the mouse cursor, a "third hand") being full, not either of the character's actual hands. The line-of-sight might be a universal requirement. Because these are all rules that are bolted on based on the design of the game system, the platform needs to support that bolting-on, not hardcoding just distance checks and locked-down checks and the like, but anything a game designer can think of -- you can only pick up this object if you're an elf, if your 12th level, if you have the right device equipped.
Each of these rules would manipulate a "result" object, something at which the framework can look, after everyone has had their say, to determine whether the action should be allowed. Thus, the distance checking rule might verify the user is close enough, and either say "yes, for now" or simply not say "no". The latter is more likely, as picking something up is probably better implemented as allowed-unless-not versus disallowed by default. But just because the distance rulecheck didn't say no doesn't mean that the next rule might not -- oh look, the object is locked down, so THAT rule will say "no", and the action will be prevented.
From my system administration background comes two kinds of permission systems as hinted at above: permissive unless prevented (except when overridden), and not permissive unless allowed (except when overridden). So picking up an item is likely the first case -- you can have it unless the rules say you can't -- but actually connecting to the MMORF game servers is the other way around: you're not allowed on UNLESS you can provide a valid username/password, EXCEPT you'll still be denied if your account has been suspended. The "except" case for picking things up might be the "gamemaster" rule: sure, the object might be too far away or locked down, but I'm a god in this realm, and such little rules don't apply to me. And it's much better to have the "gamemaster" rule as a separate rule that can overrule the "that's too far" rule, instead of having the distance rule say "okay, the character is further than two squares, but he's a gamemaster, so I'll say it's okay". Going this approach would mean that every rule would have to know to check the player's gamemaster status to know how to decide. Instead, having a single gamemaster rule that can overrule is better. It could also be implemented that the world has a function that returns a character's FurthestDistanceCanPickUp(), which the distance rule uses; THAT function might then look to see if the gamemaster flag is set and return "1000"; this would also also allow game worlds where different characters can reach further, because they are playing a race with longer arms, or are reaching with a pole, or reaching with telekinesis. In fact, this is sounding like a much better way to implement such a distance rule, instead of having a single number that a world builder can set. Just because UO has the two-tile reach for everyone doesn't mean the next game will.
Determining that a character CAN pick up an item then leaves the system to worry about what happens if they DO. In UO, it vanishes from the ground or container and goes into this pseudo-inventory slot, and the only thing that is likely to happen is that the character will attempt to drop the item (into his or her backpack, on the ground, on another player), and a whole other set of permission checks will take place. But what about actions that have more consequences than just moving things around? What if picking up the item causes damage to the holder? What if the item's absence from where it was triggers a trap? This starts a whole other line of thinking on the idea of Triggers - that some objects in the world are going to care when any item moves, so a nearby player's screen can update properly, and others when specific items move (moving the idol triggers the fire traps).
The second example I usually refer back to is using an item, but it rehashes a lot of the same ideas on the permission side as picking up an item. It's here where the result of successfully using the item, and the chain of events and rulechecks that take place, can get interesting, specifically (if you know anything about UO) when you go to use a crafting item. There's the obvious "can you reach the item" and "is it your item to use" checks, but then if you are allowed, how about "do you have the skill to use it", "what can you build at your skill level", "what are you going to make", "using what resources", etc. There can be a lot of back and forth with the user as decisions are being made, each question and decision being based on surroundings, inventory, attributes and who knows what else. And after all of the objects who have a say about the choices have said, there's the whole issue of success at crafting the item, based again on attributes, buffs, enchanted tools, magic forges, standing in a pentagram or whatever, each which might have their own say on how successful the character is.
For the most part, anything that the player has their character do is susceptible to modification by the rules, by their environment, by their belongings and by their characteristics, and the MMORF platform needs to be able to accommodate it all.
Showing posts with label scripting. Show all posts
Showing posts with label scripting. Show all posts
Thursday, June 17, 2010
Wednesday, March 01, 2006
Any chance?
I've recently discovered two other projects, Multiverse (http://www.multiverse.net) and BigWorld (http://www.bigworldtech.com). Both of these purport to be "Complete MMOG" solutions.
I heard of Multiverse from its relationship to James Cameron, the director, mentioned I believe in a Wired article. According to their press, they support the .mesh format (though I don't know graphic formats) and have a converter to get you from other popular formats, such as Maya and 3dMax. They have a tool for designing the world. They have support for a product called SpeedTree (http://www.speedtree.com) for providing scenery.
They provide a client, based on the Axiom 3D engine (http://sourceforge.net/projects/axiomengine), and the client can be customized using Python or C#.
The server is written in Java. Their target platform is Linux, but it also runs on Windows XP. They support multiple servers, splitting the world into a quad tree, and passing off quad trees to other servers. Objects are stored as either XML or binary data. Extensions to the server code are either written in Java, for low-level changes, or Java or Python to add features to their MARS (Multiverse Agnostic Rules System). The server does not currently support instanced areas. It uses TCP and UDP for communication.
The game world Kothuria (http://www.kothuria.com) has been built on the Multiverse engine. They do not charge licensing fees provided you do not charge for use of your world.
BigWorld I heard about on the Multiverse forums. I'm not sure what mesh format it uses, but it has a plug-in for 3dMax. They have a BigWorld World Editor to design to world.
They provide a client, the BigWorld Technology Client engine, which is customizable with Python, HTTP and XML. It runs on Windows.
Their server supports multiple machines, and re-aligns server load based on CPU usage. They don't say what language it's written in, but it can be modified with Python. They support dynamic world updates, dynamic manipulation, climate and day/night.
So what does this mean for MMORF? Well, it sure crushes the novelty of it all... I suppose I shouldn't be so surprised -- did I really think no one else would do this?
Both projects talks about being able to distribute the load across multiple servers, which is something that I, too, planned. They both support adding in customizations (I should hope so!) as I did, but I'm again astounded by the popularity for Python in this.
I've got a personal peeve against Python, which is probably clouding my view of it as the be-all end-all of scripting languages. Though I haven't looked too deeply into it, I'm under the impression that the Python runtime allows for some nice on-the-fly interpretation, which can be seen here on the BigWorld site, in the Kill Striff video near the bottom. That kind of interactivity is exactly what I want to be able to provide; not only having a console on which you can change the running world, but to be able to add, change and remove logic to the running server. If these two projects are using Python, I'm starting to ... worry ... that I might have to look into using it too.
I've mentioned before that I've wanted to use C# for this, because that is my current plan for the implementation language. I don't know what kind of interactive solutions are available for C#, or what kind of Python-on-C# solutions are available. I've also mentioned that it would be an interesting exercise to design a stripped-down scripting language, to help the non-programmers still work with the world. Python is a touch too involved for that, and C# would likely be as well.
Both systems provide clients, which is really beyond the scope of MMORF. While I plan to develop clients alongside the server for testing purposes, I hadn't planned on providing a client framework that would be used -- that's something that I would have left to my "customers" to supply.
The World Editor is something I never considered. I suppose providing a world editor would sure make world building a hell-of-a-lot easier than requiring world builders to use their god client to hand-place every item into the world, using the client's interface. Honestly, I hadn't considered it because the purpose of MMORF is to prove the theory that I could write the system, and never to use the actual system for anything concrete. Or populated.
One thing that I haven't found discussed in either project is the interface between client and server (cluster). That is, is there a separate login server, or does each server also act as a login server? If so, is there any rotation of this, or is that done through round-robin methods at the router? BigWorld talks about "[t]he maximum size depends on the number of machines and the switching fabric of the main switch", so this could be exactly what they intend (unless this "main switch" is something they provide.)
I envision MMORF separating the servers that the users connect to (portals to the servers) from the servers themselves -- from a logical view anyway. That is, to reduce the latency (lag) between the user's machine and the world's first point of contact, we might have these points nearer to the user ("near" being a networking idea, not a physical one) than the world servers themselves. The routing and communication between these portal servers and the world servers would then be separately analyzed and configured for optimal communication internally. Of course, they could be the same machine, for the cost-efficient worlds, but I want to provide the ability to separate them.
I'm not abandoning MMORF yet, but it's becoming less of a "wow" thing now. I still want to know, though, that I can write one myself... whether that ever gets done, we'll have to see.
I heard of Multiverse from its relationship to James Cameron, the director, mentioned I believe in a Wired article. According to their press, they support the .mesh format (though I don't know graphic formats) and have a converter to get you from other popular formats, such as Maya and 3dMax. They have a tool for designing the world. They have support for a product called SpeedTree (http://www.speedtree.com) for providing scenery.
They provide a client, based on the Axiom 3D engine (http://sourceforge.net/projects/axiomengine), and the client can be customized using Python or C#.
The server is written in Java. Their target platform is Linux, but it also runs on Windows XP. They support multiple servers, splitting the world into a quad tree, and passing off quad trees to other servers. Objects are stored as either XML or binary data. Extensions to the server code are either written in Java, for low-level changes, or Java or Python to add features to their MARS (Multiverse Agnostic Rules System). The server does not currently support instanced areas. It uses TCP and UDP for communication.
The game world Kothuria (http://www.kothuria.com) has been built on the Multiverse engine. They do not charge licensing fees provided you do not charge for use of your world.
BigWorld I heard about on the Multiverse forums. I'm not sure what mesh format it uses, but it has a plug-in for 3dMax. They have a BigWorld World Editor to design to world.
They provide a client, the BigWorld Technology Client engine, which is customizable with Python, HTTP and XML. It runs on Windows.
Their server supports multiple machines, and re-aligns server load based on CPU usage. They don't say what language it's written in, but it can be modified with Python. They support dynamic world updates, dynamic manipulation, climate and day/night.
So what does this mean for MMORF? Well, it sure crushes the novelty of it all... I suppose I shouldn't be so surprised -- did I really think no one else would do this?
Both projects talks about being able to distribute the load across multiple servers, which is something that I, too, planned. They both support adding in customizations (I should hope so!) as I did, but I'm again astounded by the popularity for Python in this.
I've got a personal peeve against Python, which is probably clouding my view of it as the be-all end-all of scripting languages. Though I haven't looked too deeply into it, I'm under the impression that the Python runtime allows for some nice on-the-fly interpretation, which can be seen here on the BigWorld site, in the Kill Striff video near the bottom. That kind of interactivity is exactly what I want to be able to provide; not only having a console on which you can change the running world, but to be able to add, change and remove logic to the running server. If these two projects are using Python, I'm starting to ... worry ... that I might have to look into using it too.
I've mentioned before that I've wanted to use C# for this, because that is my current plan for the implementation language. I don't know what kind of interactive solutions are available for C#, or what kind of Python-on-C# solutions are available. I've also mentioned that it would be an interesting exercise to design a stripped-down scripting language, to help the non-programmers still work with the world. Python is a touch too involved for that, and C# would likely be as well.
Both systems provide clients, which is really beyond the scope of MMORF. While I plan to develop clients alongside the server for testing purposes, I hadn't planned on providing a client framework that would be used -- that's something that I would have left to my "customers" to supply.
The World Editor is something I never considered. I suppose providing a world editor would sure make world building a hell-of-a-lot easier than requiring world builders to use their god client to hand-place every item into the world, using the client's interface. Honestly, I hadn't considered it because the purpose of MMORF is to prove the theory that I could write the system, and never to use the actual system for anything concrete. Or populated.
One thing that I haven't found discussed in either project is the interface between client and server (cluster). That is, is there a separate login server, or does each server also act as a login server? If so, is there any rotation of this, or is that done through round-robin methods at the router? BigWorld talks about "[t]he maximum size depends on the number of machines and the switching fabric of the main switch", so this could be exactly what they intend (unless this "main switch" is something they provide.)
I envision MMORF separating the servers that the users connect to (portals to the servers) from the servers themselves -- from a logical view anyway. That is, to reduce the latency (lag) between the user's machine and the world's first point of contact, we might have these points nearer to the user ("near" being a networking idea, not a physical one) than the world servers themselves. The routing and communication between these portal servers and the world servers would then be separately analyzed and configured for optimal communication internally. Of course, they could be the same machine, for the cost-efficient worlds, but I want to provide the ability to separate them.
I'm not abandoning MMORF yet, but it's becoming less of a "wow" thing now. I still want to know, though, that I can write one myself... whether that ever gets done, we'll have to see.
Labels:
C#,
game engines,
programming languages,
python,
scripting
Monday, June 13, 2005
Scripting
As I've mentioned before, scripting will be a big part of MMORF.
Because MMORF is just a framework, meant to run a world of objects and their movement and their interaction and their attributes, it will have only the basic rules that apply to any implementation of a world that a designer might create.
There will be no concept of ability scores (strength, charisma), or race (human, elf, orc) or even gender on the mobiles; objects will not have a weight, or color, or special attributes (magic powers, laser strength). These are all concepts that belong to the design of a world, but not the physics of the world.
The idea is that someone should be able to take the MMORF engine, slap in a bunch of customized code, and have the world run as they wish. If they want a world of fantasy, then the players are elves, have strength and dexterity and such, pick up magic +5 swords, and cast spells; sci-fi worlds will have aliens, lasers and whatnot.
Designing the core rules of the world should be something major, something that takes some time, and something that doesn't necessarily get changed all too often. These could be rules (scripts/code) that are loaded and applied when the world is started up. Any big changes to this world's universe, and the world might go offline briefly to update these programs.
But just as likely, we would want to add some functionality to the world as it's running. Gamemasters (GMs) might want to add some new behavior to a monster in the world, or create a new item that interacts in a new way with other objects, and would want to do these things without having to shut the world down. Additionally, trusted inhabitants (or players, in a game world) might be allowed to customize a subset of their world, as some MUD systems allow.
Because the customization might not be solely in the hands of the world designer (who, if not a competent programmer, would hopefully have one available), we might want to consider the learning curve for scripting.
Because MMORF will be coded in C# and .NET, the obvious way of adding customization is to allow modules (DLLs) to be written in native C# - it will run fast, and merges seamlessly with the system. The other straightforward alternative is to implement a scripting language (much as the Neverwinter Nights (NWN) game has done), which is then translated by the world as it runs.
The first method is appealing from a programmer's point-of-view, as well for time considerations. C# code will just directly access all the data in the world, which, of course, is both good and bad. Questions I had about C# being interpretable or compilable on-the-fly seem to have been partially answered - the RunUO project, also written in C#/.NET, has their customization done through C#.
The second method, providing a scripting engine, also has its plusses. The scripting language can be (if created from scratch) simple enough for the non-programmers to figure out. The NWN language was very C-like, and many tutorials were written on how to use it. Many, many useful scripts came from the NWN community, but it's not clear if the contributors were already programmers, or if they were regular Joes that could pick up the scripting language and use it effectively. The NWN language was pre-compiled, but only down to a byte-code level (I believe), so it was interpreted by the NWN engine. This kind of system would allow people in-game to type in code and have it happen immediately. Mobiles or objects could be examined in-game and have their code appear in a window, edited, and saved.
Not to say that you can't wing something like this from the "direct code" method. If the .NET framework provides a way to compile code on-the-fly, then the same could be done here. As to loading new versions while the world is "live", I'll have to investigate.
I'm leaning to the C# scripting solution. Its feasibility as a live scripting language will have to be checked. Additionally, because of the learning curve on C#, it might be desirable to have a beginner scripting language that can just be translated to C# (and then compiled); this scripting language could be used directly by the non-programmer world designer, or in-game for simple tasks. If the language is kept simple enough, mapping it to C# should be easy, and then that can be passed on and compiled with the scripter none-the-wiser that they just "wrote" C# code.
As for an API to the MMORF internals that the scripting language might use? That's for another time...
Because MMORF is just a framework, meant to run a world of objects and their movement and their interaction and their attributes, it will have only the basic rules that apply to any implementation of a world that a designer might create.
There will be no concept of ability scores (strength, charisma), or race (human, elf, orc) or even gender on the mobiles; objects will not have a weight, or color, or special attributes (magic powers, laser strength). These are all concepts that belong to the design of a world, but not the physics of the world.
The idea is that someone should be able to take the MMORF engine, slap in a bunch of customized code, and have the world run as they wish. If they want a world of fantasy, then the players are elves, have strength and dexterity and such, pick up magic +5 swords, and cast spells; sci-fi worlds will have aliens, lasers and whatnot.
Designing the core rules of the world should be something major, something that takes some time, and something that doesn't necessarily get changed all too often. These could be rules (scripts/code) that are loaded and applied when the world is started up. Any big changes to this world's universe, and the world might go offline briefly to update these programs.
But just as likely, we would want to add some functionality to the world as it's running. Gamemasters (GMs) might want to add some new behavior to a monster in the world, or create a new item that interacts in a new way with other objects, and would want to do these things without having to shut the world down. Additionally, trusted inhabitants (or players, in a game world) might be allowed to customize a subset of their world, as some MUD systems allow.
Because the customization might not be solely in the hands of the world designer (who, if not a competent programmer, would hopefully have one available), we might want to consider the learning curve for scripting.
Because MMORF will be coded in C# and .NET, the obvious way of adding customization is to allow modules (DLLs) to be written in native C# - it will run fast, and merges seamlessly with the system. The other straightforward alternative is to implement a scripting language (much as the Neverwinter Nights (NWN) game has done), which is then translated by the world as it runs.
The first method is appealing from a programmer's point-of-view, as well for time considerations. C# code will just directly access all the data in the world, which, of course, is both good and bad. Questions I had about C# being interpretable or compilable on-the-fly seem to have been partially answered - the RunUO project, also written in C#/.NET, has their customization done through C#.
The second method, providing a scripting engine, also has its plusses. The scripting language can be (if created from scratch) simple enough for the non-programmers to figure out. The NWN language was very C-like, and many tutorials were written on how to use it. Many, many useful scripts came from the NWN community, but it's not clear if the contributors were already programmers, or if they were regular Joes that could pick up the scripting language and use it effectively. The NWN language was pre-compiled, but only down to a byte-code level (I believe), so it was interpreted by the NWN engine. This kind of system would allow people in-game to type in code and have it happen immediately. Mobiles or objects could be examined in-game and have their code appear in a window, edited, and saved.
Not to say that you can't wing something like this from the "direct code" method. If the .NET framework provides a way to compile code on-the-fly, then the same could be done here. As to loading new versions while the world is "live", I'll have to investigate.
I'm leaning to the C# scripting solution. Its feasibility as a live scripting language will have to be checked. Additionally, because of the learning curve on C#, it might be desirable to have a beginner scripting language that can just be translated to C# (and then compiled); this scripting language could be used directly by the non-programmer world designer, or in-game for simple tasks. If the language is kept simple enough, mapping it to C# should be easy, and then that can be passed on and compiled with the scripter none-the-wiser that they just "wrote" C# code.
As for an API to the MMORF internals that the scripting language might use? That's for another time...
Thursday, April 14, 2005
Triggers and events
While thinking about the scripting language to use (a topic for another day), the idea of event-handling and triggers came to mind. Whatever language I choose to use or write should be able to support them, because I feel that events are a big part of a virtual world.
The best example is speech. A character walks up to the banker and says, "I'd like to access my bank box please." Or he walks onto a magic circle and says a certain word, finding himself teleported to another part of the world. Both of these examples are from Ultima Online, but I'm sure every virtual world has some case of this. Maybe not speech, exactly, but some way for an NPC or object to react to something a character does.
The issue is how to implement it. There are two ways that I can see: each object (which includes PCs and NPCs) has a youJustHeard() function, which is passed a reference to the speaker, and the text spoken; or each speaker has a youJustSaid() function, which takes the text spoken.
In the first case, every object in the world has a listener function. There are really two ways to deal with this: each object, upon creation, must register itself as a listener, to let the world know that it might be interested in things that are said in the world; or whenever something is spoken, the world looks around the speaker to get a list of all the objects within range, and "tells" each of them what was said.
If the world has to check for nearby listeners every time anything is spoken, it should be obvious that there is going to be a lot of this searching. When characters start gabbing in-game, every table, door, dog and character within a given distance is going to be told, whether or not they want to know. In this case, we better hope that we have one hell of an optimized way to get a list of objects within a certain area.
With the registration method, the world would be able to reduce the number of objects that it has to look through, because only objects that can listen are registered. Again, we would still want this to be very optimized, since every character will be in this list, as will many NPCs and probably some inanimate objects.
Both of these methods of listening seem to have a lot of overhead for every word said.
Taking the other approach, it's the responsibility of the speaker to let everyone know what was said. Instead of relying on the server to do all the figuring for finding listeners, the logic for that could be part of the speaker's youJustSaid() script, which would ask the system for a list of things within range (something that seems to be inescapable), and then the speaker's script would call each of the listener's youJustHeard() functions.
At first glance, this seems to be less effective than letting the server do it directly, because the same work is being done (finding a list of listeners, calling each of their functions), but now it's (most likely) being done in an interpreter, which isn't as optimal as a compiled server core. And while that's probably true, having the logic take place in a dynamic spot -- that is, something that the game designer can change -- allows for more flexibility whenever something is spoken.
For instance, perhaps our world allows spells, and instead of clicking an icon or scroll to cast, you simply say the words out loud. As well as having every listener's youJustHeard() being called, we would also want the character to start waving his or her hands, and spell effects to happen, and an apple to appear. Or a certain class of character might be able to open doors with but a word; the doors by themselves have no logic to listen for such things (though it could of course be added), but the speaker's script could not only inform all listeners of the words, but also call the door's use() function. Having the speech handler "local" to the speaker also allows them to control who hears them - they might have a slider that defines how loud they speak (whisper, murmur, talk, yell), or they might be able to speak to one person specifically (telepathy).
All of these things can, of course, be done at the listener's side instead of the speaker's side, and is just as accessible to the world designer, for he or she controls the scripts for everything in the world. And there's no reason that you can't mix the two; the generic "character speaker" script may know how to open doors or cast spells when the character speaks, but there's no need to put the logic for word-activated teleporters in every character when the teleporter itself can have that functionality coded into its listener script. But with this approach, we're saying that it's still the speaker's responsibility to let the teleporter know that something is said -- and what it does with that is up to it.
A third possibility, which I'm not going to entertain, is a "speech parser", which looks at everything everyone says and decides how to handle it. If a sentence contains the word "bank", then search for any bankers nearby and tell them. If one of the four magic words in the game are spoken, check the character is in one of the few places that it matters.
This is very limiting. It basically hard-codes these trigger words, requiring a list of words and their effectual area or audience. The parser might also be responsible for making the effect happen, instead of calling a function on some other object -- again, very awkward.
So, speaker or listener. A decision needs to be made... but not so fast. Triggering and events based on speech is only one possibility. What about the shopkeeper that sees you steal something? What about the citizen that sees you attack another? What about the guard that sees you discard items on the ground - littering!
Speech is only one of the generic actions that we might want world objects to react to. NPCs and monsters should likely defend themselves when you attack them; guards might arrest you if you move somewhere you shouldn't; and the shopkeeper certainly shouldn't sit idly while you get his inventory without paying.
But again, who should handle this? If my character attacks a monster, then it's pretty easy to let that monster (and its beingAttackedBy() function) know this. But what about onlookers? Maybe another monster will step in if you attack its buddy, or a nearby NPC will come to aid you.
If I drop an item on the ground, do I tell every object about this put action I just did, or do I broadcast a "I just put X at Y" message and let the "listeners" do what they will with that knowledge (fined for littering, beggars run over to pick it up). Note that depending on the game interface, this might also "push" a look action to some clients so they now know the item's there, or the world has a constant look going. But it's different to see an object suddenly appear on the ground, and to know that character X put it there. Or at least it should be.
I don't think I've convinced myself either way on who should take care of these messages about the events in the world. I'm hoping as I continue to mull over it that I can find an example that definitively says that one method is better than the other (and I equally hope I don't find two examples that contradict).
The best example is speech. A character walks up to the banker and says, "I'd like to access my bank box please." Or he walks onto a magic circle and says a certain word, finding himself teleported to another part of the world. Both of these examples are from Ultima Online, but I'm sure every virtual world has some case of this. Maybe not speech, exactly, but some way for an NPC or object to react to something a character does.
The issue is how to implement it. There are two ways that I can see: each object (which includes PCs and NPCs) has a youJustHeard() function, which is passed a reference to the speaker, and the text spoken; or each speaker has a youJustSaid() function, which takes the text spoken.
In the first case, every object in the world has a listener function. There are really two ways to deal with this: each object, upon creation, must register itself as a listener, to let the world know that it might be interested in things that are said in the world; or whenever something is spoken, the world looks around the speaker to get a list of all the objects within range, and "tells" each of them what was said.
If the world has to check for nearby listeners every time anything is spoken, it should be obvious that there is going to be a lot of this searching. When characters start gabbing in-game, every table, door, dog and character within a given distance is going to be told, whether or not they want to know. In this case, we better hope that we have one hell of an optimized way to get a list of objects within a certain area.
With the registration method, the world would be able to reduce the number of objects that it has to look through, because only objects that can listen are registered. Again, we would still want this to be very optimized, since every character will be in this list, as will many NPCs and probably some inanimate objects.
Both of these methods of listening seem to have a lot of overhead for every word said.
Taking the other approach, it's the responsibility of the speaker to let everyone know what was said. Instead of relying on the server to do all the figuring for finding listeners, the logic for that could be part of the speaker's youJustSaid() script, which would ask the system for a list of things within range (something that seems to be inescapable), and then the speaker's script would call each of the listener's youJustHeard() functions.
At first glance, this seems to be less effective than letting the server do it directly, because the same work is being done (finding a list of listeners, calling each of their functions), but now it's (most likely) being done in an interpreter, which isn't as optimal as a compiled server core. And while that's probably true, having the logic take place in a dynamic spot -- that is, something that the game designer can change -- allows for more flexibility whenever something is spoken.
For instance, perhaps our world allows spells, and instead of clicking an icon or scroll to cast, you simply say the words out loud. As well as having every listener's youJustHeard() being called, we would also want the character to start waving his or her hands, and spell effects to happen, and an apple to appear. Or a certain class of character might be able to open doors with but a word; the doors by themselves have no logic to listen for such things (though it could of course be added), but the speaker's script could not only inform all listeners of the words, but also call the door's use() function. Having the speech handler "local" to the speaker also allows them to control who hears them - they might have a slider that defines how loud they speak (whisper, murmur, talk, yell), or they might be able to speak to one person specifically (telepathy).
All of these things can, of course, be done at the listener's side instead of the speaker's side, and is just as accessible to the world designer, for he or she controls the scripts for everything in the world. And there's no reason that you can't mix the two; the generic "character speaker" script may know how to open doors or cast spells when the character speaks, but there's no need to put the logic for word-activated teleporters in every character when the teleporter itself can have that functionality coded into its listener script. But with this approach, we're saying that it's still the speaker's responsibility to let the teleporter know that something is said -- and what it does with that is up to it.
A third possibility, which I'm not going to entertain, is a "speech parser", which looks at everything everyone says and decides how to handle it. If a sentence contains the word "bank", then search for any bankers nearby and tell them. If one of the four magic words in the game are spoken, check the character is in one of the few places that it matters.
This is very limiting. It basically hard-codes these trigger words, requiring a list of words and their effectual area or audience. The parser might also be responsible for making the effect happen, instead of calling a function on some other object -- again, very awkward.
So, speaker or listener. A decision needs to be made... but not so fast. Triggering and events based on speech is only one possibility. What about the shopkeeper that sees you steal something? What about the citizen that sees you attack another? What about the guard that sees you discard items on the ground - littering!
Speech is only one of the generic actions that we might want world objects to react to. NPCs and monsters should likely defend themselves when you attack them; guards might arrest you if you move somewhere you shouldn't; and the shopkeeper certainly shouldn't sit idly while you get his inventory without paying.
But again, who should handle this? If my character attacks a monster, then it's pretty easy to let that monster (and its beingAttackedBy() function) know this. But what about onlookers? Maybe another monster will step in if you attack its buddy, or a nearby NPC will come to aid you.
If I drop an item on the ground, do I tell every object about this put action I just did, or do I broadcast a "I just put X at Y" message and let the "listeners" do what they will with that knowledge (fined for littering, beggars run over to pick it up). Note that depending on the game interface, this might also "push" a look action to some clients so they now know the item's there, or the world has a constant look going. But it's different to see an object suddenly appear on the ground, and to know that character X put it there. Or at least it should be.
I don't think I've convinced myself either way on who should take care of these messages about the events in the world. I'm hoping as I continue to mull over it that I can find an example that definitively says that one method is better than the other (and I equally hope I don't find two examples that contradict).
Subscribe to:
Posts (Atom)