13 Mar, 2012, Deimos wrote in the 1st comment:
Votes: 0
Game objects, that is.

I'm curious what the current accepted practice is with respect to game object class hierarchies. I have an aging system yhat I'm refactoring, because it was far too restrictive in what I could create. I went inheritance crazy or something. Sword extends weapon extends inanimate object extends object extends thing, and so on…

Even in that simple example, I run into the problem of players not being able to use fun stuff as weapons in weird situations (imagining someone grabbing a bottle in a bar and fighting with it and things like that). Of course, I could create special non-weapon items that extend Weapon, but that's just wasteful and silly.

In fact, I'm thinking of getting rid of differentiations like weapon and non-weapon in favor of some kind of highly generalized attribute system. A sword, for example, would have the "sharp" and "blade" attributes, among others. Maybe a broken bottle and arrow would also have the "sharp" attribute. Fighting with a "sharp" object might cause bleeding in your opponent. Fighting with a "bladed" object might open up certain combat skills.

The system I'm envisioning applies to far more than just weapons, though.

Are there any obvious drawbacks to such a system that I'm not seeing? Do you use a similar or alternate system? How well does it work for you? Is it flexible enough to handle emergent gameplay?
13 Mar, 2012, plamzi wrote in the 2nd comment:
Votes: 0
I'm not addressing the technical aspects of this question at all because my server code is in C, but I can address some of the game design implications. Curiously, this has been in the front of my mind lately, because I've also found myself departing from strict object definitions in favor of more abstract properties.

One downside that I'm seeing is that when an event occurs, you can no longer read one property (say, "object type bladed weapon") and be able to assume the rest of the object properties (it can be wielded, it's sharp, it can slash, it can cut, etc.). This makes the processing of events that key off of multiple properties (e. g. a battle round) more verbose.

Another downside I'm anticipating is in building. There's something to be said about being able to set type to "bladed weapon" and be done with it. Of course, you can still achieve that by building in some smart presets in the tools that set a combination of flags together, but that of course is a meta-layer of extra work.

Overall, however, I feel like the flexibility is well-worth it. I've been working on a crafting system, and it really pays off to be able to transfer various properties from source objects to products, combine properties, etc. Once items are crafted and in circulation, I think I'll go back to a more 'defined' state to minimize some of the extra labor involved. That is, at least for the crafting system, I'll try to keep most of the "raw" property-handling confined to code that runs only when special events happen (e. g. a new item is created).
13 Mar, 2012, Deimos wrote in the 3rd comment:
Votes: 0
I think you make a good point with respect to having more work to do in creating object prototypes for building purposes, but like you, I think the flexibility is well worth it. Besides, most prototypes that I can think of off the top of my head would only need a small handful of attributes (e.g. a "light" prototype would only require the "luminescent" attribute - anything beyond that is icing on the cake).

Concerning the event handling being more verbose, I imagine that could be addressed in much the same way. If a group of attributes are commonly needing to be compared, I would just abstract it into a method, so that you could do something like:

if obj.isFood() …

function isFood()
return this.hasAttributes(edible, organic, sustenant)


as opposed to the more common:

if obj.getType() == ObjType::FOOD …


or something along those lines (please forgive the pseudocode).
13 Mar, 2012, Kline wrote in the 4th comment:
Votes: 0
This post by KaVir awhile back is what I've been working on recently for my own project; coming from a Dikurivative. My end goal is for most things to be seamlessly transitioned to allow things such as "entering" a creature/player, etc. So far I have split sockets to Brain, anything else to Thing. Once I'm done combining all the general facets of thing between existing object/NPC/room structures (they all have names…descriptions, etc) the rest will be derived classes to implement the specifics of how "put bob into bag" differs from "put bag into bob".

edit: Re-reading your OP, I See this is partly what you've done except you went far far down the rabbit hole :) I'm aiming to keep things as generalized as possible in my own approach. Brain is strictly either a player socket or (eventually) a re-implementation of NPC scripts/AI. Thing is, well, anything else. The limits of "get bob, equip bob, fight monster" would probably be related to how "large" one Thing is relative to Bob. If a "NPC" has size properties relative to that of an ogre, and Bob is sized relative to that of a small animal, then I can't see a reason to not allow "get bob, equip bob, fight monster" with working out the damage dealt by "bob being used as a club" based on level, or some other stats, etc.
13 Mar, 2012, Rarva.Riendf wrote in the 5th comment:
Votes: 0
With objects also come the problem of over engineering.

Quote
If a "NPC" has size properties relative to that of an ogre, and Bob is sized relative to that of a small animal, then I can't see a reason to not allow "get bob, equip bob, fight monster"


I see one or two. Why allow it with a npc and not with a player once he is stunned.
Then that would kill him? Ok now that he is dead, what to do of him. Corpless soul as his is still used ?

No engine will suit any kind of game, and making a too general engine is then over complicated for all of them.

Using OOP is not a mean to get bulletproof engine that can adapt to anything. Thinking engine first/game after is a dangerous choice. One size fits all hardly ever works.
13 Mar, 2012, Deimos wrote in the 6th comment:
Votes: 0
@Kline: I agree completely! That would be a rather amusing example of the kind of emergent gameplay I'm aiming for. Size is one thing I'm currently struggling with modeling, though. For example, should a 14 ft. long lance be as "large" as 14 ft. diameter boulder? Obviously there's a huge *weight* difference, but how do we generalize size without going into actual dimensions (definitely don't want to go that route).

@Rarva: This isn't about making a generic game engine. It's about supporting emergent gameplay, which makes a game more fun, and immersive. Players don't like to be told "You can't do that" when they try to wield a lantern as a weapon, and things like that. And I don't blame them. There's absolutely no technical reason we can't allow things like this.
13 Mar, 2012, Rarva.Riendf wrote in the 7th comment:
Votes: 0
Quote
@Rarva: This isn't about making a generic game engine. It's about supporting emergent gameplay, which makes a game more fun, and immersive. Players don't like to be told "You can't do that" when they try to wield a lantern as a weapon, and things like that. And I don't blame them. There's absolutely no technical reason we can't allow things like this.


There is no technical reason, but there is a gameplay one: Games are for fun, and mimicking reality may not be a goal to achieve fun. Players dont like to be told they can only sustain one slash of sword as well. I am not so sure that preventing burning everything into the ground is such a detterrent to fun for most. I can understand it is for some though. Interaction with environment can ge fun but then you really have to be careful how you 'repair' it, because everythig will be burnt to the ground into ashes in a second.

Anyway I was jsut saying that technicaly you should think about what you ctually want to achieve in the game, and not what you could achieve if you added the option in the engine. Always think about the end result, not about the tool.
13 Mar, 2012, quixadhal wrote in the 8th comment:
Votes: 0
Not sure if the language you're using allows it, but multiple inheritance is the usual thing for making objects that can act like several different kinds of object. IE: A sword is a weapon, a lantern is a light source. If the lantern also inherits WEAPON, it should respond to being wielded and allow you to set stats and whatnot. One could also make a magic sword that inherits LIGHT so it glows and illuminates the room like a lantern.

As for size without size… try making an arbitrary scale with enough granularity to suit your needs. IE: size is 0..99, and perhaps a typical short sword is size 20, a typical apple is size 3, a typical house is size 60. Just fiddle around until you find you can get enough variation and still have a bit of room to play with. Then you just say, humans can wield weapons from size 3 to size 30, giants can wield from size 10 to size 40, halflings from size 2 to 25 or whatever.
13 Mar, 2012, Rarva.Riendf wrote in the 9th comment:
Votes: 0
Better put all that in a specific abstract object (properties like size, weight, light status, durability, damage/kind of damage when used as a weapon kind of damage, list of component materials)
No real need for two different objects there.
OOP does not mean multiplying objects for the sake of it. It is about only doing so when properties are really making the object different.

Imho, light and weapon are perfectly similar and standart objects, but from the abstract object I put as an example, food is another:it can be eatable, poisonous, wield a different energy filling property.
13 Mar, 2012, quixadhal wrote in the 10th comment:
Votes: 0
Inheritance is cheap.

Why stuff unrelated properties into some generic "abstract" container, when you can easily just have your tangible objects inherit whatever they need? I don't see "light" and "durability" as being related in any way, but I can see light sources which have no durability (the sun? the sky? the glow from a lake of lava?), and obviously all kinds of objects which will never have light, but also objects which may have both (a torch, a light bulb).

The advantage of making inheritables is you don't just get data, you get functionality. A light inheritable might include functions to turn it on or off, to brighten or dim it, to direct it, perhaps even to color it. A durability inheritable might include functions to increase/decrease the current or maximum values, as well as functions that can be called when it breaks or is repaired.

In my light bulb example, maybe durability is the number of hours it has left before it burns out. If you dim the bulb, it may extend its lifespan. If you break it, you may want to ensure it cannot be repaired.

If you stuff all that into a single "properties" object, you'll be constantly updating that object AND your game's data space will be bloated with tons of functions and variables that aren't used because you needed just one or two of them and had to include the whole thing.
13 Mar, 2012, Deimos wrote in the 11th comment:
Votes: 0
@quix: The point is to stay away from inheritance, so that things "just work." For players to be able to pick up a chair and proceed to beat a shopkeeper with it, sure I could create a special chair that inherited from both Furniture and Weapon, but then I'd have to do that for infinite combinations of items and item types in order to get the same behavior as I would automagically get by discarding inheritance WRT item types.

If any tangible thing can be used as a weapon, and we simply calculate damage based on the strength of your character, weight of the thing, "sharp" attribute, material, and so on, then we now have a system where really interesting things can happen without having to be explicitly coded. Maybe a player found an old wagon wheel and used it as a shield. Maybe he found his way through a dark forest using a glass jar (container, transparent attributes) full of glow worms (luminescent attribute).

The possibilities are endless, if I can use a poor cliche. Of course, with this kind of flexibility comes danger in the form of accidentally allowing unintended behavior. Maybe a player floated himself across your impassable acid moat on an acid proof object with the buoyant attribute or something. But, I think the advantages far outweigh the disadvantages. I might be a bit myopic, though.
14 Mar, 2012, plamzi wrote in the 12th comment:
Votes: 0
Deimos said:
The possibilities are endless, if I can use a poor cliche.


Rarva.Riendf said:
Always think about the end result, not about the tool.


I'd like to reiterate Rarva's point above by way of focusing on the practical dimensions a bit. The possibilities are endless even before you've written a single line of code for a game. But games are not worlds of endless possibilities (and neither is reality). To take your example, if a player can pick up an old wagon wheel and use it as a shield, that's kind of cool, for about a minute. But if there's any better shield in the game (e. g., a shield) then picking up an old wagon wheel in a combat-driven game would be something only an ignorant under-equipped newbie would do (maybe it has some RP value, I can't speak to that). And so you may end up building a huge forest of proverbial falling trees that no-one really sees, or sees but doesn't need to see again because they don't really advance their character. The time you invested in making any round flat object usable as shield, you could have invested in creating a few hundred items type shields that are balanced in a way that will make people want to use them repeatedly within the rules of your world. Basically what I'm trying to say is that so far in your examples "emergent" seems a bit "transient". I. e. unless you reward bonus points for "artistic impression" whenever someone cuts down a boss with a broken beer bottle. :)
14 Mar, 2012, Deimos wrote in the 13th comment:
Votes: 0
@plamzi: You're still in a concrete object type mindset. What makes you think a wagon wheel is an inferior shield? The size, shape, weight, and materials are very similar to that of a lot of shields. If the game uses these properties for determining, say, shield blocking proficiency, then a wagon wheel would not just be "newbie trash." While it may not be as durable or magical as your End-Game Dragon Scale Shield of Awesomeness, it doesn't have to be in order to be useful.

Also, no time is spent doing much of anything. Off the top of my head, shield blocking might check that an object is at least a given size and perhaps less than a given weight, but then anything matching that criteria can now be used as a shield *implicitly*. I don't have to do anything extra. Why should an object be innately better as a shield simply because it "is a shield"? That's illogical. An object might make a better shield if its size, weight, and materials are in certain ranges, but those properties could be checked against any item. Who cares if it's a wagon wheel?

Heck, a wizard might even enchant the wagon wheel with spells to make it even better. :)

Anyhow, try to look past my (probably) poor examples and see the idea for what it is, which is a way to 1) drastically simplify code, and 2) provide opportunities for more interesting gameplay.
14 Mar, 2012, quixadhal wrote in the 14th comment:
Votes: 0
Deimos said:
@quix: The point is to stay away from inheritance, so that things "just work."


First of all, inheritance is not the issue with things "just working" or not. If you use inheritance, you have modular code and can add new behaviors without having to go edit 5,000 functions related to all the raw property data. If you don't use inheritance, you have ugly monolithic code that has to be constantly fiddled with. Either way, how the world objects behave is up to you.

If you really want every object to be useable as every kind of thing (which is a very BAD idea, IMHO), have them all inherit everything. Then when you realize how silly it is for your human players to eat metal warhammers, and fight with chunks of meat, you can change your mind without having to retool the universe.

The point is, inheritance is useful and appropriate for anything where you can say "this thing IS-A <insert value here>". A data value (or property) is useful whenever something "HAS-A" <insert value here>. An apple is a fruit. An apple is food. An apple is a small ineffectual weapon. An apple has seeds. See the difference?

Deimos said:
Why should an object be innately better as a shield simply because it "is a shield"? That's illogical.


No, that's rational. An object which was designed and crafted specifically to be a shield should do a much better job as a shield, than an object that was designed and crafted to allow a wagon to roll over terrain. Sorry, but that's common sense. Now, you could argue that your wagon wheel works quite well as a shield, but I suspect the typical wagon wheel has holes around the spokes, is much thicker than you'd really prefer as a shield strapped to your arm, and is not reinforced to survive blows to the side since it was designed to carry weight from the edge and center. Sure, you could enchant one…. but if you put that same enchantment on an actual properly designed shield, would the shield not logically be superior?

How about a real-world physics example. Let's suppose you are designing an airplane. You could make a flat rectangle of metal, or you could design an airfoil. They are both 100% identical in materials, weight, and pretty darn close in size. Yet the airfoil shape will work to keep your plane in the air, while the flat metal rectangle won't work very well at all.
14 Mar, 2012, plamzi wrote in the 15th comment:
Votes: 0
I agree with quix. It's not that you can't design a world in which no shield is a better shield than a wagon wheel. It's that if you do, it will be a tough sell, counter-intuitive to the real-world experience all your players will bring to the game. It can be a fun experiment to design a game that rewards MacGyver-type invention (and punishes banal solutions?) but you have to go all out and "twist" a lot more to create a consistent gameplay experience. And as you're twisting, I bet you'll realize that you've started de-abstracting properties again (e. g. you'd have to ignore the weight, bulk, and holes of a wagon wheel to make it perform better than a steel shield).

I understand the impetus for this entirely. Sometimes as enthusiasts we need to grapple with something unusual and cool. I just think that if you don't start out with a specific game-enhancing goal in mind, this may never transcend the "look at what my code can do" stage.

In my case, I've decided that players would be able to take something like a wagon wheel and be able to craft a shield out of it that would make it better at offering protection. May be dull, but it requires no suspension of disbelief. I'm also flagging certain attacks and items with abstract properties that can make them more effective when used against certain species of opponents. This is open enough to where some "emergent" strategies can happen, yet defined enough so that it can be 'discovered' fairly quickly and be consistently useful.
14 Mar, 2012, KaVir wrote in the 16th comment:
Votes: 0
plamzi said:
To take your example, if a player can pick up an old wagon wheel and use it as a shield, that's kind of cool, for about a minute. But if there's any better shield in the game (e. g., a shield) then picking up an old wagon wheel in a combat-driven game would be something only an ignorant under-equipped newbie would do (maybe it has some RP value, I can't speak to that).

The focus of my mud is combat (there is no RP), and much like the examples in this thread, you can use any object as a weapon.

Improvised weapons are rarely used intentionally, but they do get some use - a common example is a lit torch which, while not an ideal weapon, allows you to inflict heat damage. Other improvised weapons are tied to specialised fighting styles (such as duellists using their cloaks to deflect attacks), or are created during combat (such as tearing off someone's arm to use as an improvised club, or having the tip sliced off your spear, leaving you with just the shaft).

Then of course there's the insult factor - it's one thing to kill your opponent, but quite another to beat them to death with their own leg. Some players also like the challenge of using unusual weapons, and I've seen people defeat opponents using tools, clothing, rats, fish, broken bottles, etc. One player even earned their black sash fighting with a pair of socks. And I'll never forget the player who wielded a squirming infant naga in each hand, and beat the naga queen to death with her own children.

quixadhal said:
If you really want every object to be useable as every kind of thing (which is a very BAD idea, IMHO), have them all inherit everything. Then when you realize how silly it is for your human players to eat metal warhammers, and fight with chunks of meat, you can change your mind without having to retool the universe

Having actually implemented something very similar, and having received a lot of very positive feedback from many players over the last decade, I'm going to have to disagree completely with your view.

By the way, it's better to base eating on material type rather than item type. Nothing wrong with eating a chocolate warhammer, but you shouldn't be eating petrified bacon.
14 Mar, 2012, Deimos wrote in the 17th comment:
Votes: 0
@quix: I wasn't suggesting doing away with inheritance altogether, as you seem to be under the impression. I'm well aware of the benefits when used properly. I'm simply arguing that modeling item types, in particular, with inheritance leaves you with a much less flexible system (I've first hand experience with the limitations of this method, as my OP alluded to).

Also, not every thing will be usable as any other thing. I would never let players eat warhammers "just because." I would base the ability to eat a given thing on, say, the "edible" attribute. And warhammers would, of course, not have that attribute. But other things could, like roots, berries, and so on. KaVir's example of a chocolate warhammer was contrived, but a good one. Maybe there's a wizard in the forest that turns everything he sees into chocolate. In my proposed system, this would be a matter of toggling the "edible" attribute on said items, and possibly the materials. In an inheritance model, we would have to create all new objects of type EdibleTree, EdibleChair, EdibleBoot, and so on that all inherit from both their respective item types as well as type Food (if you even have MI available to you).

Of course, this is a bad example if your game bases eating solely on material, rather than item type, but you get the idea. Maybe a better example is having an item type of "light" vs. a "luminescent" attribute. In this system, I could light a tree branch on fire and use it as an impromptu torch. A tree branch is unlikely to be type "light" in any normal game, but if I give things lit on fire the "luminescent" attribute, now anything flammable in my game is a potential light source with no extra effort on my part.
14 Mar, 2012, Jimorie wrote in the 18th comment:
Votes: 0
I only skimmed through the thread, so I apologize in advance if I come off as ignorant.

Doing away with traditional method inheritance for the objects that populate your world can certainly be a successful design path to take. KaVir's MUD is one example of that, the Skotos games are another. The Skotos folks, true to their spirit, also wrote a number of articles on the subject, that may be worth checking out if you are interested:

http://www.skotos.net/articles/TTnT_20.h...
http://www.skotos.net/articles/TTnT_60.s...

quixadhal said:
If you stuff all that into a single "properties" object, you'll be constantly updating that object AND your game's data space will be bloated with tons of functions and variables that aren't used because you needed just one or two of them and had to include the whole thing.


Functions use the same amount of memory regardless of how many objects that inherit them, so that part of the argument should be void. As for the objects' global variables, you do have a point. However, there are several other strategies one could, and should, use for storing the data in this kind of system. For example, you could simply store each object's data in one dynamic data mapping, that would use no more data than what is used by that individual object. That would probably have other disadvantages, depending on your programming language, such as slightly slower data access and loss of type checking. The point is, there are other solutions, if you care to look for them.
14 Mar, 2012, Deimos wrote in the 19th comment:
Votes: 0
@Jimorie: Those were really interesting reads. Thank you. They followed my original thought processes very closely. Unfortunately, they don't address the issue that eventually soured my appetite for object type inheritance, which is what happens when items need to inherit from more than one parents across different branches in the tree?

Two scenarios exist:

1) You completely refactor large chunks of your tree when this happens, in order to group those parents into a common parent of the child. This only works if the regrouping makes sense, though. Which brings me to…

2) In the cases where regrouping does not make sense (see: previous example about lighting a tree branch on fire to use ot as a torch), you have to abstract the data/behaviors into some kind of 2nd dimensional inheritance (e.g. attributes).

If you go on long enough, #2 gets rather tedious after a while, and you start wondering if you ought to have just discarded formal type inheritance altogether in favor of a system that relies mostly on that 2nd dimensional inheritance. And that's where I'm at right now.
14 Mar, 2012, Runter wrote in the 20th comment:
Votes: 0
Quote
By the way, it's better to base eating on material type rather than item type. Nothing wrong with eating a chocolate warhammer, but you shouldn't be eating petrified bacon.


gg thread
0.0/65