Skip to content

AI scoring system overhaul

dzfischer edited this page Oct 27, 2020 · 3 revisions

The Scoring System is used for evaluating buildings and units for the AI to build in a specific City. Currently it is implemented as a couple of massive monolithic functions, basically giant if statements accumulating various different factors. These factors can be categorized across a few different dimensions: scope, inputs, and application.

Scope

This describes how widely applicable this factor is. e.g. Do the inputs of the factor vary between players, or cities, or buildings? The scope could be any combination of the following:

  • Player - the factor varies per player
  • City - the factor varies per city
  • Building - the factor varies per building

It could be possible for instance for a factor to only vary per building: this would make it a constant on that building. Or it could vary per player per building: it is a constant on the building that varies by some state that is specific to the player (e.g. war/peace).

Inputs

This describes the set of values that go into calculating the factor, and where they come from. Examples inputs:

  • The state (and maybe evaluation of progress) of wars the player is involved in.
  • The relative tech progress between the player and the current tech leader.
  • The relative military strength between the player and their neighbors weighted by distance and relationship.

Application

This describes how the factor is applied to the current score. This would probably be either a straight multiplier or an addition. Additions would probably all be applied before multipliers to form a "base score". Multipliers would allow the score to be completely zeroed by particular factors. e.g. Disabling buildings that cost money when the net income is < 0. Multipliers that could be 0 should usually be evaluated first in this case, to allow them to "early out" the rest of the calculations. That a multiplier could be zero might be a indicated by a user supplied hint.

Evaluation Graph

Factors could be composed in an acyclic graph allowing simplification of nodes, more granularity in caching and reuse between final factor scoring. e.g. A node that wants to generate a factor for weighing military strength could be composed of a sum of the other players relative military scores, weighted by distance and relationship. This would break down into:

  • An algorithm node that performs a sum
  • A function node that multiplies two values
  • A value node that calculates relative military score
  • A value node that calculates a distance metric This would allow separate caching of the scores and distance metrics, with different cadences of cache invalidation (we probably don't need to update distance metric every turn for instance, it is a slowly changing thing generally).