7
\$\begingroup\$

Reading several other questions and answers on using a component based system to define items I want to use one for the items and spells in a web game written in PHP. I'm just stuck on the implementation.

I'm going to use a DB schema suggested in this series (part 5 describes the schema);
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

This means I'll have an items table with generic item properties, a table listing all of the components for an item and finally records in each component table used to make up the item.

Assuming I can select the first two together in a single query, I'm still going to do N queries for each component type. I'm kind of fine with this because I can cache the data into memcache and check there first before doing any queries. I'll need to build up the items on every request they are used in so the implementation needs to be on the lean side even if they're pulled from memcache.

But right there is where I feel confident about implementing a component system for my items ends. I figure I'd need to bring attributes and behaviors into the container from each component it uses. I'm just not sure how to do that effectively and not end up writing a lot of specialized code to deal with each component.

For example an AttackComponent might need to know how to filter targets inside of a battle context and also maybe provide an attack behavior. That same item might also have a UsableComponent which allows the item to be used and apply some effect onto a different set of targets filtered differently from the same battle context. Then not every part of an item is an active part, an AttributeBonusComponent might need to only kick in when the item is in an equipped state or when displaying the item details page.

Ultimately, how should I bring all of the components together into the container so when I use an item as a weapon I get the correct list of targets? Know when a weapon can also be used as an item? Or to apply the bonuses the item provides to a character object?

I feel like I've gone too far down the rabbit hole and I can't grasp onto the simple solution in front of me. (If that makes any sense at all.)

Likewise if I were to implement the best answer from here I feel like I'd have a lot of the same questions.
How to model multiple "uses" (e.g. weapon) for usable-inventory/object/items (e.g. katana) within a relational database

\$\endgroup\$

6 Answers 6

4
\$\begingroup\$

It looks like you are using relational modeling. There is an alternative method: property/prototype modeling, which Steve Yegge used to create his "ultimate extensible" MMORPG, Wyvern. Basically, each game object is stored as a single blob (only one query per object) which is then parsed into a property list after retrieval. The flexibility of property lists allows different game objects to have different sets of properties as needed.

Yegge's The Universal Design Pattern goes into depth about property/prototype modeling. Steve's blog posts tend to be quite long, so I will try to point you to the relevant sections and summarize the points relevant to your question:

  1. Wyvern uses an implementation of the Properties Pattern. A game object is basically a bag of arbitrary properties. Any object to can serve as the prototype for any other object, resulting in amazing open-ended flexibility.
  2. Persisting property lists. There are various methods of serializing and saving property lists. Wyvern uses a database, "shoving the XML-serialized property list into a text/clob column, and denormalizing the twenty or thirty fields ... needed for queries into their own columns."
  3. The datastore of property lists now needs a method of making queries on them. Steve makes several suggestions. Simple text-based queries don't work well for hierarchical data. XML databases or JavaScript/JSON + jQuery might be answers to this problem.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I almost stopped reading when you suggest a blob and thought your answer was going to suggest MongoDB or some other NoSQL solution. Instead it offers a different direction than components. Sure, this approach might work better in in NoSQL but there is a lot more here than just a 'use NoSQL' answer. \$\endgroup\$ Commented Feb 4, 2011 at 16:36
4
\$\begingroup\$

I would implement a hook system (a mechanism by which callbacks to specifiable functions can be added to and removed from an object when events occur) on the container, and have components set up the appropriate hooks when added and tear them down when removed. For instance, the AttributeBonusComponent might use atEquip and atUnequip hooks to add and remove its bonus, the AttackComponent could provide values to pollForTargets and pollForAttackBehaviors hooks, and the UsableComponent could talk to pollForUseBehaviors.

So the container winds up only having an abstract understanding of the kinds of information that can be requested of it and ways it can be interacted with, and the components are responsible for defining how they interface with those.

\$\endgroup\$
2
\$\begingroup\$

It sounds like you're missing the point of this kind of entity system. If you're "loading all components every time" then you'll get almost no benefit out of it.

You should be setting it up so that all the data needed for a particular class of operation (e.g. for "resolving attacks") is bundled into a single component.

Essentially, imagaine that you have to write the main code for some part of your game, complete with the main special cases, and you want to specify which data it needs from the start of that code to the end. That's one component (you could split it into smaller components, but only if you need to because some parts are (re)used later by other code).

Then, when you have special cases, you have the choice to edit your main component (generally: don't) or to invent extra components that allow all the existing entities to keep working, and all the existing code to keep working, unchanged.

\$\endgroup\$
1
  • \$\begingroup\$ I don't pretend to understand the component system. Part of my confusion is trying to use it in a stateless environment and I am still thinking/building the connection between say the physics, render, and input components often mentioned in articles into parts of a framework or script. \$\endgroup\$ Commented Feb 10, 2011 at 16:20
1
\$\begingroup\$

Remember the rules for optimization!

  1. Don't.
  2. Don't Yet (for experts only).

For example an AttackComponent might need to know how to filter targets inside of a battle context and also maybe provide an attack behavior. That same item might also have a UsableComponent which allows the item to be used and apply some effect onto a different set of targets filtered differently from the same battle context. Then not every part of an item is an active part, an AttributeBonusComponent might need to only kick in when the item is in an equipped state or when displaying the item details page.

Is it really a problem if you load all the components (AttackComponent, UsableComponent, AttributeBonusComponent) even if all but one go unused?

\$\endgroup\$
1
  • \$\begingroup\$ I should have been more clear. I intend to load all components every time I need the item. The attribute modifiers aren't active parts like having the item return a list of targets when given some data but instead just apply some numbers when the item is equipped. Of course I might be thinking of that all wrong as well. \$\endgroup\$ Commented Feb 4, 2011 at 16:00
1
\$\begingroup\$

"I feel like I've gone too far down the rabbit hole"

Yes, exactly. Component-based systems are still in the 'fad' phase where there is no agreement on how best to use them. Several knowledgeable and competent people have posted articles suggesting their use, but each tends to disagree over how you assemble them, how they communicate, and so on.

My personal opinion is that the relational model you've linked to is far too abstract for everyday use.

Instead, I would look more closely at your own design and see which common aspects of functionality can be factored out to form interchangeable components. That will probably be much more fruitful than trying to wedge your game into a preconceived notion of what components should be.

\$\endgroup\$
2
  • \$\begingroup\$ I'd agree that there is a lack of agreement which style of implementation is more advantageous than the next, but given the number of highly successful engines using component systems I'd hardly describe it as a "Fad". \$\endgroup\$
    – Kynth
    Commented Mar 11, 2011 at 16:18
  • \$\begingroup\$ There really aren't that many engines using such systems, certainly not enough to justify the amount of people who are interested in making them. (The only one I can think of right now is Unity.) That's not a criticism of the approach at all, just a reflection on the disproportionate interest in this topic at the moment relative to the amount of working software that actually uses it. \$\endgroup\$
    – Kylotan
    Commented Mar 11, 2011 at 20:40
0
\$\begingroup\$

As I understand the referenced series of articles on Entity Systems, your "item" is loaded with components. And a Component is a list of references. Following through with your example: AttackComponent will include references to how the "item" attacks; the AttackTargetComponent will include references to mechanisms to get list of targets; and so on. Therefore when your "item" attacks a target or targets - it is uses the AttackComponent and the AttackTargetComponent or triggers an external method based on the item (and its components) Thanks for sharing these articles.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .