6
\$\begingroup\$

I'm drafting my game and implementing small stuff in it, but hit a roadblock. You see, for my game I would like for different items to behave the same or to share behavior, for instance, some items can be picked up and dropped to the floor, some items can get damaged and be repair while some only can get damage (the player cannot repair the item), some items can be use for a variety of different purposes (fire arms as weapons, frying pan as cooking tool and as a weapon), some items can get wet while others can get wet, catch fire and spread it further (or not; this is a reference to systemic games) and so on.

In my mind, the behavior must exist in the object and be abstracted from the player/AI/Other items nevertheless I'm lacking experience on how to go about this and I think that beside implementing a behavior there must exist also code that knows how to interact with such behavior, but this approach feels odd IMHO. In any case, I was asking around and The Sims was thrown in a reply, searching on the web found Living with The Sims’ AI: 21 Tricks to Adopt for Your Game, the trick 5 reads:

Each object has a public interface that broadcasts its functionality to actors in the game. This is called advertising data in The Sims, and contains a list of possible actions and what motives they satisfy.

If reading this correctly, it means that "smart objects" have a standard interface that actors can access to, right? My guess is that this interface covers everything behavior/systemic-wise that could happen in the game and the "actors" have code implemented that allow them to make use of this advertised interface, right?

\$\endgroup\$
6
  • 1
    \$\begingroup\$ but this approach feels odd IMHO — well, how do you expect a behavior to ever be triggered, if not by something that knows how to trigger it? \$\endgroup\$ – Shadows In Rain Jun 3 at 7:31
  • 2
    \$\begingroup\$ Up until the smart object passage from The Sims, most of what you described sounds like conventional component-based approaches. Smart objects can be an interface layer between that composition-based behaviour and an AI agent seeking to fulfill a goal. It's not clear to me which of these you need help with - the underlying components of object behaviour, or the smart object broadcasting system to inform AI planning. \$\endgroup\$ – DMGregory Jun 3 at 12:06
  • 1
    \$\begingroup\$ Might you be looking for this? en.wikipedia.org/wiki/Entity_component_system \$\endgroup\$ – Guillem Vicens Jun 3 at 16:32
  • 2
    \$\begingroup\$ In that case I'd recommend asking one question at a time. Pick one to ask about first. Then you can post a second question asking about the other. That lets answers focus on giving you in-depth help with each aspect, rather than spreading themselves thin trying to cover multiple separate topics. \$\endgroup\$ – DMGregory Jun 3 at 18:34
  • 1
    \$\begingroup\$ It appears to me that you want a component based solution. And there are a few already available for Godot. What I haven't seen is one that looks like Unity. I went made a Q&A for that: How to make a component solution in Godot (In the question I also link the other solutions I'm aware of). Hopefully that is most of the first half of your question. You may also be interested in What are the basics of implementing a Goal Oriented AI? for the second half of your question. \$\endgroup\$ – Theraot Jun 4 at 15:04
3
\$\begingroup\$

Well, concerning "The Sims" article you are reffering to that actually could mean a lot of different things. But the core idea as I get it is that each object can expose a list of "functions" that can be applied to it. For example

item : ["destroy", "pick up", "eat", "cook"]

and then the actor decides it can be processed with:

item.pickUp(actor)

or

actor.pickUp(item)

or something else, depending on details of implementation.

So imaging the actor clicks on the item and basically sees this list of possible interactions. Each action is binded to specific code for processing and accepts the actor as argument.

The "broadcast" mentioned in the article means, as far I understand, that item are proactively inform actors about their features so they can move to them and interact if necessary.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ The Sims agents used goal oriented planning to satisfy their needs. To do that, the objects "advertise" that they can satisfy some need if the agent use them (e.g. a shower offers to satisfy a hygiene need). That is what the "broadcast" part is about. \$\endgroup\$ – Theraot Jun 3 at 11:12
  • 1
    \$\begingroup\$ Given the sheer number of verbs which The Sims supports, and the need for actions to be scheduled to take place in a sequence, I would be quite surprised if it did not use some variation of the command pattern internally. \$\endgroup\$ – Kevin Jun 3 at 17:39
2
\$\begingroup\$

With strong typed languages, you can create this functionality broadcast in public interfaces by the way of interfaces. Say:

interface IDamageSource
{
    DamagePoints Damage { get; }
    void Consume( DamagePoints points );
}

interface IDamageTarget
{
   void TakeDamage( DamageSource source );
}

interface IFixTarget
{
    FixMaterial[] FixCost();
    void FixApply( FixMaterial[] materials );
}

class Tool implements IDamageSource, IDamageTarget, IFixTarget {}
class Rock implements IDamageSource, IDamageTarget {}

class DamageEffect
{
    public InterfaceUpdates DoDamage( IDamageSource source , IDamageTarget target )
    {
        // Common logic, return any visual effects to later GUI render
    }
}

So in this example, a Rock can cause damage and can be damaged but not restored, and a Tool can cause damage, be damaged and be fixed with some cost. Any specifics is handled in each object implementation of interface, and the common logic is handled in DamageEffect.

When the user points to a object in screen, then you can "ask" to object:

// Can damage?

user.AttackAction.Enabled = user.SelectedObject is IDamageTarget;

// Can fix?

var fixable = user.SelectedObject as IFixTarget;
if ( fixable == null )
    user.FixAction.Status = UserFixActionEnum.NotFixable;
else
    if ( this.HasEnoughMaterials( fixable.FixCost() ) )
        user.FixAction.Status = UserFixActionEnum.Fixable;
    else
        user.FixAction.Status = UserFixActionEnum.MissingMaterials;

This could be realized by all "in game" objects having a common standard interface, but this is the way of one big class with tons of unrelated functionality, and that is a bad design that leads to very bad code later on.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.