Manual: Custom Action Plugin

Overview

A Custom Action Plugin is a system that allows you to create custom Actions and Conditions using GDScript and use them in the Visual Script editor just like built-in Actions and Conditions.

Installing a Custom Action Plugin

This section assumes that you already have the plugin file (a .gd script written in the required format).

  1. Place the plugin script (.gd) in any folder within your project.
    (The plugin will be loaded automatically.)

  2. Open the Visual Script editor.

  3. If the plugin provides a Condition, select Add Condition on any transition link.
    If the plugin provides an Action, select Add Action on any state.

  4. Switch the category tab at the top from the default AGMaker tab to a custom tab such as CustomCondition, OfficialPlugin, or another plugin-defined category.
    (The tab name is defined by the plugin author, so the displayed name may vary between plugins.)

  5. If the plugin’s Action or Condition appears in the list, it can be used just like any built-in Action or Condition.

Note: When updating a plugin to a newer version, replace the existing plugin file rather than installing it alongside the old one. Otherwise, an error indicating that a class name conflict has occurred may be generated.

Creating a Custom Action Plugin

Custom Action Plugins currently support GDScript only.

Create a .gd script file anywhere in your project and follow one of the formats below.

Creating an Action

@tool
extends AGMPluginAction
class_name CustomAction

## Numeric value
@export var num: float = 0.0

## Attribute
@export_enum("Fire", "Water", "Earth") var elements: int = 0

# Defines the tab name
func get_plugin_tab_name() -> String:
	return "Tab"

# Defines the group name
func get_group_name() -> String:
	return "Group"

# Description shown in the tooltip when hovering over the item in the Add dialog
func get_description() -> String:
	return "Description"

# Called when entering a state
func on_state_enter(p_owner: Object) -> void:
	print("AGMPlugin : CustomAction: on_state_enter")

# Called every frame while the state is active
func on_state_update(p_owner: Object, p_delta: float) -> void:
	print("AGMPlugin : CustomAction: on_state_update")

	var gameobject: GameObject = p_owner as GameObject
	var basesettings: BaseSettings = gameobject.get_base_settings()

	basesettings.set_hp(num)

# Called when exiting a state
func on_state_exit(p_owner: Object) -> void:
	print("AGMPlugin : CustomAction: on_state_exit")

Creating a Condition

@tool
extends AGMPluginCondition
class_name CustomCondition

# Defines the tab name
func get_plugin_tab_name() -> String:
	return "Tab"

# Defines the group name
func get_group_name() -> String:
	return "Group"

# Description shown in the tooltip when hovering over the item in the Add dialog
func get_description() -> String:
	return "Description"

# Called when entering the condition
# (Triggered when entering the state)
func on_condition_enter(p_owner: Object) -> void:
	print("AGMPlugin : CustomCondition: on_condition_enter")

# Called continuously to evaluate the condition
func on_judge_condition(p_owner: Object, p_delta_time: float) -> bool:
	print("AGMPlugin : CustomCondition: on_judge_condition")

	var gameobject: GameObject = p_owner as GameObject
	var basesettings: BaseSettings = gameobject.get_base_settings()

	if basesettings.get_hp() <= 0:
		return true
	else:
		return false

# Called when exiting the condition
# (Triggered when leaving the state)
func on_condition_exit(p_owner: Object) -> void:
	print("AGMPlugin : CustomCondition: on_condition_exit")

Tips for Writing Plugin Code

AGMPluginAction and AGMPluginCondition do not inherit from Node2D.

Instead, plugin logic should typically operate on the owning object, such as:

  • GameObject (inherits from CharacterBody2D)
  • Area2DGameObject (inherits from Area2D)

These can be accessed through the owner parameter and used to implement the plugin’s functionality.

When developing a large plugin containing multiple Actions and Conditions, it is recommended to create a shared utility script and build an inheritance hierarchy around it. This helps centralize common functionality and improves maintainability.

1 Like

Manual: Creating Custom Actions/Conditions Using AI

Creating Custom Action Plugins with AI

If you want to create your own actions or conditions without programming experience, consider leveraging AI.

Custom action plugins are created using the features of the base engine, Godot Engine. Since Godot Engine is widely trained in current AI models, it works well with AI code generation and can sometimes generate plugin code suitable for ACTION GAME MAKER.

Examples of Prompts for AI

Example for Creating an Action

Input the following prompt into the AI:

This is a script to create a plugin for ACTION GAME MAKER, a custom editor for Godot Engine 4.4.

ACTION GAME MAKER is an FSM-type visual script editor that utilizes the basic features of Godot Engine.

The owner of the plugin is one of the following:

  • GameObject (a custom node based on CharacterBody2D)

  • Area2DGameObject (a custom node based on Area2D)

GameObject has data storage nodes such as VariableSettings and can also use a project-wide database. Refer to the following for the access API:

Manual: Method/Signal/API List

Below is sample code for adding a new action.

@tool
extends AGMPluginAction
class_name CustomAction

## Value
@export var num: float = 0.0

## Attribute
@export_enum("Fire", "Water", "Earth") var elements: int = 0

# Define tab
func get_plugin_tab_name() -> String:
    return "Tab"

# Define group
func get_group_name() -> String:
    return "Group"

# Define description
func get_description() -> String:
    return "Description"

# Called when entering the state
func on_state_enter(p_owner: Object) -> void:
    print("AGMPlugin : CustomAction: on_state_enter")

# Called constantly during the state
func on_state_update(p_owner: Object, p_delta: float) -> void:
    print("AGMPlugin : CustomAction: on_state_update")

    var gameobject: GameObject = p_owner as GameObject
    var basesettings: BaseSettings = gameobject.get_base_settings()

    basesettings.set_hp(num)

# Called when exiting the state
func on_state_exit(p_owner: Object) -> void:
    print("AGMPlugin : CustomAction: on_state_exit")

Based on this sample code, create a plugin that performs the [Desired Behavior].

Example for Creating a Condition

The process is similar for creating conditions, but use the sample code for conditions.

This is a script to create a plugin for ACTION GAME MAKER, a custom editor for Godot Engine 4.4.

ACTION GAME MAKER is an FSM-type visual script editor that utilizes the basic features of Godot Engine.

The owner of the plugin is one of the following:

  • GameObject (a custom node based on CharacterBody2D)

  • Area2DGameObject (a custom node based on Area2D)

GameObject has data storage nodes such as VariableSettings and can also use a project-wide database. Refer to the following for the access API:

Manual: Method/Signal/API List

Below is sample code for adding a new condition.

@tool
extends AGMPluginCondition
class_name CustomCondition

# Define tab
func get_plugin_tab_name() -> String:
    return "Tab"

# Define group
func get_group_name() -> String:
    return "Group"

# Define description
func get_description() -> String:
    return "Description"

# Called when entering the condition
func on_condition_enter(p_owner: Object) -> void:
    print("AGMPlugin : CustomCondition: on_condition_enter")

# Called constantly for condition judgment
func on_judge_condition(p_owner: Object, p_delta_time: float) -> bool:
    print("AGMPlugin : CustomCondition: on_judge_condition")

    var gameobject: GameObject = p_owner as GameObject
    var basesettings: BaseSettings = gameobject.get_base_settings()

    if basesettings.get_hp() <= 0:
        return true
    else:
        return false

# Called when exiting the condition
func on_condition_exit(p_owner: Object) -> void:
    print("AGMPlugin : CustomCondition: on_condition_exit")

Based on this sample code, create a plugin with the [Condition to Evaluate] as the condition.

Tips for Giving Instructions

  • AI agents may make mistakes regarding API access paths or method names. In such cases, refer to the documentation above and provide the correct API information to the AI to request regeneration.

  • To avoid conflicts, it is recommended that you adjust the class_name, tab names, and group names yourself.

  • When creating movement-related actions, you need to stop the movement control on the ACTION GAME MAKER side. Therefore, before implementing your own movement logic, set GameObject.is_release_move_control to false.

1 Like

Sample Official Custom Action Plugins

These can also be added by selecting “CustomActionPlugin” as a template in “Create New Object”.

Custom Actions

Rotate According to Movement Direction

CA_RotateToMoveDirection.gd (1.7 KB)

Sine Curve Movement

CA_SineCurveMove.gd (2.2 KB)

Push a Physics Node (RigidBody)

CA_PushRigidBody.gd (1.3 KB)

Custom Conditions

Transition Based on Light “Brightness”

CC_CheckBrightness.gd (2.4 KB)

Transition When Variable Value Is Within a Certain Range

CC_VariableRange.gd (9.9 KB)

Transition Based on the Result of Arithmetic Operations on Two Variables

CC_VariableCalculationCondition.gd (13.6 KB)

2 Likes

Translating Custom Action Plugins

Starting with v1.3.3, you can translate custom actions by attaching translation files.

Translatable Parts

  • You can translate property names and tooltips for properties.
  • Class names (names displayed in the list) and group names cannot be translated, but their tooltips can be.

How to Implement Translations

Translation data is loaded by placing a CSV file created according to the specified format directly under the editor_translations folder within the plugin.

[Example Folder Structure]

res://addons/
└── custom_action_plugin/
├── custom_action.gd
└── editor_translations
└── custom_action.csv

  • The condition is that it must be located directly under editor_translations, which is at the same level as the custom action’s GDScript. It works regardless of whether it is in the addons folder or the custom_action_plugin folder, or any other location.
  • The name of the GDScript does not need to match the name of the CSV file.
  • One CSV file can be used for multiple GDScripts.

CSV File Sample

context,key,ja,en,ko,zh_CN,zh_TW,pt_BR,es_AR,de,ru
"CustomAction","Description","Custom Action: Tooltip","Custom Action: Tooltip","커스텀 액션: 툴팁","自定义动作:工具提示","自訂動作:工具提示","Ação personalizada: dica de ferramenta","Acción personalizada: descripción emergente","Benutzerdefinierte Aktion: Tooltip","Пользовательское действие: подсказка"
"CustomAction","group","Group","Group","그룹","组","群組","Grupo","Grupo","Gruppe","Группа"
"CustomAction:test_num","test_num(Number Tooltip)","Number tooltip","Number tooltip","숫자 툴팁","数值工具提示","數值工具提示","Dica de ferramenta do número","Descripción emergente del número","Zahlen-Tooltip","Подсказка для числа"
"CustomAction:test_num","test_num","Number","Number","숫자","数值","數值","Número","Número","Zahl","Число"
"CustomAction:test_elements","test_elements(Element Tooltip)","Element tooltip","Element tooltip","속성 툴팁","属性工具提示","屬性工具提示","Dica de ferramenta do elemento","Descripción emergente del elemento","Element-Tooltip","Подсказка для элемента"
"CustomAction:test_elements","test_elements","Element","Element","속성","属性","屬性","Elemento","Elemento","Element","Элемент"
"CustomAction:test_elements","Fire","Fire","Fire","불","火","火","Fogo","Fuego","Feuer","Огонь"
"CustomAction:test_elements","Water","Water","Water","물","水","水","Água","Agua","Wasser","Вода"
"CustomAction:test_elements","Earth","Earth","Earth","땅","土","土","Terra","Tierra","Erde","Земля"

*CSV only
custom_action.csv (1.7 KB)
*Sample configuration including the main plugin
custom_action_translation_sample.zip (2.2 KB)

Column Details

  • context specifies which property of the class it is associated with. However, descriptions returned by export_group and get_description() do not have associated properties, so they are omitted.
  • key specifies the identifier defined in the script.
  • The subsequent columns define text according to the language settings.

Tips for Writing CSVs

  1. The header (context,key,...) should not be quoted.
  2. From the second line onwards, enclose all items in double quotes.
  3. Use UTF-8 with BOM.
  4. Use CRLF line endings.
1 Like