This article is part of a series on Tips & Tricks for Adventure Creator. Last time we talked about project and scene structure, you can find the first article in the series [here]. If you’re only interested in this topic, you don’t need the previous article to be able to follow along.
This time we will talk about action lists in Adventure Creator. How to manage and reuse them effectively so you don’t make a mess that’s hard to read and even harder to add to. We’ll also share some of our “generic” action lists which we use often.
The series, in general, is most useful to developers with some Adventure Creator experience. We won’t explain what action lists are and we won’t go through the fundamentals since there are other places which already got that covered. So if you don’t know what action lists are come back after you took a glimpse and created a couple of them. And if you ever created even a single action list feel free to read on. Let’s go!
How to keep Action Lists manageable?
Did you ever create an action list like this?
If you think this is big, you’re not wrong, but it’s not even half of the list! We couldn’t zoom out more than this to show you the whole monster.
If you have big action lists, you know how daunting it is to debug or change them. It’s a zooming and panning party all day long. Once action lists gets too big they get unmanageable. So it’s time to break them down into smaller action lists and create one “master action list” which will reference and manage the smaller ones.
Break down the logic
It’s best if we break down action lists logically. If you have two big branches running in parallel, move them to separate action lists. If you have a long cutscene with moving, rotating and animating characters, split it into a start, mid and end action list.
It just doesn’t pay off to go with the mindset “I probably won’t need to come back to this action list so I don’t want to take another hour or two to break it down and rewire it”. Since the vast size of the monster chances are that you made a couple mistakes. If you have to come back to it multiple times, and you will, you will lose way more time if you leave it like that.
Create sub-action lists
If done right, some of the “sub-action” lists that we get after breaking down a big one can be reused later. So we kill two flies with one swat, both management and reusability. There are many ways you can break down your action lists and make them manageable, that’s simple. The core message here is to actually remember to do it and invest some time into it because it will pay back in many ways. Less bugs, less time spent on repairs and fixes and many cool options later in the development cycle. We’ll talk more about those options in a bit. The next section gives some concrete examples of managing your action lists, but it is focused on reusability.
How to make Action Lists reusable?
Have you ever found yourself adding an auto-save action or “fade in” action into an OnStart cutscene for 30 scenes? Or adding the same piece of logic in multiple places over and over and over in your project? If you’re using a visual programming tool like Adventure Creator, this can easily happen. Many situations like these can be avoided by doing some design in the earlier phases of your project development.
Identify key points and wrap them
Firstly, we need to identify repeatable points in your game, let’s call them “key points”. Key points could be points like scene start, scene load, scene switch, play dialog, save, open inventory, exit scene, pick up item, etc. And yes, AC already has predefined points where you put your logic for some of these situations. But what we want to do additionally, is create action list assets for these situations. Let’s call those “wrapper action lists”.
For example, let’s create a wrapper for the scene start key point. We create a StartSceneAL custom action list asset. If we want a fade-in effect at the start of every scene we put the fade logic inside of StartSceneAL. Now whenever you create a scene, in your OnStart cutscene call StartSceneAL first. Also, if you are using a scene template, and we highly recommend that you do, make it part of your template.
Adjust the wrappers as you go along
Some 20 scenes later we realize that we need to trigger auto-save on each scene start. We simply add the auto-save action in our StartSceneAL and voilà, we have auto-save in all our scenes. That’s why we need to identify as many key points as we can and wrap them. Scene exit, play dialogue, move and rotate character, pick up item, switch camera, all these points will have their corresponding wrappers; ExitSceneAL, PlayDialogAL, CharMoveAndRotateAL, PickUpItemAL, SwitchCameraAL.
Here are some examples of reusable action list assets from our game Bear With Me:
The next image is an example of using some of the mentioned action lists:
This is the OnStart cutscene. First, we execute SceneStartAL which does what has to be done on each scene start; auto-save and fade in. Then we use PlayDialogAL which will be explained later but basically, this action lists plays any amount of dialog. Then we move the character to a certain marker and rotate it according to that marker. After that our character picks up an item and then again we have some dialogue and in the end, we switch to another scene.
If we din’t use reusable action list assets this would have been a much bigger action list, harder to maintain, debug and extend. Reusable action lists shine the most when we have to manage complex logic, many condition checks and many branches. Keep in mind though that action list assets cannot use local variables, so you must design around that. Referencing scene objects might help with that and you can read more on the topic [here].
Let’s look at some of our most used action list assets (wrapper action lists).
Reusable Action List – Play Dialog
One of our most used action lists is PlayDialogAL. Every time dialog is displayed we use this action list. Here’s and example image.
If the player carries the Pamphlet item and the Keys item fell into the shaft, we play the ClarkTalkTo02 dialog. Else we play ClarkTalkTo01 or ClarkFiller01. Anytime we play a dialog we do it by running a PlayDialogAL asset file which receives a dialog action list as a parameter.
You can already see that all the dialogue in our game is broken down into chunks across many dialogue action lists, which are action lists that contain Dialogue – Play speech actions.
This image shows one simple dialogue action list which contains only Dialogue – Play speech actions:
Ideally, these action lists contain only Play speech actions and eventually animate actions which play character emotes. We sometimes put some simple logic inside them but that’s tricky. Sometimes we simplify the parent action list (master action list) by avoiding further granulation of dialogue and putting additional logic inside the lists. This is risky because debugging is harder when your logic is broken down across multiple action lists.
Back to the PlayDialogAL. This image shows a complete action list.
Let’s look in more detail
So what’s happening here? It’s pretty simple. First, we check if IsDialogSkipModeOn is set to false. This is a really cool feature which was possible because we identified the Play dialog key point and wrapped it up in this action list. We wanted to enable dialogue-free mode for speed testing the game. So we simply added a variable check in our PlayDialogAL and when we want to enable dialogue-free mode we set IsDialogSkipModeOn to true.
If the mode is disabled, we check the DoNotTurnOffInventory parameter, since usually, we want to disable the inventory display when the dialog plays. Finally, we turn on the subtitles menu which holds the subtitles canvas and we play the right dialogue action list which we passed as a parameter. In the end, we check if we need to turn off the subtitles canvas. If we marked this as positive, that probably means the dialogue action list contained the last sentence of a particular actor’s speech. This way we got rid of the subtitle flicker which was caused by rapidly turning the subtitles menu on and off for each Dialogue – Play speech action call.
This is a good example of how wrapping a key point into a custom action list pays off. Imagine if we wanted to get rid of the subtitle flicker or implement the dialogue-free mode in any of the later phases of development but we didn’t wrap the Play dialog key point in a custom action list? It would have been a hassle.
Reusable Action List – Exit Scene
Would you like to have the scene fade out and fade in each time you transition to a new scene? That should be rather really simple. But if you want to achieve a certain custom behavior it might require some thinking. For example, we didn’t want to take control away from our players when he clicks on exit hotspot. We wanted to leave them the option to cancel that interaction choice.
So we set up our exit hotspot like this:
You can see that we disabled “Cutscene while moving” and double-clicking does nothing. So everything that happens on a exit hotspot click is defined in our ExitInteractionAL action list.
In our ExitInteractionAL action list, first, we check for a double click. If a double click has happened, we immediately trigger the SceneSwitchAL which fades out the screen and switches to the next scene. This action cannot be undone. On the other hand, if the player made a single click on the exit hotspot, we let him walk towards the marker. At the same time, in parallel, we keep checking if another single click has happened. If another click happened, we kill the action list since the player clicked to move somewhere else.
Before checking for a second single click, wait for 0.3 seconds because the Click Delay on the Player Input script which is attached to the GameEngine is set to 0.3. This means that one click lasts for 0.3 seconds. So the first click which initiated this action list would get registered in this very same action list as a new click which kills this action list. In other words, we use that delay because we need to wait 0.3 seconds for the first click to get unregistered in the system. If after 0.3 seconds input check for a click returns true, we know this is a new click. Click, click. Click!
Wrapping up on Wrapper Action Lists
In this part of the series we talked about some general design practices regarding the action lists, and some specific action list solutions. We hope you found those helpful. In the next part we will cover UI related tips and tricks. And also, give more solutions to some specific issues we had while developing Bear With Me, which are likely to occur in any classical point and click game project.