home >> Low level routines for simulation

Designing player-like bots requires, besides Artificial Intelligence, low level routines dealing with aiming, moving, detecting,... to introduce human-like behavior like lags, errors, perturbations, bounds... to the otherwise god-like bot.
The set of numerical systems proposed here is meant to be a toolbox for the programmer to build such routines.
Although the focus here is on bot programming, these systems have a broader application range ( eg: simulating a tracking device).
Appendices A and B are rather theoretical. The "mathematically impaired" should know that their reading is not needed to use the code.


Several definitions

First of all, I am the kind of guy who likes to know how things work. The (possibly huge) chunks of text dedicated to explanations are for those of you that are like me.
So here is the first one...

By "system" I mean
-a set of variables and equations defining a type of behavior,
-the parameters of the equations which determine the particular behavior of one system.
-a set of tuning parameters, fully related to the equations parameters, but choosen so that user control over the behavior is more convenient/intuitive.
The set of variables that have to be initialized( and stored, for numerical version) are not detailed, as this can be derived from the equations.
A continuous system ( or analog system) is a system the variables/parameters of which are defined for every value of time. This has nothing to do with the usual mathematical definition of a continuous function.
A numerical system is a particular case of a discrete system as coded in a software program. A discrete system refers to systems described by equations where variable/parameters are indexed by integers representing a sequence of steps ( or stages). A discrete system is undefined between steps. Still, in cases ( like ours) where steps are associated to points in time, the usual implementation assumes or insures that variables/parameters keep their value at step n until step n+1 occurs ( like a "sample-hold" device does).
Most of the systems are "dynamic", ie their state(s) change over time (for continuous systems) or with the index( for numerical systems).
The word "dynsyst" will be used as an abbreviation for "dynamic system".

The first and biggest subset is the one of dynsysts meant to be input by a variable of the game/bot code, and produce an output fed back into the game/bot code. Within this subset, most dynsysts are aimed at altering ( smoothing, bounding,...) the input, and are called "filters", be they dynamic or not. The second subset includes dynsysts like perturbation generators (eg the colored noise generator), which generate an output on their own, which is meant to be superimposed ( usually by addition) on a variable of the game/bot code.

The state variables of a system is the minimum set of variables that are needed at a given point in time/at a given step to fully describe the system. It can be viewed as the minimum set that must be memorized to be able to comprehensively recompute the state of the system from scatch. This set is not unique, but its number of state variables -the order of the system- is ( eg: a system described by 3 variables such as any variable can be computed from the 2 others requires 2 state variables, chosen amongst the 3 showing in the system equations).

Note: The number of variables that must be memorized in the examples of the PSEUDO-CODE/CODE is in some case higher than the order of the system. This is because I did not want to perform variable change for almost no benefit on memory at the expense of clarity on how the code works.


Expanding on the solutions

Dynsysts proposed here are mostly low-pass filters ie they smooth short term ( "fast") input variations and let long-term ("slow") variations almost unaffected.

High-pass filters

These do the opposite of Low-pass filters: they let short-term variations almost unaffected, but long-term ones are "washed-out".
A simple way to get a high-pass filter when one got a low-pass one is to define the high pass as the input minus the output of the low pass: HighPass( Input)= Input- LowPass( Input)
Such High-pass filter and Low-pass filter are referred to as "complementary" in the following, meaning that, fed in with the same input, the sum of their output is equal to the input.

"Mixing " filters, pass-band filters

One can build a new dynsyst from 2 dynsysts, as K*DynSyst_1+ (1-K) DynSyst_2, with 0< K< 1 and thedynsysts having the same input.
K needs not be constant.
In particular, if I have a dynsyst D1 the behaviour of which I like in the short term but not in the long term, and another dynsyst D2 for which the reverse holds, I can mix frequency-wise ( or time-wise if you prefer) the two dynsyst to get the best of both .
This is done with the help of complementary filters:
Mixed( Input)= HighPass( D1( Input))+ LowPass( D2(Input))
or probably better if using non linear complementary filters :
Mixed( Input)= D1( HighPass(Input))+ D2(LowPass(Input))

Several other solutions not addressed here

Most dynsysts presented here have equations where the previous step output(s) show on the right side of the formulas ( recursive filters ), ie the current ouput is a function of the previous one(s).
Why? To put it simply, because they are more flexible, with low memory requirements ( previous steps variables storage).
Other solutions would include for example...
-numerical equations with no reference to any previous step output value ("non recursive filters").

Example: Outputn= 0.5*( Inputn+Inputn-1) is the well known average. Weighted averages on N input steps is the more general formula ( which requires storage of N-1 variables).

-Output based on statistical properties of a set of N current and previous Inputs ( the average as above, the mode, the median,...).