Empires Scripting: Difference between revisions

From Archon Wiki
Jump to navigation Jump to search
(Created page with "See My Games\<Game Name>\AUTODOCS\BATTLESCRIPT.TXT for definitive script command descriptions. Also output to the AUTODOCS folder is ARCHON.XML, a language definition compati...")
 
No edit summary
Line 2: Line 2:


Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).
Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).
= Pathfinding =
== GetRoute ==
The main entry point is GetRoute(startRegion, destRegion, workArray, groupID, ...).  It returns the total cost of the route and the route itself is stored in the temporary work array.  The steps in the route are accessed using GetArray(step).  For example to get the route from current to destination into the array route:
    int route[32];
    int i;
    cost = GetRoute(current, destination, 0, group);
    if (cost >= 0)
    {
        for (i = 0; i < 32; i++)
        {
            route[i] = GetArray(i);
            if (route[i] == -1)
            {
                i = 32; // done
            }
        }
    }
Internally, there are a number of callbacks during pathfinding so that the costs can be dynamically determined by scripts.  The sequence is something like this:
/- GetRoute(startRegion, targetRegion, workArray, groupID, ...) BATTLESCRIPT command
|    / | \
|  v  v  v
|  PathfindingData(region, groupID, ...)                Map.BSF function
|    / | \
|  v  v  v
|  SetPathfindingData(region, neighbour, cost)                  BATTLESCRIPT command
|
\-> GetRoute returns total cost
PathfindingData is a function implemented in Map.BSF that tells the engine which regions are connected to the requested region and the cost of moving to them.  Simple calculations based on region and group properties can be used to determine the cost.  PathfindingData must call SetPathfindingData for each neighbour connected to the region.  It is possible to pass additional parameters to the PathfindingData callback by adding more parameters to the function, and then padding them as additional parameters to GetRoute after the groupID.
Internally, data is cached so that if you make consecutive calls to GetRoute for the same startRegion and groupID within the same frame, the result will be found much faster.  A loop with one unit evaluating N destinations will be much faster than N units evaluating one destination.
== GetRegionsInRange ==
Pathfinding can also be used to find a list of regions in range of another.  The entry point for this is GetRegionsInRange(sourceRegion, maxCost, dynArrayHandle, [callback], [data...]).
Similar to GetRoute, evaluating a GetRegionsInRange request will result in a number of calls to a callback function which must call SetPathfindingData to provide costs to the engine.  The difference is that the name of the callback function can be provided to GetRegionsInRange.  The first parameter to the callback function will always be the region ID that data is requested for, all additional integer parameters will be passed through from the GetRegionsInRange call to the callback.
For example, to get all regions within a cost of 12 of startID using the same callback as GetRoute uses:
handle = CreateDyamicArray();
GetRegionsInRange(startID, 12, handle, "PathfindingData", groupID);
...
DestroyDynamicArray(handle);
To use a callback that uses different criteria or a different calculation, define another callback function:
FUNCTION PathfindingDataByKind(regionID, kind, faction)
{
    int i;
    int neighbour;
    int cost;
    int count;
   
    count = GetRegionInt(region, $REGION_CONNECTIONCOUNT);
    for (i = 0; i < count; i++)
    {
        neighbour = GetRegionInt(region, $REGION_CONNECTIONS, i);
        cost = myCost(regionID, kind, faction);
        SetPathfindingData(region, neighbour, cost);
    }
}
And then provide the name and expected parameters to the search:
GetRegionsInRange(startID, 12, handle, "PathfindingDataByKind", kind, factionID);
If the callback name and parameters are omitted, the search will be done without script callbacks based on the Connections attribute of the regions with a fixed cost of 1 for each step.

Revision as of 23:21, 15 November 2016

See My Games\<Game Name>\AUTODOCS\BATTLESCRIPT.TXT for definitive script command descriptions.

Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).

Pathfinding

GetRoute

The main entry point is GetRoute(startRegion, destRegion, workArray, groupID, ...). It returns the total cost of the route and the route itself is stored in the temporary work array. The steps in the route are accessed using GetArray(step). For example to get the route from current to destination into the array route:

   int route[32];
   int i;
   cost = GetRoute(current, destination, 0, group);
   if (cost >= 0)
   {
       for (i = 0; i < 32; i++)
       {
           route[i] = GetArray(i);
           if (route[i] == -1)
           {
               i = 32; // done
           }
       }
   }

Internally, there are a number of callbacks during pathfinding so that the costs can be dynamically determined by scripts. The sequence is something like this:

/- GetRoute(startRegion, targetRegion, workArray, groupID, ...) BATTLESCRIPT command
|    / | \
|   v  v  v
|  PathfindingData(region, groupID, ...)                Map.BSF function
|    / | \
|   v  v  v
|  SetPathfindingData(region, neighbour, cost)                  BATTLESCRIPT command
|
\-> GetRoute returns total cost

PathfindingData is a function implemented in Map.BSF that tells the engine which regions are connected to the requested region and the cost of moving to them. Simple calculations based on region and group properties can be used to determine the cost. PathfindingData must call SetPathfindingData for each neighbour connected to the region. It is possible to pass additional parameters to the PathfindingData callback by adding more parameters to the function, and then padding them as additional parameters to GetRoute after the groupID.

Internally, data is cached so that if you make consecutive calls to GetRoute for the same startRegion and groupID within the same frame, the result will be found much faster. A loop with one unit evaluating N destinations will be much faster than N units evaluating one destination.

GetRegionsInRange

Pathfinding can also be used to find a list of regions in range of another. The entry point for this is GetRegionsInRange(sourceRegion, maxCost, dynArrayHandle, [callback], [data...]).

Similar to GetRoute, evaluating a GetRegionsInRange request will result in a number of calls to a callback function which must call SetPathfindingData to provide costs to the engine. The difference is that the name of the callback function can be provided to GetRegionsInRange. The first parameter to the callback function will always be the region ID that data is requested for, all additional integer parameters will be passed through from the GetRegionsInRange call to the callback.

For example, to get all regions within a cost of 12 of startID using the same callback as GetRoute uses:

handle = CreateDyamicArray();
GetRegionsInRange(startID, 12, handle, "PathfindingData", groupID);
...
DestroyDynamicArray(handle);

To use a callback that uses different criteria or a different calculation, define another callback function:

FUNCTION PathfindingDataByKind(regionID, kind, faction)
{
    int i;
    int neighbour;
    int cost;
    int count;
    
    count = GetRegionInt(region, $REGION_CONNECTIONCOUNT);
    for (i = 0; i < count; i++)
    {
        neighbour = GetRegionInt(region, $REGION_CONNECTIONS, i);
        cost = myCost(regionID, kind, faction);
        SetPathfindingData(region, neighbour, cost);
    }
}

And then provide the name and expected parameters to the search:

GetRegionsInRange(startID, 12, handle, "PathfindingDataByKind", kind, factionID);

If the callback name and parameters are omitted, the search will be done without script callbacks based on the Connections attribute of the regions with a fixed cost of 1 for each step.