• entries
    146
  • comments
    436
  • views
    197356

Interpreter, Part 2

Sign in to follow this  
Washu

114 views

The game we shall be imagining is an RPG of sorts, although the concepts apply almost anywhere. For the sake of discussion, we'll assume a variety of bits and pieces of code already exist, such as spatial partitioning, an entity relational manager, and anything else we find we need that would be considered game mechanics. The idea of this discussion is not to introduce and describe such concepts as spatial partitioning, but to instead describe a mechanism whereby we can build a highly extensible query mechanism.

Some concrete examples that we can initially analyze will be useful for our purposes. So, in order to facilitate an initial set of reasons for why we might want to implement a system such as I shall describe later on, we shall refer to the following examples:
  • "A nano-heal will heal all friendly grouped units within a small radius of the user."

  • "A nano-shield will absorb some fixed amount of damage dealt to any friendly grouped unit within a large radius of the user."

  • "An incendiary grenade damages all units within a large radius of its blast."


Obviously we should perhaps provide some sample of how they might be implemented initially; as such the following code should be useful:

public class NanoHealEffect : Effect {
static const float EffectRadius = 10.0f;
static const float HealAmount = 25.0f;

public override void ApplyEffect(Entity user, Scene s) {
List entities = s.SceneGraph.GetEntitiesWithinRadius(user.Position, NanoHealEffect.EffectRadius);

foreach (Entity entity in entities) {
if (entity.AllyState(user) == AllyState.Friendly && entity.IsLiving && entity.Group.Contains(user)) {
entity.Heal(HealAmount);
}
}
}
}

public class NanoShieldEffect : Effect, IDamagable {
static const float EffectRadius = 25.0f;
static const float StartingHealth = 15.0f;

public override void ApplyEffect(Entity user, Scene s) {
List entities = s.SceneGraph.GetEntitiesWithinRadius(user.Position, NanoShieldEffect.EffectRadius);

foreach (Entity entity in entities) {
if (entity.AllyState(user) == AllyState.Friendly && entity.IsLiving && entity.Group.Contains(user)) {
entity.AddEffect(this);
}
}
}

public void TakeDamage(float damageAmount) {
startingHealth -= damageAmount;

if(startingHealth <= 0) {
startingHealth = 0;
isLiving = false;
}
}

public bool IsLiving { get { return isLiving; } }

private float startingHealth = NanoShieldEffect.StartingHealth;
private bool isLiving = true;
}

public class IncendiaryGrenadeEffect : Effect {
static const float EffectRadius = 30.0f;
static const float DamageAmount = 25.0f;

public override void ApplyEffect(Entity grenade, Scene s) {
List entities = s.SceneGraph.GetEntitiesWithinRadius(grenade.Position, IncendiaryGrenadeEffect.EffectRadius);

foreach (Entity entity in entities) {
if (entity.IsLiving) {
entity.Damage(DamageAmount);
}
}
}
}



Now, obviously this code isn't exactly how you would actually implement it, but it will do for our purposes. Some things to note: For any sufficiently varied number of effects, the scene graph will have to support more and more complex methods of querying for entities. It would be nice if we could replace that with some other method of asking questions of the scene graph. Another point is that if you look at the Boolean logic, in many cases it appears to be duplicated, especially between the nano-heal and nano-shield effects, where they are almost identical.

Initially you would probably consider refactoring that duplication out of the two classes and then making them both have the same base class (perhaps GroupEffect). The problem with that is what happens when we come up with an effect with nearly identical logic, but just slightly different. These small amounts of duplication that keep cropping up could be dealt with in a variety of ways, many deal with increasing the depth of the inheritance hierarchy, something that isn't always desirable. Especially if you are dealing with a scripting language, as it may not have the ability to use inheritance, or might add additional overhead (along with increasing the required knowledge of the user, something which shouldn't be necessary).
Sign in to follow this  


2 Comments


Recommended Comments

I'm shaking in my pants waiting for the awesome solution to this ever present problem! I really hate how you leave us hanging here :(

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now