Custom Actions ~ Current Module State (2022) - uchicago-cs/chiventure GitHub Wiki
Documentation of Existing Custom Actions Code (2022)
Aims
The documentation on this page summarizes the current state of the custom actions module. The current action-management team will be using this document to understand what has currently been accomplished in custom actions, as well as what may still need to be accomplished.
Relevant Files
chiventure/src/custom-actions/
-
include/
- action_block.h
- ast_block.h
- branch_block.h
- conditional_block.h
- control_block.h
- custom-actions-common.h
- custom-actions-cond.h
- custom-actions-effect.h
- custom-action.h
- interface.h
-
src/
- action_block.c
- ast_block.c
- branch_block.c
- conditional_block.c
- control_block.c
- custom-actions-cond.c
- custom-actions-effect.c
- custom-action.c
- interface.c
File Descriptions
The following section describes the role of each module in the custom actions feature, with links to the relevant parts of the Design Document where applicable. Modules are ordered from highest level (most abstraction) to lowest level.
interface.h/interface.c
The interface for users to create new custom actions. Contains five functions:
- do_custom_action: executes a custom action and returns SUCCESS if the action can be executed, FAILURE otherwise
- search_for_custom_action: searches through the game's list of actions for the selected action, returning a pointer to the action with the same name, or NULL if no such action can be found
- compile_custom_action: takes an action object that has been translated from JSON, turns it into a custom action object, then adds it to the game's list of custom actions. Returns a pointer to the compiled action upon success, or NULL upon failure.
- add_custom_action_to_game: adds a custom action to the game's list of custom actions. Returns either SUCCESS or FAILURE to indicate successful/failed addition
- currently public for sandbox purposes, but is intended to be a private helper for compile_custom_action
- translate_custom_action: turns an object parsed from JSON into a custom action type (custom_action_t), returns a pointer to the custom_action_t upon success, or NULL upon failure
- Not currently implemented; see backlog issue #796
- Dependency of compile_custom_action; if the current action management team wants to progress with this feature, implementing this function will likely be one of the first orders of business
Additional information can be found in this section of the design doc.
custom_action.h/custom_action.c
Contains the struct for a custom action, along with the proper new/init/free functions. A custom action struct contains:
- The name of the action (string)
- The context of the action (string) - current contexts are Player, Battle, Item, and Item-Item
- The name of the item associated with the action (string)
- The type of the action (string)
- A pointer to an AST block (more on this later); specifically, the first AST block in the sequence of actions
custom-actions-common.h
Defines numerical values for SUCCEEDS, FAILS, TRUE, and FALSE for use in other modules. Also contains a helper function to create a new attribute, since such a function is missing from game-state/item.h.
ast_block.h/ast_block.c
Explanations for the design structure of actions can be found here. Briefly, each custom action contains an action sequence; that is, a list of actions that will be performed in order upon execution of the custom action. Actions in the sequence are categorized into four blocks (types): action blocks, branch blocks, control blocks, and conditional blocks. An action sequence is implemented as a linked list of ast_blocks (Abstract Syntax Tree blocks), created as an abstraction of the four possible block types. As such, an ast_block contains:
- A pointer to a block (a union of all four block types)
- An enum describing the block type
- A pointer to the next ast_block in the linked list In addition to the new/init/free functions for ast_blocks, the ast_block module contains the following functions
- list_how_many_AST_blocks: counts the number of AST blocks in a list
- Consider renaming this function.
- append_list_AST_block and prepend_list_AST_block: functions to add AST blocks at the end and start of the action sequence, respectively
- list_remove_AST_block: removes an AST block from the action sequence
- run_AST_block: executes an AST block, provided its of the appropriate block type (only branch and action blocks can be "run")
action_block.h/action_block.c
Implements the action block type. This block type takes a list of attributes and executes the atomic action associated with that particular block. The execution of an action block results in either modified existing attributes or new, temporary attributes. In line with this, an action struct contains:
- The type of (atomic) action as an enum
- The number of attributes to which the above action is to be applied
- The list of attributes to which the above action is to be applied This module contains new/init/free functions for an action block struct, as well as a function for initializing an AST block of type action_block. It also contains the function exec_action_block to execute an action block by applying its action to its attributes, returning SUCCESS or FAILURE depending on the outcome.
custom_actions_effect.h/custom_actions_effect.c
Contains helper functions to facilitate the changing of attributes resulting in the action block.
- set_attr: takes two attributes and sets the value of attr_1 to that of attr_2
- add_attr/sub_attr/mult_attr/div_attr: takes two attributes (must be a pair of ints or doubles) and adds/subtracts/multiplies/divides them,storing the result in a third attribute.
- gen_attrval: generates a integer between a given min and max and stores it in an attribute
- say_phrase: prints a given phrase to the user interface
- not yet implemented!
- move_player: moves a player to a room
- not yet implemented!
conditional_block.h/conditional_block.c
Implements the conditional block type. Conditional blocks compare two attributes with a specified binary comparison operator after verifying that the attributes have a type that can be compared in such a way. As such, conditional blocks contain:
- The type of conditional (the comparison operation to be performed)
- A "left" attribute, to be compared to "right"
- A "right" attribute, to be compared to "left" This module contains new/init/free functions for a conditional block struct, as well as a function for initializing an AST block of type conditional_block. It also contains the function eval_conditional_block to execute the comparison of the attributes associated with the block, returning TRUE if the condition is true or FALSE otherwise.
custom_actions_cond.h/custom_actions_cond.c
Contains helper functions for checking the different conditions of an action, and defines an enum for the conditional types.
control_block.h/control_block.c
Implements the control block type. The control block simply contains a control type (e.g. IFELSE, WHILEENDWHILE, FORENDFOR), and was created to exist within the branch block. Control types indicate how a sequence of logic will be executed. This module contains new/init/free functions for a control block struct, as well as a function for initializing an AST block of type control_block.
branch_block.h/branch_block.c
Implements the branch block type. Branch blocks contain conditional blocks and control blocks. Each control block must have at least one associated conditional in the branch. Specifically, a branch block struct has:
- An int representing the number of conditional blocks it contains
- A list of pointers to conditional blocks
- A control_block struct to indicate control type
- An int representing the number of control blocks it contains
- An list of pointers to control blocks This module contains new/init/free functions for a branch block struct, as well as a function for initializing an AST block of type branch_block. It also contains the function do_branch_block to execute a branch block, returning SUCCESS or FAILURE depending on the outcome.
- For a control block of type IFELSE, the branch block will evaluate the list of associated conditionals until one is true (conditionals act as if/elif/else statements)
- For a control block of type FORENDFOR or WHILEENDWHILE, the branch block will evaluate the given condition(s) while the condition evaluates to true. For every true condition the block will execute the associated action, breaking the loop upon failure to complete an action.