3
\$\begingroup\$

In a strategy game, I want to declare prerequisites for various types of game objects to limit when they can be acquired/executed: technologies, buildables, resources, actions, etc. Any of these types could have prerequisites from any other type.

Examples:

  • Training unit U requires technology X to be known, a building Y present in the city, and a surplus of resource Z available.
  • Starting research on technology T requires technologies A and B to be known, and a source of resource C available.
  • Construction wonder W requires 5 instances of building D in that player's cities and no other instance of W in existence.

The difficulty here is that each type of object meets the prerequisite in a somewhat different way. Technologies are known to a player or not, while buildings may exist in a given city, and resources could be present but not exploited or already claimed.

Is there a way I can generically describe such a prerequisite feature that can include any combination of semantically different game objects? This structure would have to determine, given a context, whether all prerequisites are met, and if not what is missing.

\$\endgroup\$
1
  • \$\begingroup\$ The first thing that came to mind would be to use a tree structure, but that would only work for the technology side of things as it would rely on the fact that once you know something, you cannot "forget" it. I think it would need to be a combination of data structures, trees for static things that have prerequisites (tech tree), possibly a tree for building requirements (if they are permanent or not). \$\endgroup\$ Jun 22, 2015 at 16:03

2 Answers 2

1
\$\begingroup\$

If you're looking for some magic pattern or data structure that deals with prerequisites, I don't think there is one, or rather, it's very simple: all you need is a simple way to query the number of Xs in Y, and a clear hierarchy of ownership.

That is, be able to query things like:

  • Number of buildings of a certain type in a city
  • Whether a specific technology is known by the player's tech tree

And so on, which naturally implies a hierarchy:

  • Player
    • Tech tree
      • Technologies
    • Cities
      • Buildings
    • Access to resources (?)

Then you check whether an action (training, research) is possible by checking that all of its prerequisites are met. From your examples, you'll need some aggregation functions too.

Examples:

Training unit U requires technology X to be known, a building Y present in the city, and a surplus of resource Z available.

Becomes:

  • Technology X exists in the tech tree
  • Building Y exists in city
  • whatever owns resources has at least some amount of resource Z

Starting research on technology T requires technologies A and B to be known, and a source of resource C available.

Becomes:

  • Technology A exists in the tech tree
  • Technology B exists in the tech tree
  • whatever owns availability of resources contains resource C

Construction wonder W requires 5 instances of building D in that player's cities and no other instance of W in existence.

Becomes:

  • The sum of buildings D in all cities is at least 5
  • The sum of wonders W in all cities is 0

There are many ways you can implement these prerequisites. Consider preferring simple representations, because don't forget, the player also needs to know and track these prerequisites, so you don't want it to be too confusing.

\$\endgroup\$
1
\$\begingroup\$

Generalizing your problem, you have a pool of data (the player's state), and you need a way to represent a boolean expression over such data,

Before starting, you may want to sit down and decide:

  • How many situations need prerequisites? 20? 10000?

  • Which data sources are available for querying? Just technologies and resources? How about time since the game started? How about custom flags to restrict development? (think about the early missions in story mode where your tech tree is not completely available) How about magic spells to restrict the enemy's development?

    The more data sources you have, the more complex the system will be

  • What kind of operations do you want to perform on your data? available/not_available, equals, unequals, greater_than, lesser_than, and so on

    The more types of operations you have, the more complex the system will be

  • How are different conditions related? Are all prerequisites just a large "and", so only one condition not being satisfied invalidates everything? Or will you also need "or" and other operators? How about grouping (parentheses)?

    The more types of relationships, the more complex the system will be

  • And finally, how easy do you want your system to be mofifiable? Can you get away by hardcoding it into your game source? Or do you have a group of game balancers that you want to be able to tweak these conditions without having to rebuild (or even restart) the game? Or do you want the game to be moddable, so end users can actually change the game conditions?

As a result, I can come up with three main ways to implement prerequsite systems like the one you need:

  • Hardcoding into your game logic: This may leave a funny aftertaste, but do remember that it is the easiest to implement if the amount of situations is small. Also it is very flexible, as you have the entire power of your programming language to implement conditions as you see fit

  • Making a database, where all these conditions are stored. As long as the relationships between different conditions are very simple (just a big "and"), this may be a CSV file, where you have conditions like SOURCE OPERATOR VALUE. This is relatively simple to implement, and doesn't require you to recompile whenever you make a change. I've used this type of database for representing pretty much everything in a game, so a team of game balancers can focus on their job

  • Having your own language where your conditions are interpreted. This can either be a custom language (not recommended unless it is very simple), or a script language like lua. Conditions are stored as expressions in that language, and the parser/compiler makes sure they are correctly implemented. This is almost as flexible as hardcoding, but no recompiles are required. This is also very mod-friendly if you choose to add modding support for your game. However, remember the overhead you need to completely support a second programming language (if your game doesn't have any scripting capabilities yet), and the training needed to explain how the language works to other people if they are going to be helping you balance the system.

Be pragmatic though, and only implement the bare minimum to support what you need.

\$\endgroup\$
1
  • \$\begingroup\$ What is the most commun way to deal with it for large games? \$\endgroup\$ May 15, 2022 at 7:46

You must log in to answer this question.

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