Designing game rules around tags

WildWeazel

Going Dutch
Joined
Jul 14, 2003
Messages
7,526
Location
/mnt/games/Civ3/Conquests/Scenarios
This is a big, far-reaching topic that I've had on my mind for about 4 years now. It could impact how we implement many features in code as well as what mod content looks like. This is NOT a fully fleshed out system, but a collection of loosely integrated ideas. I'm sure I am overlooking things, so please look at this analytically and think through the implications.

Tags

A "tag" is simply an arbitrary string (text) associated with an item. Tags are often used as keywords or topics to search, filter, or match related items. If you've used a bookmark manager, CMS, or certain social media (#hastags) you're probably familiar with them. In fact, this thread has some!

In our case, tags would be used as criteria to match items to apply certain rules. An "item" here could be just about any noun: object, type, "thing" in the game. The Warrior unit, as well as *this* particular Warrior unit. Individual cities, and city sizes. And so on. Tags could be part of the definition of a thing in the rules (all Horseman units come with the "mounted" tag) which are automatically inherited by instances of the thing, or they could be applied to a specific thing in-game as a result of some rule (*this* Horseman spawned a military leader and got the "created-leader" tag).

The tags themselves do not inherently mean anything, do anything, or come from some list of allowable tags. They are just strings that can be matched. They don't need to be meaningful or even human-readable, though more specific and self-explanatory tags are better for posterity. If your cat walks across the keyboard while you're editing techs and gives Bronze Working the "wdbyjj.[" tag, nothing happens provided you don't have any special rules that check for "wdbyjj.[".

Matching Tags

The power of tags comes in the ability to search for them. With a system that allows you to apply arbitrary tags to things, and then create rules and conditions that match arbitrary tags, you can define much more complex and elegant behavior than you could hope for by hard-coding specific rules. This not only gives much greater flexibility for deciding how requirements are met, but opens up new types of relationships that were not previously possible: you might have a tech that can only be researched when a resource is available, or a tile improvement limited to a government.

Civ3 rules are limited by the arbitrary available options: a given thing (eg, a city improvement) has fixed abilities or applicability (eg, only happiness effects can be doubled) and in most cases the number and types of things it can require are fixed (eg, buildings can require one tech, a government, and/or up to 4 resources). There are a handful of exceptions mostly in the form of technologies unlocking new abilities (eg, precision strikes, irrigation without fresh water), but those cases are again arbitrarily limited to specific pre-defined fields. You can't for example make amphibious attacks or defensive bombardment abilities require a tech, and even if you could, that wouldn't scale well. Are we going to make a new field for each possible combination of actions and requirements? Every such case would require new code and data fields.

Using user-defined tags on the other hand provides nearly unlimited options compared to explicitly defining data fields, provided that the infrastructure is there to interpret the tags.

For example, look at the units tab of the Civ3 editor, which closely reflects how the data is defined in the BIQ. A unit type can have any set of units in its stealth attack targets. That's fine, but there are (units^2) number of possibilities here and it can be very tedious to update this list for each unit with stealth attack as you define new units. Imagine that you have a unit, that for whatever reason can stealth attack any mounted units. Instead of maintaining this target list, you could instead define a rule that the unit's stealth attack will match (or require, in this case) the "mounted" tag on the target. Now, whenever you add a unit with the "mounted" tag, it's a valid stealth attack target. This would even apply to any units that you import to this mod, assuming the source also used the "mounted" tag: remember the tag is just an aribtrary string, so it does not need to be defined in any central place. Of course, you may later decide that you do not want ALL "mounted" units to be targets, so in that case it may be better to use more specific tags for each rule rather than overloading them with multiple purposes. The point is that it's up to the modder to decide what tags to use and how, rather than the game rules providing a fixed number of properties to work with.

Scoping tags

It's not enough to say "must have X" if you don't know if X is a tech, a building in a city, a property of the unit itself, or any of the above. Scopes are a way to tell the game where to search for a tag, or put another way, limit where a tag applies.

Scopes on which a tag can be matched, in expanding order:
  • SELF: the object looking for the tag (this unit, this building)
  • TILE: the actual map tile, including its fixed characteristics (terrain, overlays, improvements, ownership)
  • LOCATION: the tile itself AND anything else on the tile (the unit stack, the city itself)
  • CITY: the actual city and its contents (buildings, citizens)
  • ADJACENT: the tile AND all adjacent tiles
  • RADIUS: the city itself AND all tiles within its workable radius that are claimed (perhaps this scope will only applicable for things belonging to a city)
  • LANDMASS: all contiguous land tiles?
  • CIV: properties of the whole empire (known techs, owned wonders, civ traits)
  • GAME: essentially "global" variables relating to the game settings, loaded mods, singleton flags (map size, nuclear weapons unlocked)

It may also be necessary to flip this around and have objects apply their tags on a scope or even a more specific range. This might allow more specialized effects to be tag-driven, such as the radio tower applying the combat bonus to all tiles within a range. That then raises the question of how to store such tags, as you cannot necessarily know what objects' tags to check based on the scope.

In any case, we can standardize how object types are scoped: civs, traits, techs, resources, buildings, etc are each checked when matching on specific scopes, ie each scope looks at certain types or places.

Combining tags with rules

Again, tags themselves don't actually do anything. They're just arbitrary intert data that can be attached to game objects. We need to define tag-based rules and conditions so that tags can drive behavior.

Many of the checkboxes, radio buttons, and multi-select menus from the rules editor could be replaced with tags on things, and corresponding rules that know to apply an effect or allow an action (only) with the presence of a certain tag. I'm handwaving away what this would look like in terms of code. It's probably not the best way to implement all behaviors, but it certainly provides more flexibility to the things that we want to be customizable. In general, the advantage here is that rules (abilities, effects, etc) could be enabled by matching a tag, which would be conditional based on context, rather than just being set on or off. For example, instead of a unit class being given the Amphibious ability, it could have the ability when the "amphibious-warfare" tag is present at the civ scope- that is, once the tech is researched. That would allow multiple units to gain the ability once the tech is researched, or whatever other condition provides the tag.

Prerequisites

One of the main areas where tags come in handy is for defining prerequisites. In Civ3, prereq options are predefined: you have a very small number of specific types of prereqs to choose from for a given item. Tech to tech, tech and resource to unit, and so on. But what if instead of defining options for each different type of thing that can be required, your prereqs can come from anywhere? This not only streamlines the way that prereqs can be defined, but it provides much more flexibility to how they are provided.

Let's say you want to add a Garden city improvement that requires water access. In Civ3 you could require fresh water, OR require an Aqueduct, but not both because they're mutually exclusive (and certainly not either/or). The best you could do is make two copies with different prereqs. That might work, but then if you want to make something else that requires a Garden, you're back to square one.

Now consider using tags: the Garden could simply require the "water-source" tag at the city scope. That tag could be provided by anything, or multiple things: natural fresh water, an Aqueduct, or even adjacent irrigation! What's more, the Garden doesn't need to know where this tag comes from. If you later add a Well, or decide to remove the tag effect from irrigation, you don't need to go back and update the Garden. They are decoupled. This can be especially important if we end up devising modular mods where you can enable or import collections of content, because then content from different mod packages can be set up to interact implicitly without having to define references to things that may not exist. Going back to the Garden example, perhaps another small mod provides a Desalinization Plant that provides fresh water to coastal cities and also uses the same "water-source" tag, it will also unlock your Garden.

Of course, since tags are arbitrary strings this degree of integration requires some coordination of tags, and/or allows for emergent behaviors from unintentional tag matching. This goes back to the earlier point of making tags clear and specific: you will usually want each tag to be unique to your mod and for a single purpose, but in time there may be some standardization of common tags to provide plug-and-play integration between some mods.

Conclusion

So far I've described what tags and scopes are, and what they could potentially do if we adopt them as the basis for enabling game rules. In the next post I'll get into what this might look like in mod data, and some potential hangups from using this approach.
 
Surely you can add also the requirement that Stealth attacks cannot be used against units without the Mounted tag.
And also, yes, water. Or not require water.
It might work as IIRC Civ 4 did when making some units more vulnerable to others. You could have damage types as in Starcraft (normal/splash/explosive).

This tag thing might work also for requiring that you have more than 1 of some resource available to build a particularly large wonder.

/Subscription post
 
If you use Lua I think you can just make scenario files with .xml format. It could work as an upgrade from .txt config files.
 
(blinks) If you want me to hug you just say so.

Edit: something I was thinking of was that improvements could take one or more resources to be built and the same or others to work. E.g. you require stone to build an aqueduct but water for it to work (and maybe stone for upkeep).
 
Last edited:
I've been thinking this for a long time. Been playing a lot of Elder Scrolls recently, and from my delving into modding there I know that those games make great use of a keyword system.
 
Back
Top Bottom