We recently introduced a new redesigned functions feature for Construct 3. Check out that blog post in case you missed it. We have a few more things we wanted to highlight about the new functions feature!
'Wait' in functions
With the old Function plugin, the system Wait action would cause parameters to be lost. This was a common issue people ran in to and often resulted in questions on the forum. The problem was as soon as you wait, the function ends and its parameters are discarded. Then when it resumes actions after a delay, expressions like Functions.Param(0)
don't have the parameters any more, so just return 0. In other words Wait had the effect of clearing all parameters.
With the new built-in functions, Construct now knows to save all the function parameters when it reaches Wait. Then when it resumes actions after a delay, it restores them. This means waiting in a function works like you expect! All parameters are still available no matter how long or how many times you wait in a function.
The example above will correctly set the parameter number in the text after the wait.
Function maps
The new functions feature didn't originally support calling a function by an expression of its name, which the old Function plugin supported. However this is one of the design shortcuts that in turn caused some problems. Firstly if you call a function by an expression like "Func" & number
, Construct can't tell in advance from the editor alone which function will be run - it depends on runtime values. This means when you use Find all references, it doesn't know if that function call references the function you're searching for or not - so it errs on the side of caution and always includes it, marked as an ambiguous result. In large projects this means Find all references results eventually clog up with lots of ambiguous results you have to sift through. Further an advantage of the new functions is when you rename them, all their references throughout the project update automatically. However if the same ability to call by an expression was supported, it would also be unable to update calls by expression. Then sometimes renaming a function will require you to manually update events - reversing one of their benefits.
To solve this, Function maps are a new feature inspired by the approach you'd use in a real programming language, that associates a string with a function. This is the best of both worlds: you can call a function by its string, but since it never uses an expression for a function name, Find all references is always perfectly accurate, and you can always rename functions with the confidence it won't break anything.
This is a fairly advanced feature, but should be straightforward once you get used to it. Here's how it looks in events:
The process to use them is as follows:
- On startup, create a function map, which "maps" (associates) a string with a function.
- Normally you'd want to pass parameters, so when you call the function, first do it via another function (in the example above, this is CallColor).
- Then use the Call mapped function action to call a function by its string. This can also forward some of the parameters from the current function call, so the called function receives the same parameters. Normally when you do this you'd omit the parameter that specified the string, since the called function generally doesn't need it any more.
One extra capability is you can also set a default mapped function, which is called when the string doesn't match any function. It's often useful to have a "catch-all" to fall back on. This wasn't easily possible with calling functions by an expression so is a useful new part of the feature! Also when calling the default, all parameters are always forwarded. This lets the default function look at the string that was used, so it can be compared and used in expressions and so on.
Even when calling through an intermediate function, our benchmarks show function maps are about 30% faster than the equivalent using the Function plugin calling a function by an expression! So this approach is still faster. If you want to try this out, take a look at the new Function maps advanced example in the latest release.
Automatically converting old functions
Updating existing projects using lots of functions with the old Function plugin could be a bit of a chore. Luckily the latest release also includes a new option to automatically convert old functions to the new built-in functions! Simply right-click a On function condition from the old Function plugin and select Replace with built-in function.
Once converted a new function appears, the old one is disabled, and all references to the function across your project are updated to reference the built-in function instead.
Unfortunately the conversion may not always be successful. The new functions feature works differently in some cases, and these differences sometimes prevent automatic conversion. Some of the reasons conversion might not work include:
- Using parameters as both numbers and strings. This is the most common problem. New functions use a specific parameter types - either string or number - and can't be both, like they could in the old Function plugin.
- Using dynamic parameter indices - i.e. an expression for the parameter index in
Function.Param(n)
- Using multiple On function events - new functions only allow one.
- Calling functions as both actions and expressions - new functions can only be used as one or the other.
- Calling functions by expressions also can't be converted, since as before, the editor can't work out which function it would call.
However our experiments show it works about 3/4 of the time, so it's still a useful time-saver. You can try converting your project's functions one at a time and manually convert any that aren't automatically converted.
Do note however that this feature makes far-reaching changes to your project, and cannot be undone. So please be sure to back up your project before you use it!
Conclusion
Construct 3's new built-in functions feature is much better designed. Along with the benefits noted in the previous blog, it also fixes a long-standing issue with Wait, function maps cover calling functions by a string without the editor having to make guesses about dynamic function names, and there's even an option to help you switch over automatically. The old Function plugin is now deprecated so you should think about switching over if you can - or even upgrading your project to the C3 runtime if you haven't already, since new functions are only available there. We think the new functions feature will be much easier to use, and especially easier to manage in large projects, and they're far faster too! We hope you enjoy using them!