playMaker

Author Topic: Improving The Workflow  (Read 9896 times)

Thore

  • Sr. Member
  • ****
  • Posts: 480
Improving The Workflow
« on: September 15, 2017, 03:40:30 PM »
It can be hard to keep an overview, once there are dozens of FSMs buzzing and sending events and variables around. There are also ways to make it easier, or more fun, to work with it all.

Here are a couple of workflow tips that will help you, or inspire you to manage your project and will help you staying on top of the ever-growing list of FSMs.

Renaming Actions
On Windows, you can press F2 to rename items (folders in Explorer, Game Objects in Unity, also paths in the animations, …). Did you know that you can rename actions, too? Place the action you want to use, then press F2 (or double-click) and rename it to something that gives you an idea what it does in your context. You can make the action list more intelligible and less abstract this way, almost like pseudocode. However, this makes it more difficult to see what the original action name was. Don't despair. Just hover over the little book icon and the tooltip tells you.

As pointed out by djaydino below, be mindful when working in a team. You can of course keep the action name, and just add to it, e.g. "Get Game Object: Player 1" or if it's obvious from context "Get: Player 1" and you have the best of both worlds.

Floating Labels & Headlines
This is more of a hack. States are also simply boxes with a name on it and a (possible) comment box underneath. You can appropriate them as a headline and paragraph, or as a floating label.

Place an empty state not connected to anything, and colour it (right click on state) with a colour used only for that purpose. That way you can tell these non-functional bits apart more easily. Now name them, and place them anywhere you like. You can add a kind of headline to functional parts of the FSM, for example.

Incoming Event
Let's suppose you have a state where you GET variables from somewhere else, or you read from a script. In other words, the FSM relies on incoming information. This is hard to see in the graph overview. How about using this hack in a similar vain as the floating label.

Create an empty state floating in thin air. Add an event like "Send Variable" or "From Script" to it, and connect it to a state which actually gets the variable from somewhere else. Colour both the state and the link, perhaps use the circuit link style to make it stand out from functional bits. Now you have something similar looking as a global event "coming in", but you can name the state and the event anything you like, and see clearly where variables are injected.

Tagging Nomenclature
I use some simple keywords I'll add into the states "description" field (in the State tab), like #Anim, #Send, etc. I use these to tell me straight away where dependencies are. I then see where, for example, animation events are send off. Short tags do the trick, and are fast and better to comprehend than longer explanations.

Global Events ALL CAPS
Global events are typically named uppercase. That way you can quickly tell them apart, and there's no issue with uppercase spelling (e.g. was it "turn on" or "Turn On"? It's "TURN ON")

Comment Action
Did you know there's an actual comment action? It's very useful to add information inside the states without cluttering up your graph.

Comment Action Dividers
Since you can rename actions, see the tip above, you can rename the Comment action into _______________, +++++++++++, ###########, ..................., ————————, ––––––––––––, --------------- and so on. Now you can structure your action list that way. Neat, isn't it?

Comment Action as Headline
Especially when you want to keep your graphs clean, you'll cram a lot of actions into one state. To still keep an overview, you can place Comment Actions, switch them off (just to be sure) and name them like /// EVERY FRAME /// etc. this way, you can group a block of actions with a headline.

Documentation URL
I haven't used that feature yet. However, the FSM has an option to include documentation right on the FSM tab.

Colour Coding
You can set up additional colours in the playmaker preferences and colour states and even the links (also separately). I sometimes succumb briefly to colour, but refrain from doing it, unless to draw attention to something. If every FSM looks like a rainbow, you have no clarity. Other users (see comments below) use them to differentiate whole groups of states.

Color Naming
You can name your colours and add new ones in the preferences, and that way determine more precisely what they mean. If you call the colour "WIP" (work in progress), you will probably use it consistently, and you will also see in two years what Red was supposed to mean.

Grouping
You can switch on grid snapping which makes structuring and arguably grouping better. Obviously, you can move the states around and group them. Use this for your advantage. Arrange the states of loops close to one another, then leave some nice distance to the next functional block, that way you can keep a good overview even in one FSM that does many things. Forget about symmetry and other such superficial criteria. Think of the FSM to flow top-down, for example; or from left-to-right -- whatever serves your purpose.

You can also control on which side the link arrows come out, by selecting the transition, hold CTRL and then left/right arrows to lock them in place. While I am at it, CTRL+Click on a state creates a FINISHED transition. CTRL+dragging out the link creates a new state that's already connected to the transition.

Naming Conventions
You have a VampireEnemy, and a SlimeEnemy? It may be better to adopt a general-to-detail naming convention for your variables. EnemyVampire, EnemySlime, etc and they are listed next to each other. Using space seems to create no problem, like "Enemy Vampire"; no need for clunky_names. Commonly, variables are also typed like enemyVampire (first lowercase, then every new word attached, starting uppercase). This convention is interpreted in Unity Editor as separate words when used in scripts (enemyVampire makes "Enemy Vampire").

FSM Paths
Name your FSM for example "Gameplay/Jumping" and you'll see in the FSM navigation bar right above the graph view, how it is now tucked inside a menu point "Gameplay". You need to keep this in mind when referencing it.

Watermarks
Right click on the graph view and set a watermark. You can add your own graphics into the folder and use them. Depending on your game, it can give you another quick and visible bit of information. Differentiate game logic FSMs and those that are for UI or effects, maybe. You can mark critical FSM, or use it as a stamp to assign ownership of the FSM when you work in a team (alien-head means Alice is responsible for this FSM). Maybe your game has two opposing sides pitched against each other, with nearly identical FSMs: watermark the sides. Watermarks can also be coloured images. I use this to mark FSMs with player input (movement, jumping, controllers etc). 

Variable Categories
When you select a variable, you can also set a category in the variable tab. Categories you once typed in, appear behind the tiny arrows next to the input field in subsequent variables. That makes it easier to keep the categories consistent. The same tip as above: don't succumb to categorize just because you can. The most important categories you want to use is Runtime and Config. In Config, you put those variables that you need to adjust; variables that are given. Into Runtime, you group all the variables that are overwritten and used for computation when the game is running (where it is pointless, or even game breaking when you adjust them).

On-the-Fly Variables and Events
A small workflow tip. You probably noticed that you can define variables and events right in the action. You find the option in the small dropdown menu where you set them. Once you do define an events there, a red box is popping up, telling you that no transition exists with that event (since you haven't yet added it). If you click on this box, it will create the transition on the fly. This happens when you pick an event that has no transition yet, and it's the fast way to populate especially switches that call for great many events. If you ever want to define ten types of events to use later, stop right there, and mind this trick.

Generic Events
(Non-global) event names don't have to be unique. You can create new events for each state individually ("go to jump"), but you can save some time if you pick more generic names, like Do, Next, Done, Fail, True, False, etc. The state only cares about the events as set in it.

Global Event Tricks
When you send a global event to an FSM, it will find it, and induce the flow there, no matter where it is. For this reason never use global events for anything other than to specifically communicate "globally". But you can also use this inside one FSM. Suppose you anyway use a global event called "AWAKE". Instead of looping back with a link, you can also send AWAKE to this same FSM, going back. This might be useful when your FSM is large and you want to "jump" from one place to another. Watch out, though, it might be a sign that your design is too much spaghetti, and perhaps needs to be broken up.

Shortcut Method Do Once
That's more a design pattern. Many actions do their thing. Then they trigger an event when they are done, or when some condition was met. You can often times leave the events not filled in, say Float Compare, only care about whether the float is smaller, and ignore equal and greater. You can take advantage of this fact, because this is good shortcut. That means, when you place such actions further above in the list, and they get triggered, the rest of actions down below will be skipped.

For example, you want that the actions below are only triggered once. But the sends keep coming in, constantly retriggering the FSM. Place a bool test with a variable that stands for "did we do this already?" on top. If true, do event "Skip". At the very bottom or in a subsequent state you set the variable "Did we do this already?" to true. Hence, when the list was used once, it's set to true, and when the chain is triggered again, the bool on top will recognize this and skip the rest. Later you need to reset the bool to false again. Take advantage of this to create a short cool-off period of retriggering events.

Think Ahead
It can be useful to get a fresh beverage and open a simple txt editor and type out what you exactly want to achieve. What kind of elements do you probably need? Are there different ways to solve the problem? Can you make it simpler with less dependency? Also, think about what exactly your mechanic is trying to solve; what gameplay purpose it will have? It might seem silly, but you should think whether your platformer really needs jumping, for instance. Imagine seriously how a game would be like without that mechanic (this is also great to get innovative games). Consider also inverting the problem, if you cannot trigger something, can you untrigger it? You measure from player to obstacle, how about from obstacle to player? etc. Make this a habit, and you have some clarity when you approach the situation.

Do the Research
Unless you know exactly what you're going to do, check some resources to give you a good turbo start on the frequent problems; get a glimpse of what kind of variables you probably need; and perhaps even find detailed talks, papers or videos on such seemingly simple things like jumping or camera movement (here, here) in a platformer -- stuff that is going to put your game above the competition when implemented with some juice.

Perhaps this is useful to some people. :) Please add your own ideas, or comments below!

EDIT: expanded a bit, made some improvements to the text.
« Last Edit: September 19, 2017, 08:18:37 AM by Thore »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7615
    • jinxtergames
Re: Workflow: Documenting, Commenting, Naming etc.
« Reply #1 on: September 15, 2017, 09:15:32 PM »
Hi,
great explanation!

For Renaming Action i tend to write in the comments on the state what going on.
but if i need to, i tend to rename them like this : "Action name = action description"

it is not so good to change the action names, especially when you are with more people on a project or when you need to ask help on the forum with pictures :)

Also i tend to use colors for grouping actions.
Maybe one day Playmaker will have grouping option (like unreal's blueprint group)

thank for this nice explanation.

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Workflow: Documenting, Commenting, Naming etc.
« Reply #2 on: September 16, 2017, 07:48:18 AM »
Thanks djaydino!

Incorporated your remark above, good point! And I added a few more that came to mind: Colour Naming, On-the-Fly Variables and Events, Generic Events and the Shortcut Method.

Plancksize

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 75
Re: Improving The Workflow
« Reply #3 on: September 18, 2017, 10:45:42 AM »
Excelent post.

Just to add something:
Quote
FSM Paths
Name your FSM for example "Gameplay/Jumping" and you'll see in the FSM navigation bar right above the graph view, how it is now tucked inside a menu point "Gameplay". You need to keep this in mind when referencing it.

This also works with Variables. If using Path/Var as var name (it can have several sub-menus), you'll find that when using the var drop-down in actions you'll get a menu/submenu for those vars.
I use that a lot to contain specific Globals under their own category. :)
« Last Edit: September 18, 2017, 10:50:17 AM by Plancksize »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Improving The Workflow
« Reply #4 on: September 19, 2017, 02:42:20 AM »
Hi,

 This could go on the wiki actually. Thore, w can add you to the wiki authors, would you like that?

Bye,

 Jean

NateGallardo

  • Playmaker Newbie
  • *
  • Posts: 31
Re: Improving The Workflow
« Reply #5 on: September 19, 2017, 06:42:43 AM »
This is a great guide Thore!

I have a couple of small points to add:

Colours
I use colours religiously! I disagree with Thore here, but obviously it's completely subjective personal preference. I use colours to group states that are related in some sense, as well as placement. This helps me to understand the graph at a glance, and enabling coloured links also helps in busier graphs where links overlap to see what is feeding into a state.

I also use a couple of custom colours for very specific purposes. For example, I always user Error states where appropriate, usually with DataMaker and ArrayMaker actions. I always name these sequentially, and they're always red. I too use magenta for WIP stuff!

Pins
As we all know, complex graphs can become tricky to keep tidy at times. I use  empty states, named sequentially starting with Pin 1 and exclusively coloured black, to feed transitions into so that I can force links to move cleanly around states rather than cross over them. In the absence of a true 'pin' function in Playmaker this works really well! I don't know if I'm explaining that very well so I'll pop up a screenshot later.

Mouse Shortcuts
I switch obsessively between curvy and square links and between left and right transitions to keep my graphs tidy. So I created a few macros in my mouse software to allow me to toggle between curvy/square and left/right with a single button press. 

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7615
    • jinxtergames
Re: Improving The Workflow
« Reply #6 on: September 19, 2017, 07:18:45 AM »
hi,
One more to add, for action that have an error event :

Make state and set a global transition.
Inside the state you can (optionally) use the action "Get Previous State Name" and then you can use a set text to show the state.
This is good for debugging on devices.

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Improving The Workflow
« Reply #7 on: September 19, 2017, 07:40:23 AM »
Hi,

 This could go on the wiki actually. Thore, w can add you to the wiki authors, would you like that?

Bye,

 Jean

Sure. :)


Pins
As we all know, complex graphs can become tricky to keep tidy at times. I use  empty states, named sequentially starting with Pin 1 and exclusively coloured black, to feed transitions into so that I can force links to move cleanly around states rather than cross over them. In the absence of a true 'pin' function in Playmaker this works really well! I don't know if I'm explaining that very well so I'll pop up a screenshot later.

Thanks for the reply. I'm curious about this one! Screenshot would be very nice.

MajorIdea

  • Full Member
  • ***
  • Posts: 131
Re: Improving The Workflow
« Reply #8 on: October 17, 2017, 11:26:22 AM »
This is really good. Thanks a lot!

One question though - I don't know how if this is true but isn't placing a bunch of empty states as labels going to affect editor performance? It usually shows a warning when we have too many states in an FSM.
« Last Edit: October 17, 2017, 11:31:03 AM by MajorIdea »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7615
    • jinxtergames
Re: Improving The Workflow
« Reply #9 on: October 17, 2017, 11:52:27 AM »
Hi,
When there are no actions/transitions inside them i believe they should not affect any performance.