Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a graphical representation of the state chart for easier analysis #72

Open
LucasArusiewicz opened this issue Jan 4, 2024 · 9 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@LucasArusiewicz
Copy link

Overview

Recently, I've extensively used and tested the plugin, creating prototypes and more. However, after validating a mechanic, I realized that I had used an inappropriate name for an event, violating best practices and clean code principles. I went ahead to rename the event, which proved to be a bit tedious. While changing the code was straightforward, manually updating event names in all states was necessary.

After completing the renaming process, everything continued to work normally. Nevertheless, I identified an opportunity to enhance this aspect by abstracting and simplifying it within the plugin. My suggestion is to introduce an option for event registration, allowing users to select registered events or enter. If an event is selected, it would only update the String value. In principle, this way would have a more user-friendly interface and would maintain compatibility with existing projects.

Visual State Construction

I also asked myself whether it would be possible to create a visual aspect of the State construction stage. In my research into graphics, I came across stately.ai, a tool with an interface that I really liked. I wondered if the plugin currently has a level of abstraction that allows the implementation of an interface using Godot's GraphEdit (Note: I haven't delved into the plugin's source code yet).

Comments and suggestions

  • Introduce a step to register events, allowing users to select events in addition to manually entering their names.
  • Would it be possible to create an interface inspired by stately.ai to build and visualize the StateChart?

I look forward to your feedback on these suggestions and appreciate your efforts in improving and maintaining the plugin.

@derkork
Copy link
Owner

derkork commented Jan 4, 2024

Hi Lucas, thanks a lot for taking the time to write all this. I agree that the string events are not ideal but given we need to interact with it from code, it's about the only thing we can do here. I can think of a few things to improve handling here:

  • the event field in transitions gets an auto-complete that provides a list of all event names currently in use within the state chart. this would minimize the chance for a typo and could also speed up editing.
    image
    i'm not sure if the godot UI can do this, I will have to investigate. Doing it this way would make the event registration implicit without adding extra steps to the workflow.
  • a new tool is added that allows to rename events that are used within a state chart: Snapshot
    this would make it quick and safe to rename all occurences of an event in a state chart and the editor has all the information to safely do it. You'd still need to rename the code occurrences.

Now for the visual editor. I totally get the appeal of it and I'm a big fan of visual editing - I made OpenSCAD Graph Editor. I still decided against doing it for a few reasons:

  • Godot's graph edit does not provide the necessary functionality to do it. While we can do flat node graphs pretty fine, we currently have not anything that would allow us to represent compound/parallel states. Something like this could potentially be added but it would require a good amount of work, especially for layouting the hierarchy when you move nodes in nested states around.
  • In general editing of nested state hierarchies is not very efficient in a diagram. I built the state chart for the platformer frog in stately.ai and while it was reasonably quick to set it up, doing it with nodes was a lot quicker as I don't need to layout the graph by hand all the time. In addition there is no real nice way to move a state from an inner nest level to an outer level while keeping its transitions e.g. like this
    image In a node tree this is trivial, i can just drag around nodes to a new parent.
  • Nodes are already a familiar concept for users of Godot as almost everything is a node in Godot
  • Nodes allow you to use the built-in features for scene composition and inheritance to make your state charts - or parts of them - reusable basically for free.

Finally, the amount of code needed for graph editor would very likely exceed the amount of code needed for everything else (I've got some experience on that with the OpenSCAD Graph Editor). I feel, that this time can better be spent elsewhere (for example this event name refactoring you suggested), especially given that a graph editor would not even be a better editing experience. What are your thoughts on this?

@SirPigeonz
Copy link

My experience with many different state machines both in Godot and Unreal show that Graph view is not that usefull if they don't support features that Godot Scene system already supports (and usually they don't). Those would be instancing, hierarchy, API to manage nodes and their flow through scripts and serializableto file modules.

I realy like current approach that State Charts uses. It's compact, fast to edit, easy to reause, modular and easy to extend.

Only two things I miss is refactoring tool for events, or the possibility to use predefined structure containing events, that would also help with maintaining documentation for State Trees.
Second one is a tool to better visualize transitions relations. Unfortunately Scene system is only good to visualize hierarchy, signaling and events are better viewed in graph form. Maybe separate debugging tool based on graphs similar to the one in Beehave?

Thanks for a great add-on! 😁

@officiallyaninja
Copy link

What are your thoughts on using nodes instead of strings for events?
You could have a new Event Node that would be a child of StateChart (or possible another new Events Node) that is used to send events.

So instead of doing

$StateChart.send_event("attacked") 

You could create an Attacked Event Node, and then do

$StateChart/Attacked.send_event()

Or something like that.
And then the event field will allow you to select a node, and renaming it shouldnt cause any issues. (assuming you use export vars instead of directly naming the nodes using node paths, but that's a common issue with node paths all over godot)

This also has the benefits of having all the events in the node tree, so you don't have to remember all rhe events that you've defined.

@derkork
Copy link
Owner

derkork commented Jan 6, 2024

I have a feeling this would introduce additional problems. Right now the problem is that we may have a typo in our event names somewhere. If we replace this by nodes we get additional sources of problems:

@onready var _my_event:Event  = $Graph/MyEvent  

The node path is essentially also a String which may have a typo. In addition this will break if we move the event nodes around or rename them. We could also export nodes/nodepaths like this:

@export var my_event:Event   
# or 
@export_nodepath("Event") var my_event:NodePath 

This would fix the typo problem and would also potentially be auto-fixed by Godot when you move nodes around, but you still may forget to select an event in your export (which will then produce a null problem) or you may even select an event from a different state chart than the one you are working with.

Also this would be detrimental to the usability of the library, you now need to create extra nodes and reference them just to send an event to the state chart. Finally this would be a breaking change breaking all existing projects out there. So I think providing an explicit refactoring for the event names and giving some autocomplete to prevent typos is less invasive and will hopefully not introduce additional sources of errors.

@LucasArusiewicz
Copy link
Author

Hello @derkork , thank you for the feedback.

I really liked the autocomplete idea for the event field, but I believe there's nothing ready in Godot to implement this UI. I explored Godot a bit and found a trick using VSCode to refactor event names. Since scenes are not binary, VSCode interprets them as code and finds the references correctly, so it's just a matter of replacing them with the new value.

VSCode screenshot

I like the idea of having the option to refactor event names through the plugin itself. After some thought, I think we can design it similar to Godot's group manager.

Godot group manager screenshot

Keeping things as simple as possible seems interesting to me. Representing events as just a string seems like a good option, essentially making it a tag. This simplifies the use of the plugin, similar to Godot groups. Godot has the Group Manager, which has an interface that displays indexed values (nodes present or not in a group) and facilitates batch editing.

Bringing this to the context of the plugin, it could be a list of registered events, transitions related to the event (perhaps even an option to add/link a new transition), and scripts associated with the event. From what I've seen, fetching and editing this information seems straightforward. The idea is to have something that facilitates batch editing of events and possibly expand to other plugin operations in the future.

Graphical Editing

Regarding graphical editing, I hadn't paid attention to the details of data representation. What I had in mind was a visual representation of the tree. A correct visual representation of NinjaFrog would look like this:

Diagram screenshot

While practice and a well-defined approach may make it faster to create through nodes, having a visual representation could make it easier for some users. In more complex scenarios, visualizing and editing through Godot's node tree can become challenging. I moved almost all conditions and states of the player to the StateChart in one of my projects. The code became clean, but in the tree, I have 73 nodes, including CompoundState, AtomicState, and Transition. Collapsing the editor and looking at one at a time is fine, but understanding the overall context and how states relate would be easier in a graph.

Is there perhaps something already available in the Godot ecosystem? Like a tree editor – the Beehave debug seems somewhat like that, but I haven't tested it.

I understand that the visual aspect is extensive to program, but I believe we can define how it could be included in the plugin and identify the steps needed to complete it. As more people express interest in this feature, they could contribute to the plugin's development.

I am someone who, in my spare time, could easily program one thing or another and over time it would end up being ready, but if there were more people willing to help it would be great 😁

@derkork
Copy link
Owner

derkork commented Jan 7, 2024

Autocomplete may actually be possible. There is nothing built in, but with a bit of event handling and custom drawing it might just work...

2024-01-07_22-54-06.mp4

Still need the selection but looks definitely doable.

@derkork
Copy link
Owner

derkork commented Jan 12, 2024

Okay, so the autocomplete idea didn't materialize after all, the issue is that while I can totally draw a completion popup, I cannot really detect the mouse on it. So I settled for a popup, which basically does the same thing and since it also supports typing it's almost a typeahead. I also added a facility to rename events together with full undo/redo support.

2024-01-12_22-04-33.mp4

I think this is already a nice improvement over the current status and i prefer a workable solution that I can have now over a perfect one that may never come.

@officiallyaninja
Copy link

I prefer this over (just) a simple autocomplete imo being able to view and edit the events in the popup is a huge improvement

@derkork
Copy link
Owner

derkork commented Jan 12, 2024

Released as 0.12.0. As for the visualization, I totally like the idea. However auto-layouting graphs is far from a solved problem. Most graph layouting tools I have seen produce abysmal results and not for a lack of trying. I actually have only seen one implementation that produces half-way decent results (yFiles) and this is both exceptionally expensive (licenses start at 22k€) and not compatible with Godot. So any ideas how a graph layouter could actually work?

@derkork derkork added enhancement New feature or request help wanted Extra attention is needed labels Jul 20, 2024
@derkork derkork changed the title A little feedback and suggestion Provide a graphical representation of the state chart for easier analysis Jul 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants