ActorSerializeParameter and AI

From Pikmin Technical Knowledge Base
Revision as of 03:50, 14 January 2024 by Noodl (talk | contribs) (ActorSpawner problem)
Jump to navigation Jump to search

All of the info on this page (thus far) is research and assumptions by Noodl - it may not all be entirely correct.

ActorSerializeParameter is a property on each object in an ActorGeneratorList. It contains much of the "per-instance" characteristics of the enemy it is generating, and contains parameter such as AI, object life and audio.

Each membor of ActorSerializeParameter is an object containing Static and Dynamic properties, both of which are varying-width arrays of 8bit integers that represent other data types.

{
    "ActorSerializeParameter": {
        "AI": {
            "Static": [],
            "Dynamic": []    
        }
    }
}

For the majority of actors in the game, most of the fields within ActorSerializeParameter are the same for each type of enemy. A data scrape of each unique value that each type of enemy can have can be found here (note, does not include night enemies). This can be used for sourcing the non-changing values, or for various examples of each byte array for every creature and object. (Generating code is here).

AI

AI is the interesting and important parameter. It controls per-instance parameters for actors such as drops, territory, and configuration for gimmicks. I currently believe that AI is mapped on top of an entity's own blueprint configuration from its Placeables/ file, with AI able to send overrides to parts of it.

Thus far, 3 types of teki AI have been partly charted, mostly pertaining to the inventory system.

Concepts

Before trying to break down a byte array, it helps to understand a few concepts of the data types used:

  • Each integer in the array is a single 8-bit value, so can only go up to 255.
  • The arrays are not fixed to 32-bit boundaries. A 1byte float can be adjacent to a 16bit integer.
  • Floats are little-endian, and 1 byte long. For example the value 100 will be a byte of 0, 0, 200, 66.
  • Integers can also be encoded across 16-bits (two integers of this array). For example, the value 271 would be 15,1 - 15 + (256 * 1). They are also sometimes just 1-byte long with the value at index 0.
  • Strings are encoded by 1 byte dictating the length of the string (null terminator included) followed by the string's characters in ASCII codes, ending with 0. For example the string of None will be encoded as 5, 0, 0, 0, 78, 111, 110, 101, 0, with 5 being the length of the string (4 chars + 0).
  • When arrays/objects are used (for fields like DropConditions or bSetTerritory, there is often a 1 byte boolean that dictates if the rest of the object is present, or the number of items in the array. For example, with territory, if bSetTerritory is false, the byte will look like 0, 0, 0, 0, ... followed by whatever else comes after. However if it is true (1, 0, 0, 0), 5 floats (X, Y, Z, HalfHeight and Radius) will follow, making the array vary in length.

Dandori Desktop provides tools for byte conversions that can aid in finding values.

Charts

Attempts have been made to chart the bytes of various AI parameters to uncover patterns and the locations of values in order to manipulate them. The current diagrams mostly illustrate the inventory system.

There are many bytes AFTER the end of the inventory which ends in a byte of <255, 255, 255, 255 (-1), but I have no idea what they do. I believe they're probably the overrides for TekiAIParameter and each enemy's custom AI arguments.

Creature AI

Details the drop system for a regular enemy (and eggs). The inventory system used here is the same as in GroupDropManager's, so it helps to understand creatures first.

P4-creature-ai-inventory-bytes.png

ActorSpawner AI

ActorSpawners are a little different, and their only drop is the thing they spawn, with some configuration for it.

P4-actorspawner-ai.png

GroupDropManager AI

P4-gdm-ai.png

Researching

The best way of breaking down the AI parameter (I have found) is to combine the blueprint JSONs from the Sublevels/ folder, with the ActorPlacementInfo file of the same type. The Sublevels files contain the gen_variables that seem to be encoded into the byte arrays of ActorSerializeParameter.

AI parameters can be found by searching for {entity}AI_GEN_VARIABLE, for example ElecMushiAI_GEN_VARIABLE for Anode Beetles. Most of the contents of that object's Properties will be encoded in that actor's ActorSerializeParameter.AI.Static in the ActorPlacementInfo file, so you can compare things like the drop numbers, asset path and other such floats for occurrences of those values in the AI array. Strings are often the easiest to find/locate with due to their easy to spot nature (look for the big sequence of non-0 numbers and decode it to see if it matches what you need).