Giter VIP home page Giter VIP logo

godot-pushdown-fsm's Introduction

Godot Pushdown Fsm

A Godot 4 FSM addon which allows you to set, push and pop states.

Installation

Clone or download the repo as a .zip, and copy the contents of fsm/ directory to wherever you want. TODO: package as addon

This addon is tested and compatible with Godot 4 Beta 17, and should continue to work for future versions.

Usage

  • This addon provides two new global classes: StateMachine and State.

  • The StateMachine object manages the State nodes below it, and can switch between them using the set_state, push_state and pop_state methods.

  • States are where the actual behaviors are defined. They contain a few key functions which are called from the StateMachine:

  1. func enter(msg={}):

    When a State is switched to, it's _enter(msg) function is called. The optional msg parameter is a dictionary, which is passed along when switching to a new state. Use this to add further complexity to your behaviors.

  2. func exit():

    Similarly, _exit() is called when the State is being switched away from. Use this to cleanup any lingering behaviors, signals, or variables you assigned during the State runtime.

  3. func input(event):

    Hands off _input(event) calls down to the State. These only fire when the State is active.

  4. func process(delta):

    Hands off _process(delta) calls down to the State. These only fire when the State is active.

  • Extend these functions to build behaviors in your FSM.

  • In addition, two variable references are passed down to States by the parent StateMachine:

  1. var machine

    A reference to the parent StateMachine. Use this to switch states from within a given State node.

  2. var target

    The object utilizing the state machine. Set this to your Player, Enemy, or whatever the States will target. This variable must be explicitly passed to the StateMachine during it's _ready() function.

Examples

  1. An Idle/Walk State
extends State

func enter(msg = {}):
    # Use asserts to confirm the target object fits with your code requirements
	assert(target is ActiveCharacter)
	target.strafe_changed.connect(update_anim)
	update_anim(target.strafe)

func exit():
	target.strafe_changed.disconnect(update_anim)

func get_strafe() -> Vector2:
	return Vector2(
		Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), 
		Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
	)

func input(event) -> void:
	target.strafe = get_strafe()
	
    # If you want accessable methods for all your states, it's useful to put them
    # in the parent object itself.
    # You could also extend an existing State and leverage a previously written function.
	if(event.is_action_pressed("interact")):
		await target.interact_nearest()

func get_anim_dir(strafe):
	if(strafe.x == 0 and strafe.y > 0): return "_d"
	if(strafe.y < 0): return "_u"
	return ""

# This animation code is nice and contained within this single state.
func update_anim(strafe):
	var is_moving = strafe != Vector2.ZERO
	var anim = "walk" if is_moving else "idle"
	anim += get_anim_dir(target.look)
	
	target.sprite.play(anim)
  1. A Special Interaction State
extends State

# Player movement and input is disabled, await completion of terminal input 
# before restoring control

func enter(msg={}):
	assert(target is Active)
	var terminal = msg.get("terminal",null)
	
	if(not terminal):
		machine.pop_state()
		return
	
	target.sprite.play("typing")
	await terminal.control_finished
	machine.pop_state()

Notes

  • This is my personal library that I use for my games, and is WIP. (Use at your own risk).
  • If you find any major bugs or problems, let me know in the Github Issues and I'll try to fix them.
  • There is a danger of things breaking if you don't keep track of how many states you've pushed or popped, and I'm pretty sure my implementation breaks some rules about how the 'pushdown automata' strategy should work. Therefore, if you want the most vanilla FSM experience, just stick with the 'set_state' function.

godot-pushdown-fsm's People

Contributors

ccriddler avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.