New Flowcharts feature in r370

1 favourites
From the Asset Store
Create your game with this complete pack of images and animations!
  • Introduction

    Starting with r370 we are introducing a new feature, Flow Charts. In the editor, a flow chart allows you to:

    1. Create nodes
    2. Add arbitrary data to those nodes
    3. Stablish logical connections between the nodes

    Later, at runtime, it is possible to create multiple instances of a flow chart and use the new Flowchart Controller plugin to navigate through the nodes. Each instance will keep it's state independently, namely the current node.

    Since event sheets are the main method of managing any kind of logic in C3, flow charts themselves don't have any functionality to perform logic, instead they only serve as data holders and to model the connections between the nodes. Any logic that can be associated with the current state of a flow chart is handled by events.

    Possible applications

    This kind of data structure can be used to model any kind of system that might look like a tree structure, like dialog trees, skill trees or quest trees in an RPG. It could also be used as a state machine to manage the logic behind objects in a game that have moderately complex behaviours, like a boss or mini boss would have in a shoot 'em up game.

    Those are just some examples I could come up off the top of my head and certainly not the only applications.

    Creating a flow chart

    To create a flow chart, just do so through the Project bar by bringing up the context menu in the new Flow charts sub folder and selecting the Add Flow chart option.

    Editing a flow chart

    Double clicking on a flow chart item in the Project bar will open a new tab with a Flow chart view where it is possible to edit it.

    Some of the basic editing options are the following:

    Adding nodes
    The context menu that comes up by clicking on any empty space in the flow chart will have the "Insert node" option, which will create a new node in that position.
    Deleting nodes
    The context menu that comes up by clicking on any empty space in a node will have the "Delete node" option, which will delete the corresponding node.
    Adding node outputs
    A newly created node has one output, which has a name and a value. By clicking on the "Add" link at the bottom of a node, it is possible to add as many outputs as needed to a node.
    Deleting node outputs
    A node output can be deleted by bring up the context menu of the output and choosing the "Delete output" option. Nodes must have at least one output.
    Edit output name
    The name of an output can be edited by double clicking it or by bringing up the context menu and choosing the "Edit name" option.
    Edit output value
    The value of an output can be edited by double clicking it or by bringing up the context menu and choosing the "Edit value" option.
    Connecting nodes
    Each output of a node can be connected to the input of another node. To do so:


    1. tap and hold on the starting input or output icon

    2. drag to the other input or output

    3. release the pointer device

    Disconnecting nodes
    Connected nodes can be disconnected by bringing up the context menu option in the corresponding input or output and choosing the "Unlink" option
    Edit a node's tag
    Every node has a tag property which can be used at runtime to identify it.
    Sorting outputs
    By tapping and holding an output and then dragging it it is possible to give it a different position in the node.

    Asides from those options, nodes can also be moved by tapping and holding the caption of the node and resized by tapping and holding the borders of the node.

    Moving and resizing is limited by other nodes.

    Properties Bar

    The Properties bar shows another view of the properties of a flow chart and more importantly the individual nodes. At the moment of writing there is only one option which can only be edited through the properties bar and not the nodes themselves.

    That is the "Start Node" property which indicates which should be the default starting node when a new flow chart instance is created at runtime.

    Using any of the "Reset" actions will also set the current node of a flow chart as the one set as the starting one.

    Flow chart controller plugin

    The plugin is used to instantiate flow charts at runtime, navigate through them, extract data and eventually release them when no longer needed.

    Actions

    Start flow chart & Start flow chart by name
    Used to instantiate a new flow chart from the ones defined in the editor. The newly created flow chart starts at the node defined as the starting one. A tag needs to be passed when starting a flow chart to be able to control it later.
    End flow chart & End flow chart by tag
    Used to release all resources associated with a flow chart. The first action releases the currently active flow chart, while the "by tag" variant allows you to release any other flow chart.
    Reset flow chart & Reset flow chart by tag
    Reset a flow chart to it's initial state. The first action resets the currently active flow chart while the "by tag" variant targets a specific one. The current node is set as the one marked as the starting one in the editor.
    Set flow chart
    Sets a flow chart instance as the currently active one. Other actions, conditions and expressions will work according to the active flow chart. Some expressions can receive a flow chart tag as argument to work according to that specific flow chart rather than the active one.
    Go to next node
    Uses an index or a name and will follow the corresponding output into the next node.
    Go to any node
    Uses a tag to just jump to that node ignoring all connections.
    Go to previous node
    Goes to the previous node that was navigated to with one of the previous actions.
    Go to parent node
    uses an index or a tag to go to the parent of the current node. In this action the index or tag is only meaningful if a node has more than one parent.

    Conditions

    On any flow chart change
    Triggered when the current flow chart changes.
    On any node change
    Triggered when the current node changes.
    On tagged node change
    Triggered when the current node changes and it's tag matches the one specified.
    On tagged node change by flow chart
    Triggered when the current node changes and it's tag matches the one specified, in the flow chart specified.
    On any node change by flow chart
    Triggered when the current node changes in the flow chart specified.
    Is at start node
    Check if the current node is the starting one.
    Is at start node by flow chart
    Check if the current node is the starting one, in the specified flow chart.
    Has flow chart
    Check if the plugin instance has a flow chart for the specified tag.

    Expressions

    GetCurrentFlowchartTag
    Get the tag of the current flow chart.
    GetCurrentNodeTag
    Get the tag of the current node in the current flow chart. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeOutputCount
    Get the number of outputs in the current node of the current flow chart. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeOutputNameAt
    Get the name of an output in the current node of the current flow chart. Pass in an index or a name as argument. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeOutputValueAt
    Get the value of an output in the current node of the current flow chart. Pass in an index or a name as argument. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeParentCount
    Get the amount of parent nodes the current node in the current flow chart has. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeParentTag
    Get the tag of the parent of the current node in the current flow chart. In the case of having more than one parent an index can be specified to choose which tag to get. An optional flow chart argument can be passed to get the same value of another flow chart instance.
    GetCurrentNodeParentIndex
    Get the index of the parent of the current node in the current flow chart. In the case of having more than one parent a tag can be specified to choose which index to get. An optional flow chart argument can be passed to get the same value of another flow chart instance.

    Example project

    Lastly, make sure to check out the example browser for the new example, it is a moderately complex project, showing a possible use for this new feature. It is exactly 50 events, so it will work on the free edition.

  • would it be possible to have links back to previous nodes? also will nodes only be able to have one input?

  • Would it be possible to create a special "Linked Flowchart" Node ? with a clickable button to open the referenced other flowchart.

    Currently, the way we have to do it is creating a custom logic with ACE. Everything is string based and it's difficult to navigate from one flowhcart to an other within the editor, must go to the bottom of project view everytime, looking for the right flowchart etc. Here is how it is in the example.

    Would be cool if we could actually reference actual flowcharts directly in a new Node Type.

    Referenced flowcharts could also have a list of all the backlinks of other flowcharts referencing them.

    So we could easily naviguate from one flowchart to an other (from referencing to referenced AND from referenced to referencing), it would enhance the UX a bunch.

    HOWEVER : We should still be able to change those new "flowcharts output" by name/string at runtime thanks to new ACE for more flexibility, in addition to new dropdown list ACE

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Thank you for your great work!!

    I think it would be perfect for a game like Choice of Life: Middle Ages and Yes, Your Grace and Sort The Court and Pilgrims

    ----

    I have a few polishing ideas:

    • New r373

      8. When Output is selected, the context menu use 'Remove' output to distinguish 'Delete' Node options

      I had a bold idea, if Flowcharts can work like JsonCrack?

      jsoncrack (github)

      1. Add a format button, Automatically sort node, no need to manually organize spaghetti.

      2. displayed as JSON (without editor node data)

      the editor's zoom and search functions also make sense.

      1. Zoom to fit

      2. Collapse Nodes

      3. Focus to First Node

      4. Search Node

    • Tab 1

      Content

    • Archived

      7. If the node can be named, it will help better manage the flowchart page

      6. Allow top-down organizational structure (Flowchart properties)bold text

      5. Context Menu on Out component Add a 'Go to' function, allowing the editor to focus on nodes.

      4. importing/export the flowchart AsJSON for external editing. If it can converted to data files, it would be even cooler! people can write flowchart data from external excel and import it into the flowchart with just a simple work.

      3. Allow 'Add Output' in the property bar (like add instance variables) which can better utilize the working habits of Construct

      the same context applies to nodes

      2.delete confirmation

      1. When dragging the node, keeping the output width small, But rather drag the column of Value.

    -

  • piranha305

    It is possible to connect multiple outputs to the same input.

    As for connecting back to the first node, I decided to leave that for a future update to get something out. The obvious problem is that it produces an infinitely recursive structure, which usually is something you have to avoid.

    Overboy

    I noticed it would be a useful feature as I was building the example. I wanted a way to directly connect to an entire flowchart from an output in order to be able to neatly chop up a large flowchart into many smaller ones, I couldn't figure out a way to do it cleanly and most importantly quickly. So I decided to just leave it for a future update and make the example showing what you could do with the simple available options.

  • XHXIAIEIN

    1) I though about that myself, but because I spent more time than I would have liked just getting it to do what it is doing now. I though I would leave that as a future improvement.

    2) You should be able to undo the deletion of a node if it happens on accident. I think that is much better than a confirmation dialog.

    3) I actually didn't think about that the first time around. Will consider it for the future polish updates the feature will get.

  • "Infinite loops" (looping Flowcharts) make sense for all kind of State Machines/FSM that could be used for AI Behaviors, Game States, and UI state. (but also for creating complex Platformer/Movement behavior or that kind of stuff)

    Great to know backlinking nodes and referencing flowcharts directly are considered for future updates !

    Here are a few screenshot of a cool Node-tree tools using Actions and Conditions called Game Creator 2 (and its module Behaviors), I think those would be inspiring for C3 Flowcharts

  • XHXIAIEIN

    4) I definitely did not think about that last one. I don't think it is necessary though.

    In the example the output values are used as raw text, but they don't need to be used like that all the time. They could be ids to a dictionary. With a few events it would be relatively easy to pick up the real values from the dictionary using the ids from the node outputs.

    I think that's a reasonable and scalable solution that can be implemented in any project right now, no need to wait for us.

    5) That sounds like something that might be pushed for later updates because there are already more important things to work on, but maybe if we don't get flooded with requests I might get around to do it.

  • In the example the output values are used as raw text, but they don't need to be used like that all the time. They could be ids to a dictionary. With a few events it would be relatively easy to pick up the real values from the dictionary using the ids from the node outputs.

    I disagree on that point, because being able to save and load flocharts at runtime would be amazing for moddable content. Also in some languages it might be required to split a given dialogue message into 2, or remove one option entirely (for any reason that might occur during localisation) and having the option to have separate flowchart files one can load can come in very handy.

    Although, for most projects linking to a dictionnary will still be the best use case, having the alternative would be great!

  • XHXIAIEIN

    6) Allow top-down organizational structure (Flowchart properties)

    I don't think that will happen.

    When I first started developing the feature, the diagrams I drew on paper had the outputs at the bottom of the node and the input on top, instead of the left and right respectively. That is how most people would draw tree diagrams.

    The problem with that was that text fields are horizontal so having each output to the side of each name and value pair makes much more sense visually and because being on the side makes sense for the outputs, it becomes natural for the input to be on the opposite side rather than the top.

  • Looking forward to experiment more with it to figure out what new workflows this enables, thank you for this cool new feature Diego!

    first impressions of stuff I'd like to see added are:

    - linking back to parent

    - general ux/ui improvements and polish

  • This is a very exciting feature, thank you for the hard work on this.

    IMO the biggest issue right now is that it still requires us to create a tedious/complex backend using Eventsheets to actually use this new data formats.

    It requires us to create a bunch of Functions, use a lot of different ACE etc...

    Usually branching tools kinda automates some stuff for you

    Also we need to painfully handle infinite else if statements on triggers to do some special logic on each Nodes (playing sounds/displaying an avatar etc...), everything being a string and it's a spaghetti mess between eventsheet and flowcharts

    By coincidence, I very recently wrote a long forum posts explaining my thoughts about it with a detailed benchmark of other tools merging Action/Conditions with Node Trees.

    construct.net/en/forum/construct-3/general-discussion-7/ace-based-node-trees-creating-179570

    Especially Unity's 3rd Party tool suite called Game Creator 2 and not-yet-announced official Unity Tool called Muse Behavior.

    The excellent thing with the implementation you chose is that it's very versatile so it would be possible for Scirra to build very cool stuff/options to just make some of it works "immediatly" without requiring us to create all the complex backend (as the current example is doing).

    I know both the release note and this post present this new feature as a data-oriented feature but I do think the true potentail of that kind of feature would be achieved if it also allowed us to implement game-logic per node.

    ALLOW TO ADD A EMBED FUNCTION FOR EACH NODE

    • Basically each node would have a "Add Node Function" or "Open Node Function" button. (it can only have 1)
    • A node function is a "mini-eventsheet" directly embed in the Flowchart asset and that is executed as soon as this node is reached in the flowchart. In fact it's a Function-like single eventblock with its children. It can have any number of actions/Condtions/Subevents, but can't have any parameters. Under the hood it would be exactly the same implementation as a function except it can't be called via "call Function" action, it's only automatically called when the node is reached.
    • When we click "open node function" it would open a pop-up that looks like a more restrictive mini-eventsheet only displaying the Node Function.

    It would allow us to do crazy stuff with ease.

    Like playing a particular sound when the node is reached/setting a global variable or anything useful for any Quest/Dynamic Cutscenes/Dialogue/AI/Movement system.

    And it would avoid the need to handle the cases with Triggers events placed on Eventsheets that would create dependancies everywhere between actual Eventsheets and Flowcharts using Triggers that would ends up being a mess for big projects (Triggers are also useful but really embedding logic per Node would be amazing).

    NODE CONDITIONS (And node Types)

    this suggestion is built upon the previous Node Function suggestion

    • All conditions that are directly under the Node Function (so not in its own subevent but directly at the root) are the "Node conditions".
    • They could be the only ACE of the related Node Function that are also displayed directly in the flowchart. So it's more readable for state machines or conditional flowcharts.
    • There would be a condition to check if the current Node Condition are true (so no need to handle every single cases manually in Eventsheets), it's just done "automatically" by default.
    • There could also be different kind of nodes depending on how to choose the output.
    • The current default would be the "Manual" Node.
    • But there would also be other kind of Nodes such as "Choose" Node, that automatically finds the first Output Node which "Node Conditions" are true and play it immediatly.
    • There could be other cool stuff to think about regarding Node Types and Node conditions to automate some stuff.
    • Maybe also a "Sequence" Node ? that would execute each output node and it's branching in order until it reaches an end and then do the same for the next output node.

    Even if it's NOT what i'm describing here is a visual representation of the Quests Module of Game Creator 2

    EDIT : Node Conditions and On Node Enter should be 2 seperate Blocks on a "Node Sheet", along side with On Node Tick and On Node Exit, everything is detailed on a mockup on my next post here : construct.net/en/forum/construct-3/general-discussion-7/new-flowcharts-feature-r370-179833/page-2

  • I think the fundamental problem with adding the functionality to execute logic to nodes is that the more logic capabilities flowcharts had, the more they would overlap with event sheets.

    That poses two problems.

    The first is having two different ways to handle logic, which in on itself is not great because it would be confusing. Specially for new people. The immediate question someone new would have is "What are better, Event Sheets or Flow charts?" and the answer would inevitably be "It depends on what you are doing, both have pitfalls... bla bla bla" :)

    But the second problem is that Event Sheets are just better for programming and are Construct's way of doing things. Flowcharts could be used for small bits of logic, but they don't scale. If you have boxes connected with lines to handle logic, things become spaghetti rather quickly. I pray for the soul that has to debug that kind of visual systems.

    So, if the best practice is to use the feature for relatively small systems, I think it's ok to have to use event sheets to glue things together.

  • I have only briefly looked over it for now, but basically my wishlist aligns very closely with Overboy.

    1. Being able to link an entire flowchart into the out of a node, or reference it somehow else. But I think linking would be the best probably (?)

    2. Being able to enable/disable nodes based on some snippet of code. (If player has money, show "gamble" node)

    3. Being able to execute a snippet of code whenever a node is reached. (Play sound whenever node is reached)

    4. Being able to execute a snippet of code whenever a connection is traversed. (Remove 5 money whenever "gamble" is picked)

    4b. Being able to branch a connection based on the result of a snippet of code (If gamble won, if gamble lost,...)

    Nice to have

    5. Aligning nodes etc. to a grid, I like grids :)

    6. Every other row in the node could have a slightly darker/brighter color to make it easier to see the rows.

    I think this would do a lot of heavy lifting and tie together the flowchart closely with the logic that's supposed to drive it. Right now it's all raw data and strings which all have to be handled in a quite detached manner in the eventsheet. If I think about a larger project, this sounds daunting to work with.

    Quick mockup just cause. I think the "Eventsnippets" could theoretically just be a function in an Eventsheet, but I think it would be better if it were a mini-eventsheet as Overboy suggested.

    EDIT

    I think the fundamental problem with adding the functionality to execute logic to nodes is that the more logic capabilities flowcharts had, the more they would overlap with event sheets.

    I can see what you mean but I feel like these suggestions were almost inevitable :) There has to be a way to create a sensible interface between the two. Purely thinking of a text-adventure as in the example, I'd totally want to do things like "If the player is low health, show/hide this option" and "If the player picks this option, there's a chance that X will happen". Right now this would seem like a lot of frankensteining together flowcharts at runtime, and my gut feeling does not like that.

    For example, how'd you do a check for: "if (player.health < 10 && player.poisoned) showOption()". Currently a flowchart has two fields where we could convey this information we want to test for with the eventsheet. The name, and the value. The name doesn't really appear to be the right place for this. The value... maybe? But it would mean we have to write a JSON string into the value, then parse the JSON, then extract the intent what we want to check for with which values, call a function and if true, stitch in some flowchart. When with the other approach, we'd just have a field that says "condition" and we throw in a function that returns true or false, and if false the node is not shown.

  • For example, how'd you do a check for: "if (player.health < 10 && player.poisoned) showOption()". Currently a flowchart has two fields where we could convey this information we want to test for with the eventsheet. The name, and the value. The name doesn't really appear to be the right place for this. The value... maybe? But it would mean we have to write a JSON string into the value, then parse the JSON, then extract the intent what we want to check for with which values, call a function and if true, stitch in some flowchart. When with the other approach, we'd just have a field that says "condition" and we throw in a function that returns true or false, and if false the node is not shown.

    I 100% agree with this...

    being able to attach a condition to the flow chart weather that is thur some type of expression or a custom node or function? that handle conditions and branching based on that, it improves the eventsheet / flowchart workflow so much.

    having all the logic in event sheet adds a bit of context switching, and if your nodes for some reason dont share a common interface you could end up with a spaghetti of event.

    if there is a vote for much needed feature in flow charts... I vote for that one!

Jump to:
Active Users
There are 2 visitors browsing this topic (0 users and 2 guests)