Action

From Ukikipedia
Revision as of 19:49, 28 April 2024 by Icecream17 (talk | contribs) (→‎Frame: add OOB step)
Jump to navigation Jump to search

An action is a particular state that Mario can be in. Long jumping, crouching, and walking are examples of actions. Each action has code controlling high-level behavior such as Mario's movement while in the action, as well as transitions to other actions. Mario can only be in one action at a time.

It is likely the game developers referred to actions as "states", as evidenced by the "STA" label on one of the debug menus. The name "action" was chosen by the community as a less ambiguous alternative.

If Mario's current action is hacked to be an invalid action value, the game will either freeze or softlock, since such an action lacks associated code. There are 230 valid actions in the game, but some of these are accessible only through hacking. In addition to these, there are two "pseudo-actions", 0x050 and 0x051, that immediately transition to another action. Specifically, they are "begin sliding" actions, and they transition into either butt slide or stomach slide, depending on whether Mario is facing uphill or downhill. There is evidence of one action, action 0x00E, that was defined but whose code was never implemented.

Action groups

An action is represented as a 32-bit value. The lowest nine bits are a unique ID for the action, ranging in value from 0x000 to 0x192. Not all action IDs in this range are used by an action.

These IDs are divided into seven ranges, called action groups. These roughly categorize the behavior of each action, but are primarily used for organizational purposes in the code.

Name Range start Range end Number of actions Description
stationary 0x001 0x03F 36 stopped while on ground
moving 0x040 0x07F 40 moving while on ground
airborne 0x080 0x0BF 45 moving in air
submerged 0x0C0 0x0FF 32 in water, including with metal cap
cutscene 0x100 0x13F 51 no control of mario
automatic 0x140 0x17F 17 restricted control of mario
object 0x180 0x1BF 10 relating to picking up or releasing objects

The "uninitialized" action with ID 0x000 is not considered to be a part of any group. Despite being a valid action, it overrides much of Mario's behavior and is implemented differently than regular actions.

Action groups, while largely used for organization, do sometimes define shared properties of the actions contained in them. For example, the code for dying in quicksand is shared among the stationary, moving, and object action groups, so it is impossible to die from quicksand while in one of the other action groups.

Action flags

Most properties of actions are defined by action flags, which make up the remaining bits of the 32-bit action value. While there are 23 bits left after excluding the 9-bit ID, bit 30 is both unused by the game and unset by any action, so there are effectively only 22 action flags.

Bit Name Example properties
9 stationary increases deceleration in water
10 moving affects buoyancy in water, push speed of horizontal wind
11 airborne allows stomping on enemies, affects knockback behavior, disallows lava boost
12 intangible disallows object interaction
13 swimming affects knockback behavior
14 metal water affects knockback behavior, lessens gravity and terminal velocity
15 short hitbox shortens Mario's object hitbox from 160 to 100
16 riding shell makes water surface a tangible floor, allows attacking objects
17 invulnerable disables certain interactions involving damage or knockback
18 butt/stomach slide Klepto checks this flag; details not yet known
19 diving determines which picking-up action is used, affects water entry
20 on pole cannot grab pole when previous action has this flag set
21 hanging affects knockback behavior
22 idle animation plays when collecting cap, allows reading signs
23 attacking slightly affects whether an object can pick Mario up
24 interruptable by wind allows entering the vertical wind action
25 control jump height strengthens gravity when not holding A on ascent
26 allow first person allows C-up to affect action behavior
27 pause exit the level exit option is shown in the pause menu
28 swimming/flying unused by the game
29 water/text unused by the game
31 throwing something to do with particle effects; details not yet known

Note that the first three flags have the same name as the first three action groups. While most actions in these groups have the corresponding flag set, the converse is typically not true. Actions in the cutscene group, for example, may have the airborne flag set if they take place while Mario is in the air. There also exist unintuitive cases, such as action 0x036, air throw landing, which has the airborne flag set despite being a grounded stationary action, leading to strange behavior in some circumstances.[1]

Frame

Whenever within a frame, execute_mario_action is called, and Mario's action is not uninitialized (i.e. 0), the following happens:

  1. Reset Mario's model. The model animation will be updated within the action.
  2. Why is so update_mario_inputs so complicated? Not even going into that.
  3. Special floors:
    1. If Mario's floor type is the death plane or... vertical wind, check warps, play SOUND_MARIO_WAAAOOOW.
    2. If Mario's floor type is a warp, check warps.
    3. If Mario's floor type is the PSS start or end tiles, start or end the timer.
    4. If Mario's action does not have the (11) air or (13) swimming flags, the floor is SURFACE_BURNING (lava?), and Mario is not riding a shell and mario's is less than 10 units above the floor.
      1. Damage if not wearing metal cap, and set action to Lava Boost.
  4. If Mario's floor type is null (OOB), exit.
  5. mario_process_interactions (Interact with objects). This can change mario's action.
    1. First, loop over every object's interaction handlers.
      1. If the interactType of the handler is one of the types Mario can currently collide with...
        1. Unset that type. (Basically Mario cannot interact with two objects of the same interaction type.)
        2. If the object's interaction status is not INT_STATUS_INTERACTED, call the handler
    2. Decrement the invincibility timer
    3. Call check_kick_or_punch_wall. (Basically, Mario still gets speed from kicking, punching, or "tripping" (idk what this flag name means) a wall, even if the action changes.)
    4. Remove the punching, kicking, and tripping flags from Mario.
    5. If (not interacting with door) sDisplayingDoorText = FALSE
    6. If (not interacting with warp) sJustTeleported = FALSE
  6. Loop: Call the function that executes Mario's current action. Each action has associated code as stated above. Whenever the function is called, it can return TRUE, continuing the loop. Actions often call set_mario_action, which returns TRUE and processes yet another action. Theoretically, this could cause an infinite loop, however such a subframe transition sequence has not been found.[2]
    1. To be more accurate, each action group has a function. That function is called. That group-action function may do behaviour shared across all actions of the group before calling the action function.
  7. Update Mario's model for quicksand and squishing, adjust the camera, when submerged adjust the camera and spawn bubbles, update health, update cap hitbox and model, process wind and infinite stairs music.
  8. Set oInteractionStatus to 0.

execute_mario_action is only called by bhv_mario_update, which after all of this is also responsible for spawning particles.[3]

References