News for hackers. Stuff that matters.
Re:How I Learned to Stop Worrying and Love the State Machine by badsectoracula on Monday February 26, 2018 @08:29PM (#16470462)
The first four articles are interesting and i was following along, but i am not buying the last solution - it is way too complicated and over-engineered. It is telling that unlike the other four articles, the last one has no implementation code.

What i would do is simply have Item (base for Weapon, Potion, etc) have a "IsUsableBy(Player p)" which returns true in the default implementation (which would be the case for the majority of items) and the objects that have special considerations check the player class themselves.

Similarly an Animal (or Entity or Organism or whatever) class would have a "OnDamage(Animal source, int damage)" that by default calls -say- "ApplyDamage(int damage)", but special animals - like the werewolves - may want to filter the result so that the damage is doubled when they are on holy ground or when the class of source is Paladin.

Also the IsUsableBy and OnDamage functions could check against Item objects in an inventory (e.g. Item could also provide a "FilterDamage" and "VetoUsageOf" so that an HolyCross can multiply all damage from Undead enemies by 0.25 but veto using any UnholyItem based class - truth be told here, you probably need a tag system for some of that stuff instead of relying on classes alone) and on an active Effect list (would also be able to do the same sort of vetoing and filtering and the Animal class could also provide a HasEffect method for use by the other classes to make decisions about - e.g. a PaperDoll might refuse to talk to you if you have the OnFireEffect :-P).

To me that sort of setup feels more natural and intuitive than the user-command-state-rule stuff mentioned in the article. You can't really generalize it in a way that applies to other things (e.g. a MagicSpell would need its own set of functions and such) but i believe that there is a thing as too much generalization.

(note that the above are when talking about the common Java/C++/C#/etc like OOP languages, in something like C i'd go with a more data and/or script driven approach...)

Re:How I Learned to Stop Worrying and Love the State Machine by psyc on Monday February 26, 2018 @11:32PM (#16471093)
I agree with you up to a point, and that point is when the game becomes "large" in the number of rules and entity varieties. Eric is approaching this very much like a compiler developer. We always have the option of 'lofting' concepts out of the code and into types. E.g. we usually start by writing:

  int a = 1;
  int b = 1;
  int c = a + b;
And we have the option of writing, alternatively:

  class Integer { ... }
  class Operation { ... }
  class Expression { ... }
Or something 'meta' like that. The upside is that it's flexible, powerful, expressive to turn code into data. The downside is that it's slower, and there's a whole extra system to maintain.

However, in my experience as a game developer, past a certain large size, pretty much all systems seem to want to converge to Lippert's solution. You want to be able to put the entity data and the rules into tables, and not have to edit code to change the game rules. For small games, not worth it. But for large games, and also for game engines that aspire to be generic, it makes everything a lot easier.

Re:How I Learned to Stop Worrying and Love the State Machine by badsectoracula on Tuesday February 27, 2018 @07:45AM (#16472891)
I wanted to stick with the language side this that is what the original article was about. But yes, in large games you wouldn't do all that stuff in C#/C++/etc, you'll most likely use a data driven approach. However this can still be put at the gameplay side of the engine to provide the base. For example if you look at the mod tools for RPG engines like Aurora, Creation Kit and REDEngine you'll see that they have inherent knowledge about base item types like armor, monster, etc, but they rely on data for the specific items (and scripts for the exceptional behavior). The easiest to see that is with the Creation Kit based games like Skyrim since it gives you a nice GUI to create/edit each different item type.
Re:How I Learned to Stop Worrying and Love the State Machine by professor_plum on Tuesday February 27, 2018 @11:01AM (#16474598)
Thanks for helping to qualify when the proposed solution starts to become appropriate. I'd still really need a solid example of when this starts to be beneficial. Could anyone oblige?
Re:How I Learned to Stop Worrying and Love the State Machine by a_t48 on Monday February 26, 2018 @09:22PM (#16470657)
This is all about composition over inheritance. What if I want a sword that has a flask built in? How do I reconcile the fact that Potion and Weapon are two different branches of the inheritance tree? His points about pushing things out to a data file are also very valid.

Granted, the author may have taken it a little far, but the sentiment is right.

Re:How I Learned to Stop Worrying and Love the State Machine by badsectoracula on Tuesday February 27, 2018 @07:13AM (#16472756)
What you describe is a very special and exceptional case to have it affect everything else. Personally what i would do in such a case is to have the Weapon object own a WeaponFlask object and when the weapon is added/removed to the player's inventory it automatically adds/removes the WeaponFlask object too and the WeaponFlask itself can veto being removed from the inventory. You'd need to add extra events for that, but assuming we're talking about an RPG style game, you most likely will have functionality for stuff like that anyway for other items (e.g. cursed items that cannot be removed, enchanted items that apply/remove an Effect when they are added/removed from the inventory or the player wears them, etc).
Re:How I Learned to Stop Worrying and Love the State Machine by a_t48 on Tuesday February 27, 2018 @03:43PM (#16477683)
That's one special case, but eventually you end up with a few dozen special cases.
Re:How I Learned to Stop Worrying and Love the State Machine by taneq on Tuesday February 27, 2018 @02:39AM (#16471722)
I'd do something similar for the item types, although instead of a floating IsUsableBy() I'd make it a member of the Player (or probably Creature, with Player deriving from Creature) so you could go player->CanEquip(item).

I also think trying to squeegee it into the language's type system is the wrong approach (for this specific problem, I mean - I'm not saying there aren't cases where doing it in the language is useful) purely because we're going to want the art team to add more monster types and player types, and to be able to change the rules for attacks and damage and soforth quickly on the fly to try out new game mechanics. We're going to want it all in data very soon, so it'd be better to just jump straight to a data-driven design.

Re:How I Learned to Stop Worrying and Love the State Machine by badsectoracula on Tuesday February 27, 2018 @07:23AM (#16472800)
I think either way is fine, the main reason i placed the check to the item is that it is usually an item attribute (e.g. daggers are usuable by warriors, thieves and wizards, staves are usable by wizards and monks, swords are usable by warriors and thieves, etc).

Generally if you see mod tools for existing games (e.g. Skyrim) you'll see that the engine does have inherent support for the base classes (Weapon, Armor, etc) but it relies on data for the specific items, so what i describe above can be the engine (gameplay code) side of that.

Re:How I Learned to Stop Worrying and Love the State Machine by dnomad on Tuesday February 27, 2018 @09:05AM (#16473393)
This is on the right track. You actually sort of need both but it's important to get the language right.

Objects, particularly highly sophisticated objects, generally have minimal requirements that determine who can use them successfully. Requirements can be anything from strength to knowledge. At the same time people have skills (or don't have skills) and attributes which lets them use objects. Some people are more skilled than others.

Modelling this requires both the ability to ask an object "What are the minimal requirements needed for somebody to use you?" and the ability to ask a player "How skilled are you really at using this object?"

As a smell test, it doesn't make much sense to ask a sword "can I use you?" How would the sword know? But you can ask the sword, say, "how heavy are you?" It does make some sense to ask a person "can you use this sword?"

And yes, it's not clear at all that every object type corresponds to a first-class language type. You might have a Sword type... but in reality, unless the game is very sophisticated, all bladed weapons do pretty much the same thing. This is where it's useful to take a step back and focus not so much on nouns but also on verbs in our domain language. Swords, axes, ninja stars -- they are all cutting damage. Spears, knifes, polearms -- they are all stabbing damage.

Re:How I Learned to Stop Worrying and Love the State Machine by nybble41 on Tuesday February 27, 2018 @12:06PM (#16475422)
It does make some sense to ask a person "can you use this sword?"

Does it really? I mean, if we're talking about an actual person then sure, since a person can think about the problem and come up with a creative answer. But the object representing a person in a game? That would imply that the "person" object must know all about swords and the requirements for using each of them. How is that better than requiring the "sword" object to know about people and their capabilities?

Swords have attributes (e.g. weight). People have attributes (e.g. strength). Whether a particular person can wield a particular sword is not a question either a sword or a person can answer without introducing unnatural dependencies. It is a property of the environment in which the player and sword both exist, and IMHO is best modelled as some form of external "rule" object, or via a multiple-dispatch method (if your language supports that paradigm).