Data Limits

An AI script is not a complete blank slate where you have boundless options for what you can script. The AI scripting engine, for data computation and storage reasons, puts limitations on the various things you can do in AI scripting, and it's useful to know these limitations when you are scripting. Here's a list of all the limitations you'll need to keep in mind when scripting for the UP or DE versions.

Tangentially related, but if you are interested in performance limitations of various commands, check out this thread in the AI Scripter's forums (account required) where TheMaximalBeing posts the results from lag tests: Link

Data Limits Summary

Rules

In AI scripting every bit of code that changes behavior must be inside a rule, which is started with a defrule command and ended with a closing parenthesis. AI scripts have a maximum of 10,000 rules, which sounds like a lot but some scripts have started running up against this limit.

Elements Per Rule

Each rule is limited to 32 elements in DE and 16 elements in UP. If you want to maintain compatibility with both versions it is a good idea to stick to 16 elements per rule from the start. "Elements" include all commands in the rule as well as any use of logical operators (or, and, not, nor, etc.). The defrule command and the "=>" that separates the facts and actions sections of the rule do not count toward your rule element count.

Goals

Goals are essentially an integer variable which the AI scripter can modify in the AI script. AI scripts has 512 different goals they can use to store different values, which are numbered from 1 to 512. One important note is that goals 1-40 cannot be used with some commands. These commands include any of the Point or Cost Data commands, up-get-search-state, or up-get-guard-state. Filter on the Category dropdown on the Commands index to find out which commands use points or cost data. These commands don't work because they modify multiple consecutively numbered goals at once, and the original goals from 1-40 aren't designed to allow this automatic behavior for these commands. Additionally, be careful about using goal 512 in point commands (which modify two goals) or goals 510-512 with cost data commands or up-get-search-state or up-get-guard-state (which all modify four goals) because they will try to automatically modify goals 513 or beyond which don't exist. However, the original Userpatch documentation says to avoid goals 511 and 512 for point goals and goals 509-512 for the commands that automatically modify four goals. To be safe, use goals 509-512 only for simple tasks, like for goals 1-40.

Strategic Numbers

Strategic numbers modify various built-in behaviors and settings that can modify the automatic behaviors of your AI. See the SN Index for details on what each strategic number does. Each SN is given an ID between 0 and 511. Currently, the SNs in the 313-511 range don't appear in the SN index and don't modify the behavior of your AI, but they are available for your AI to use. So, you can modify these SNs however you like, similar to goals, without changing the behavior of your AI. However, if you want to use a strategic number in this way like an extra custom goal, always check the SN index to make sure that the SN ID you are using is actually currently unused. A good practice is to start with using SN 511 and work your way backwards toward SNs in the 300 range.

Timers

There are 50 different timers an AI script can use at any time, numbered from 1 to 50.

Defconst Values

Defconsts allow you to train your AI to treat a word or phrase in place of an integer value. See this article series that explains what defconsts do: Link. The value you can use with a defconst can range from -32,768 to 32,767 (a 16-bit signed integer). You can also defconst a text string such as (defconst chat-gg "gg").

Goal and SN Values

Each goal and strategic number can be set to any integer value between 2,147,483,648 to 2,147,483,647 (a 32-bit signed integer). However, there are many strategic numbers which have a much more limited usable range. Look at the Req. Min and Req. Max columns in the SN index for the true usable limits of each SN.

Flag values

Flag values must be powers of 2 between 1 (2^0) and 2,147,483,648 (2^31). In other words: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, etc. This is due to the binary arithmetic that flags use. Scripts will often defconst the values of the flags for ease of reading, but unfortunately you can only defconst the flags up to 16,384 because of the defconst limit of 32,767.

DUC Local Search List

The local search list used in DUC searches can only hold up to 240 objects at once.

DUC Remote Search List

The remote search list used in DUC searches can only hold up to 40 objects at once.

Taunts

AIs can respond to any numeric taunt from 1 to 255, even if the taunt doesn't have a corresponding audio message. Any chat message that starts with a number in this range can be detected as a taunt with the taunt-detected command.

Characters Per Line

AI scripts can only read up to 255 characters per line in your AI script, including any characters in a comment. Otherwise your script will likely generate an error.

Nested File Load Commands

Load commands, such as (load "AI Name/Attack"), can be nested (a script that loads another script) up to 10 levels deep.

Nested #load-if Commands

The CPSB (the original ES AI scripting documentation) says that conditional loading directives (#load-if commands like #load-if-defined AZTEC-CIV) can be nested 50 levels deep. Nested means having a #load-if inside of a #load-if, where the inner #load-if is only read if the outer #load-if is true. However, some testing in UP a couple years ago found that the nesting limit is much lower, somewhere in the upper 30s, so be careful when using a bunch of nested #load-if-not-defined commands.

Lag Limit

While not a true limit per se, any script pass that lasts longer than 20 milliseconds will start causing lag. Script pass durations can be checked with up-get-precise-time.

Doctrine

The often forgotten doctrine. There is only one because there can only be one true doctrine...Anyway, the doctrine is simply an extra goal that you can't use with UP commands. All you can do is set it exactly to a given value with the set-doctrine command and then check if the doctrine is set exactly to a certain value with the doctrine command. But in dire need, you can use it if you run out of goals.