An overview of the data structure that stores information about each a-life creature. Thanks to Bo Bayles for finding where this data is located and investigating what it means.
The data for a-life, including nightopians, mepians, and nightmaren enemies, is stored in HWRAM starting at offset 0x060CC000. Each a-life's structure takes up 0x80 bytes. Up to 126 individual a-life can be described in memory, since it ends at 0x060CFF00, although less than this are allowed to be generated (42 in the final, and 63 in E3).
Key:
Use the numbers on the left and top to find the offset of a particular byte. The first byte is 00. The last byte is 7F.
White/grey = highlighting to show distinct fields
Yellow = unknown data
0 1 2 3 4 5 6 7 8 9 A B C D E F
________________________________________
0 | 0000 0000 060C C380 060C C280 0815 036C
1 | 7723 FFFF 0000 0024 0002 0000 0000 0000
2 | 060C C380 0000 0000 0000 0000 0001 0000
3 | 09DD 6800 0C79 4900 09EB 0000 065E 5525
4 | 0B0B 224C 051E 1E01 0400 0000 0000 0000
5 | 0000 0000 0000 0000 0000 0000 0000 0000
6 | 0000 0000 0000 0000 0000 0000 0000 0000
7 | 0000 0000 0000 0000 0000 360B 0000 0000
List of fields (more research needed)
0x00: long. Pointer to object reference. If this value is 0, the a-life object is not currently rendered on screen. If this value is -1, the a-life slot is empty.
0x04 long. Pointer to another a-life object. This is the next pointer for the doubly linked list of a-life.
0x08 long. Pointer to another a-life object. This is the prev pointer for the doubly linked list of a-life.
0x0C byte. The current lap segment the a-life is in.
0x0D byte. A set of bit flags used for interactions with other a-life. Purpose:
80: Touching a-life has nightmaren DNA
40: Touching a-life is a nightopian (if 80 not set) or a mepian (if 80 set). If false, a-life is a king pian (if 80 not set) or a badpian (if 80 set).
20: Near a-life has nightmaren DNA
10: Near a-life is a nightopian (if 80 not set) or a mepian (if 80 set). If false, a-life is a king pian (if 80 not set) or a badpian (if 80 set).
08: A-life is touching another a-life
04: A-life is near another a-life
02: Touching a-life is to the right (true)/left (false)
01: Near a-life is to the right (true)/left (false)
0x0E byte. A set of bit flags. Purpose:
80: A-life should be ignored by others
40: A-life's behavior cannot be interrupted
20: Unknown
10: A-life is in mating behavior (can produce an egg)
08: Unknown
04: A-life is turning
02: A-life is facing right (true)/left (false)
01: A-life is touching the ground
0x0F byte. First nibble is a set of bit flags relating to a-life type:
80: A-life has nightmaren DNA
40: A-life is a nightopian (if 80 not set) or a mepian (if 80 set). If false, a-life is a king pian (if 80 not set) or a badpian (if 80 set).
20: A-life has ai (true on normal adult a-life, false on eggs and background a-life)
10: A-life is an egg
Last two bits set a modifier for flight path (increases after each playthrough, capped at 3):
03: Checks the height of the ground? seems to make a-life fly low.
02: Checks the height of the ceiling? seems to make a-life fly high.
01: Causes the a-life to move upwards slightly when it touches the ground.
00: Causes the a-life to move upwards slightly when it touches the ground and switch its x direction.
Purpose of 5th and 6th bits unknown.
0x10 byte. Used as a counter for the current frame of the flight cycle (see here).
0x11 byte. Purpose unknown
0x12 word. Used as a timer for a-life flight. After a certain time, it causes the a-life to descend.
0x14 word. Used as a timer for certain aspects of a-life behavior, such as when to switch behaviors.
0x16 word. Timer for a-life flight. After a certain time has passed, there is a 1/8th chance that the a-life will turn around. However, this does not actually work when activated. The turning animation will play but the a-life does not change direction.
0x18 word. Used to start a new behavior when the a-life moves off screen.
0x1A word. Purpose unknown
0x1C long. Pointer to an a-life which is touching. Used for some interactions.
0x20 long. Pointer to an a-life which is near. Used for some interactions.
0x24 long, Fixed point number storing velocity on the virtual X-axis.
0x28 long. Fixed point number storing velocity on the Y-axis.
0x2C long. Fixed point number storing default speed which is used in calculations of X and Y velocity.
0x30 long, Fixed point number storing position on the real X-axis.
0x34 long, Fixed point number storing position on the Y-axis.
0x38 long. Fixed point number storing position on the real Z-axis.
0x3C long. Fixed point number storing position on the virtual X-axis (a-life live on a 2D plane wrapped around a path in the 3D world, so two coordinate systems are necessary to represent their location).
0x40 byte. Stores the a-life's current action (see here).
0x41 byte. Stores the a-life's previous action.
0x42 byte. Lower nibble stores the a-life's mood on a scale from 0 to 3. Purpose of upper nibble unclear.
0x43 byte. Upper nibble stores the a-life's default speed which is multiplied to get the value found in 0x2C. Lower nibble stores its vision distance. This determines at what distance it can notice the player and other a-life.
0x44 byte. Each nibble stores a flight type which is used to evaluate the a-life's flight path. The second nibble is evaluated first. See more details here.
0x45 byte. Stores a-life's remaining lifespan.
0x46 byte. Stores a-life's initial lifespan, which it passes on to its offspring.
0x47 byte. Stores one of a-life's "genetic behavior" alleles, which can range from 0x0-17 and determines a unique action it can do triggered either by being unrendered, encountering another a-life, or touching another a-life (more info here). In cases where both genetic behaviors have the same trigger, this one is chosen first.
0x48 byte. Stores second "genetic behavior" allele.
0x49-5F Unknown data
0x60 byte. Stores a-life's body part type. Upper 2 bits store a "dominance" value used in probability calculations when breeding. Lower bits can range from 0 to 3, with values 1-3 representing different types of nightmaren parts.
0x61 byte. Unused a-life gene inherited in the same way as body part genes.
0x62 byte. Unused a-life gene.
0x63 byte. Stores a-life's head part type. Upper 2 bits store a "dominance" value used in probability calculations when breeding. Lower bits can range from 0 to 3, with values 1-3 representing different types of nightmaren parts.
0x64 byte. Unused a-life gene.
0x65 byte. Unused a-life gene.
0x66 byte. Stores a-life's arm part type. Upper 2 bits store a "dominance" value used in probability calculations when breeding. Lower bits can range from 0 to 3, with values 1-3 representing different types of nightmaren parts.
0x67 byte. Unused a-life gene.
0x68 byte. Unused a-life gene.
0x69 byte. Stores a-life's leg part type. Upper 2 bits store a "dominance" value used in probability calculations when breeding. Lower bits can range from 0 to 3, with values 1-3 representing different types of nightmaren parts.
0x6A byte. Unused a-life gene.
0x6B byte. Unused a-life gene.
0x6C-73 Unknown data
0x74 long. Holds a series of bit flags which prevent a-life from repeating certain actions more than once per playthrough.
0x78 long. Holds a-life's "desire to mate" value, which is incremented every frame. Mating behavior is only activated once this value reaches a threshold of 0x4650 (18000) after 5 minutes.
0x7C long. Stores a pointer to a positioning scheme that places the a-life's limbs around its body depending on what torso part it has. This allows mepians to have different body shapes depending on what nightmaren torso they have.