Advertisement

Moddability : Use of pre-defined parameters, or script ?

Started by July 28, 2011 03:24 PM
5 comments, last by wodinoneeye 13 years, 3 months ago
Hi there :)

I've been working on the design of an open (moddable) role-playing environment for a while, now.

As far as moddability is concerned, I'm still reluctant to use scripts, and I'm holding the hope of being able to provide an enclosed design for modders, based on hard-coded classes exposing a few parameters only (I know, this may be counter-intuitive).

For example, to add a new ability, we could choose among a few set of generic types of events (e.g. this is a character-action, more specifically a spell...) and tweak some pre-defined moddable parameters based on the event type.

Let's say we want to add a shiny new healing spell, these could be :

- Interface (Ability Icon ; Default shortcut ; Target-based or ground-based cast-type...)
- Effect (type = healing [instant/over time]; healing efficiency ; range ; area of effect )
- Requirments (casting time ; required tool or alchemic component ; manna or other source consumption )
- Name of Graphical & sound effects data on preparation, casting and landing.
- Other Stuff (restriction or alterations based on nature of target... ; spell interruptability...)

Additionnaly, in the best-case scenario in which I have plenty of free time, I could imagine a lightweight home-made parser, which would make the following (silly) statements possible :
[font="Courier New"]Creature.MyCustomVar = Creature.Size * 20
...
ShinyNewHealingSpell.Range = Caster.MyCustomVar + 10
[/font]
Now, why is this reflexion in the AI section ? Well, I'm wondering if this could match well with an AI system based on utility theory, as Dave presented it.

i.e. casting our ShinyNewSpell could be categorized, AI-wise, in the "healing spell" action choice, using suitable considerations based on casting requirments, healing efficiency, urgency to heal...
Similarily, the world agents would be described in such a way that they could feed each other's decision process : appearance parameters and such to compute good feelings or threat considerations, courage and playfulness parameters to compute fleeing, or fighting, or playing around appraisals, etc.
A few binary-parameters, at the modder's discretion, could also describe a creature's mind in the form "I'm a wild animal", which adds the hard-coded consideration that "I don't care about world politics...", to take a silly example again.

Could a world filled with lots of NPC-creatures work well with this kind of hard-coded tweakable parameters (provided a "lil" bit of work), or do you think this would be either too cumbersome to code, or not moddable enough ? If you had to do this, would you rather use LUA scripts extensively for modded events/agents/actions definitions as well as associated AI behaviors ? Or would you do this in a way I didnt imagine ?

Thanks in advance :)

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

I think if you're careful and design your parameter set nicely up front, you can get plenty of flexibility without the (perhaps excessive) freedom of full scripting.

You can also easily attach utility values to each spell/item/etc. and have different "filters" for them - Utility for Defense, Utility for Offense, etc. Then defensively-minded characters can prefer stuff with a high utility for defense, and vice versa.


So yeah, sounds like a decent approach to me.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement

You can also easily attach utility values to each spell/item/etc. and have different "filters" for them - Utility for Defense, Utility for Offense, etc. Then defensively-minded characters can prefer stuff with a high utility for defense, and vice versa.

I like that idea

thanks for your reply :)

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

All of the openly mod-able stuff has been based primarily on data. That way, as you drop a new unit into a game, the game code already knows how and when to use it. Civ 4, for example, had almost nothing hard-coded. It would all be pulled in from data files. If you tweaked the data, the game played considerably differently. You can even include other things in your data, of course... graphics, sound, etc. Data-driven is the way to go.

("I'm Dave Mark and I approve of this thread.")

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit
Author of the book, Behavioral Mathematics for Game AI
Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"


All of the openly mod-able stuff has been based primarily on data. That way, as you drop a new unit into a game, the game code already knows how and when to use it. Civ 4, for example, had almost nothing hard-coded. It would all be pulled in from data files. If you tweaked the data, the game played considerably differently. You can even include other things in your data, of course... graphics, sound, etc. Data-driven is the way to go.


Hi Dave, thanks for coming by.

I'm not totally new to the concept of data-driven, as I once worked in the industry on a network architecture using DDS... Yet...
Yet, when I think further about it, I'm still quite unsure of what to call data-driven... this could maybe result from the fact that when one says "data-driven", there is no real indication as to "how much" it should be [driven by data]. The answer can indeed never be "totally", since data has to meet code at some point.

Here are a few ideas I can come up with

1. Numerical tweaks only :[spoiler]


ShinyNewSpell.ini
range=150
damage=20
cost=5
graphEffect="ShinyNewspell.gfx"



Spell.hh
class Spell {
...
int _range;
int _cost;
int _damage;
GraphicalEffect _castEffect;
...
static Spell* fromIniFile(const char* szFileName);
ECastResult cast(Creature& caster, Creature& target) const;
};



Spell.cc
ECastResult Spell::cast(Creature& caster, Creature& target) const {

if (GameWorld::distance(caster, target) > _range)
return ECR_TOOFARAWAY;
if (caster.getManna() < _cost)
return ECR_LOWMANNA;

caster.spendManna(_cost);
Graphics::draw(_castEffect);
target.receiveDamage(_damage);

return ECR_SUCCESS;
}
[/spoiler]

2. Any number of parameters :[spoiler]


ShinyNewSpell.xml
<spell name="ShinyNewSpell">
<range>150</range>
<cost source="manna">
<value>5</value>
</cost>
<effect type="damage">
<value>20</value>
</effect>
<graphics>
<OnCast gfx="ShinyNewspell.gfx"/>
</graphics>
</spell>



Spell.hh
class SpellParam {
virtual ECastResult checkCondition(Creature& caster, Creature& target) const = 0;
virtual void applyEffect(Creature& caster, Creature& target) const = 0;
};
typedef List<SpellParam> SpellParamList;

class RangeParam : public SpellParam { ... };
class CostParam : public SpellParam { ... };
class EffectParam : public SpellParam { ... };
class GraphicsParam : public SpellParam { ... };

class Spell {

...
SpellParamList _paramList;
...

static Spell* fromXmlNode(const XmlNode& node);
void cast(Creature& caster, Creature& target) const;
};



Spell.cc
ECastResult Spell::cast(Creature& caster, Creature& target) const {

FOREACH(SpellParam, param, _paramList) {
ECastResult r = param.checkCondition(caster, target);
if (r != ECR_SUCCESS) return r;
}

FOREACH(SpellParam, param, _paramList) {
param.applyEffect(caster, target);
}

return ECR_SUCCESS;
}
[/spoiler]

3. Full Script :[spoiler]


ShinyNewSpell.lua
function castShinyNewSpell(caster, target)

if (distance(caster, target) > 150) then
return TOOFARAWAY;
end
if (caster.manna < 5) then
return LOWMANNA;
end

caster.manna = caster.manna - 5;
drawShinyNewGfx();
damageCreature(target, 20);

return SUCCESS;
end
[/spoiler]

I believe the more we approach the limit of the fully-data-driven thing, the more i'll have to resort on a script language & parser, either LUA or home-made.

I guess the second solution would be the most elegant... and suited for utility-theory params and considerations, but could you tell me which one would be the closest to what 'you' have in mind ?

Thanks for the civ4 example, I'll try to find some info on how they did things (I've played it a lot but never went into modding it).

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/



Hi Dave, thanks for coming by.

Meh... figured a moderator should swing by his domain once in a while. I'm in San Diego this weekend, though, so I can't do too much... I'll have to let others comb through your code.


Thanks for the civ4 example, I'll try to find some info on how they did things (I've played it a lot but never went into modding it).
[/quote]
You can actually download all the Civ4 code from somewhere. The link I have is broken. See if you can poke around and find it somewhere.


Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit
Author of the book, Behavioral Mathematics for Game AI
Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

Advertisement

Hi there :)

I've been working on the design of an open (moddable) role-playing environment for a while, now.

As far as moddability is concerned, I'm still reluctant to use scripts, and I'm holding the hope of being able to provide an enclosed design for modders, based on hard-coded classes exposing a few parameters only (I know, this may be counter-intuitive).

For example, to add a new ability, we could choose among a few set of generic types of events (e.g. this is a character-action, more specifically a spell...) and tweak some pre-defined moddable parameters based on the event type.

Let's say we want to add a shiny new healing spell, these could be :

- Interface (Ability Icon ; Default shortcut ; Target-based or ground-based cast-type...)
- Effect (type = healing [instant/over time]; healing efficiency ; range ; area of effect )
- Requirments (casting time ; required tool or alchemic component ; manna or other source consumption )
- Name of Graphical & sound effects data on preparation, casting and landing.
- Other Stuff (restriction or alterations based on nature of target... ; spell interruptability...)

Additionnaly, in the best-case scenario in which I have plenty of free time, I could imagine a lightweight home-made parser, which would make the following (silly) statements possible :
[font="Courier New"]Creature.MyCustomVar = Creature.Size * 20
...
ShinyNewHealingSpell.Range = Caster.MyCustomVar + 10
[/font]
Now, why is this reflexion in the AI section ? Well, I'm wondering if this could match well with an AI system based on utility theory, as Dave presented it.

i.e. casting our ShinyNewSpell could be categorized, AI-wise, in the "healing spell" action choice, using suitable considerations based on casting requirments, healing efficiency, urgency to heal...
Similarily, the world agents would be described in such a way that they could feed each other's decision process : appearance parameters and such to compute good feelings or threat considerations, courage and playfulness parameters to compute fleeing, or fighting, or playing around appraisals, etc.
A few binary-parameters, at the modder's discretion, could also describe a creature's mind in the form "I'm a wild animal", which adds the hard-coded consideration that "I don't care about world politics...", to take a silly example again.

Could a world filled with lots of NPC-creatures work well with this kind of hard-coded tweakable parameters (provided a "lil" bit of work), or do you think this would be either too cumbersome to code, or not moddable enough ? If you had to do this, would you rather use LUA scripts extensively for modded events/agents/actions definitions as well as associated AI behaviors ? Or would you do this in a way I didnt imagine ?

Thanks in advance :)




It depends how many special cases you game mechanics allow.
Without specific scripting, you would have to have enabling flags for every special logic hanfdling of evey special case for every factor.
That special case logic would have to be precanned and flags set yea or nay (or maybe a coefficient) for every one of them in yout object type defining data.
That can be OK as long as the complexity doesnt get to rediculous and youy can forseee all/most of the exceptions.

Scripting can be more flexible because often simple if-then-else logic can customize what/how you want that object to behave to a very high/convoluted degree if needed.

Of course the fun is that a 'code chunk' often has to be seperate from the static data component and that make for more work.
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement