• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

Asset - Scripts TweenGMS - Tweening Engine

8BitWarrior

Member


Available on:
GameMaker Marketplace ($4.99)
Itch.io ($0)


TweenGMS is an easy-to-use and flexible automated tweening engine.
With many years of development, it offers many essential and advanced features powered by an optimised codebase.
Quickly improve the look of your games by tweening movements, fades, rotations, animations, stats, and much more!

HTML5 Demo
Video Tutorials
Documentation

[ Features ]
  • Fire-and-forget tweening
  • Step and delta(seconds) timing
  • Time scale manipulation
  • Custom variable easing
  • Control groups
  • Event callbacks
  • Tween stepping
  • Delay management
  • Path resource easing
  • Optimised performance
  • Automatic memory management
  • Compatible with all target platforms
  • Supports persistent instances and rooms
  • Clean script documentation
  • ... and more!
 
Last edited:

8BitWarrior

Member
An early alpha build for the next major release is available for testing! (v0.9.80)
Please do not test it with existing projects, as it is NOT backwards compatible with previous versions.
And be warned, it isn't properly documented yet (at all), so I don't suggest trying it if not already familiar with TweenGMS.

You can download the alpha build from HERE
 
This looks amazing! Can't wait to try it out.
It is amazing indeed. I've done great things with this asset :D But someone knows if it is going to be adapted to GMS 2? I've tried to import it and adapt by myself but it's a bit arduous to clean all compatibility scripts and got it working right.
 

8BitWarrior

Member
An early alpha is now available for GameMaker Studio 2. Please be aware that it is only partially documented and is not compatible with previous versions of TweenGMS.
I am open to feedback and suggestions!

Download Link

The biggest changes are:
- Multi-property tweens are now supported.
- Properties now use a string (e.g. "x", "myVar")
- Custom variables don't require property setter scripts. (to be further documented later)
- TweenFire() now supports TweenFireTo() and TweenFireFrom(). (not yet supported by TweenCreate() or TweenPlay().
- TweenSimple*() scripts have been replaced with TweenEasy*() scripts
- Replaced TweenGet*() and TweenSet*() scripts with TweenGet() and TweenSet() which now take string labels.
- Added advanced property scripts (e.g. TPMap()) for tweening arrays, lists, grids, and maps.
- Reduced need for many scripts by removing Tween*All()/Tween*Target()/Tween*Group() scripts.
*** The new Tweens*() scripts are now used to select specified tweens. e.g. TweenPause(TweensAll()).

Anyhow, let me know what you guys think!
 
Last edited:

Arconious

Member
Very excited to make use of this in GMS2! Was very hopeful this extension would eventually be ported over. Looks like importing .yymp files is currently broken in GMS2, so I guess I just need to manually import from the example project (extension file + scripts I assume). Thank you for working on this and releasing it to us all!!
 

8BitWarrior

Member
Looks like importing .yymp files is currently broken in GMS2, so I guess I just need to manually import from the example project (extension file + scripts I assume).
Importing .yymp files works (at least for me) if you drag and drop the file into GMS2 from windows explorer. Let me know if that works!
 

8BitWarrior

Member
I have fixed a problem with the alpha version for GameMaker Studio 2 which caused an error when using play modes other than TWEEN_MODE_ONCE. Anyone using the alpha is heavily encouraged to download the latest version.
 
D

djrain

Guest
This extension is causing my build to fail for iPhone (using GMS2 for Mac). Works perfectly on the Mac test though. Any idea why that might be?

Here's what I assume is the relevant error:

/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono DONE (0)
System.DllNotFoundException: kernel32
at (wrapper managed-to-native) .: (string,./&)
at Igor.iOSBuilder.HandleExtensions () [0x0020f] in <bd91bca3df6b4338a96799a391f58a40>:0 Igor complete.

elapsed time 00:00:05.7152540s for command "/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono" /Users/Shared/GameMakerStudio2/Cache/runtimes/runtime-2.1.0.135/bin/Igor.exe -options="/private/tmp/PKInstallSandbox.X0jjqz/GameMakerStudio2/GMS2TEMP/build.bff" -- iOS Run started at 08/25/2017 11:10:19
FAILED: Run Program Complete
 

8BitWarrior

Member
This extension is causing my build to fail for iPhone (using GMS2 for Mac). Works perfectly on the Mac test though. Any idea why that might be?

Here's what I assume is the relevant error:

/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono DONE (0)
System.DllNotFoundException: kernel32
at (wrapper managed-to-native) .: (string,./&)
at Igor.iOSBuilder.HandleExtensions () [0x0020f] in <bd91bca3df6b4338a96799a391f58a40>:0 Igor complete.

elapsed time 00:00:05.7152540s for command "/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono" /Users/Shared/GameMakerStudio2/Cache/runtimes/runtime-2.1.0.135/bin/Igor.exe -options="/private/tmp/PKInstallSandbox.X0jjqz/GameMakerStudio2/GMS2TEMP/build.bff" -- iOS Run started at 08/25/2017 11:10:19
FAILED: Run Program Complete
Sorry for the late reply. Unfortunately, this error does't offer me any useful information, as I don't see anything specifically related to TweenGMS. I am going to assume that this is a bug with GameMaker Studio 2 for Mac. Please let me know if anything changes. I will let you know if I come across any useful information.

Edit:
Are you using TweenGMS from the marketplace, or are you using the alpha build linked at the top of this page?
 
D

djrain

Guest
Sorry for the late reply. Unfortunately, this error does't offer me any useful information, as I don't see anything specifically related to TweenGMS. I am going to assume that this is a bug with GameMaker Studio 2 for Mac. Please let me know if anything changes. I will let you know if I come across any useful information.

Edit:
Are you using TweenGMS from the marketplace, or are you using the alpha build linked at the top of this page?
Thanks for the reply. Fortunately, I discovered today that in the latest version of GMS2 the problem seems to have disappeared.

I'm using the alpha v0.9.80 which I downloaded from the marketplace description. (I'm assuming they're the same?)
 

8BitWarrior

Member
I'm using the alpha v0.9.80 which I downloaded from the marketplace description. (I'm assuming they're the same?)
Yup! This page and the marketplace listing both link to the same download.
I'm hoping to officially launch to the marketplace for GMS2 later this week. I am just waiting on an HTML5 fix in a coming GameMaker update.
 

8BitWarrior

Member
An updated version of TweenGMS (v0.9.8) is now available for GameMaker Studio 2!
Please be aware that this version has significant changes from previous versions which are not backwards compatible. Please see the included documentation for more details.

Version 0.9.8 will arrive on GMS 1.4 at a later date.

A few of the notable changes:

- Property setter scripts are no longer required to tween custom variables
- Property arguments now take a string ("x") instead of script (x__)
- Tweens now support multiple variables
- Added TweenFireTo() and TweenFireFrom()
- New TweenGet() and TweenSet() scripts have replaced all TweenGet*() and TweenSet*() variants
- Improved script reference documentation
- Cleaner code base and removal of many redundant scripts
 
Last edited:

8BitWarrior

Member
TweenGMS has been updated to v0.9.82 with fixes for TweenFinish() and TweenFinishDelay(). This only affects GameMaker Studio 2.
 
R

RargraveEntertainment

Guest
Just wanted to add my thanks for such a great library. I haven't had a chance to try 0.9.83 yet but have enjoyed 0.9.74 with GM:S 1.4..
 

8BitWarrior

Member
Just wanted to add my thanks for such a great library. I haven't had a chance to try 0.9.83 yet but have enjoyed 0.9.74 with GM:S 1.4..
Happy to hear that!

Just as a side note, v0.9.83 breaks some previous conventions. More specifically, TweenFire(), TweenCreate(), and TweenPlay() have been updated to allow for multiple properties:
e.g. TweenFire(id, EaseLinear, 0, true, 0.0, 1.0, "x", x, mouse_x, "y", y, mouse_y);

It would be best to wait for a new clean project to try things out.
 
R

RargraveEntertainment

Guest
Thanks, I'll update soon as that multiple property fire sounds really useful.

One problem I haven't been able to figure out is if I have a project that is working fine, as soon as I save it to a network share folder, when I run I get this error:
"Could not locate initialization function TGMS_Ext_Init"

If I completely remove the extension and then re-add it this seems to fix the problem, but it makes switching which computer I'm working on a bit tricky :).

Any thoughts or ideas?

Thanks again for such a great library, without it I wouldn't have ever learned about tweens.
 

8BitWarrior

Member
One problem I haven't been able to figure out is if I have a project that is working fine, as soon as I save it to a network share folder, when I run I get this error:
"Could not locate initialization function TGMS_Ext_Init"

If I completely remove the extension and then re-add it this seems to fix the problem, but it makes switching which computer I'm working on a bit tricky :).

Any thoughts or ideas?.
Hmm... not totally sure what is going on.
Is TGMS_Setup.gml appearing in the TweenGMS extension folder? If that isn't being transferred properly, it would lead to that issue. Otherwise, you could delete TGMS_Setup.gml and manually call TGMS_Init() to initialize TweenGMS once at startup.
 
R

RargraveEntertainment

Guest
Thanks for the hint. That's the problem, I'm not sure why, but when I save to a network folder the 'extensions' sub folder has "TweenGMS.extension.gmx" and the folder "TweenGMS" but the "TweenGMS" folder is empty.

If I copy the contents of the "TweenGMS" folder from a local drive save over things work as expected. Much easier than re-installing the whole extension.
 

8BitWarrior

Member
TweenGMS has been updated to version 0.9.84.

The Amazon Fire target has been added to "Copies To:" and many corrections have been made to the Script Reference documentation.
 

8BitWarrior

Member
I have a way to greatly boost TweenGMS performance for YYC targets, but it'd require quite a bit of work on my end to set it up. I'm just wondering if any users out there could make use of extra performance gains, particularly for mobile targets. Otherwise, I could focus my time on adding new features instead... when I get around to them!

Update:
Never mind! After some testing, it seems that array access is now faster than ds_grid access for YYC targets. This wasn't the case, some time ago. Free gains, ftw!
 
Last edited:

8BitWarrior

Member
TweenGMS v0.9.84 is now live for GameMaker Studio 1.4 users. This brings it in line with the GameMaker Studio 2 version.

Be warned that this version has breaking changes from the previous version. I do not suggest upgrading large existing projects.
Please review documentation to see what has been changed.
 

8BitWarrior

Member
A note for GameMaker 1.4 users. The current version (v0.9.84) is currently broken when downloading through "My Library" in GameMaker. Please download the latest version directly from the marketplace listing instead.

[Update]
This issue has been fixed.
 
Last edited:

8BitWarrior

Member
TweenGMS has officially launched as version 1.0 for GameMaker 1.4 and GameMaker Studio 2.

As is, it is now considered feature complete and stable. Additional features may be added in the future, but no promises at this point. :squirrel:
 

8BitWarrior

Member
Looking for some feedback on an idea.
I am considering adding a feature which would optionally round eased values. This could be achieved by using an "r:variable" token for properties. So, for example...

TweenFire(id, EaseLinear, 0, 0, 0, 1, "r:x", x, mouse_x, "r:y", y, mouse_y);

That would round the eased values of x and y without having to manually round them elsewhere. There could also be variants added for flooring and ceiling, "f:var" and "c:var", respectively.

Anyhow! Would anyone find this useful?
 

8BitWarrior

Member
TweenGMS update v1.0.2 is now available for GameMaker Studio 1.4 and GameMaker Studio 2.

The major feature of this update is a new script called TweenMore(). This script allows you to easily chain tweens to play one after another.
Code:
// Chain various tweens to fire one after another
tween1 = TweenFire(id, EaseOutBounce, 0, true, 0, 1.0, "y", -100, y);
tween2 = TweenMore(tween1, id, EaseInOutQuad, 0, true, 0, 0.5, "image_yscale", 1, 0.25);
tween3 = TweenMore(tween1, id, EaseInOutSine, 0, true, 0, 1.0, "image_angle", 0, 360);
tween4 = TweenMore(tween3, id, EaseInOutQuad, 0, true, 0, 2.0, "image_xscale", 1, 0.5);

Another script added is TweenDefine(), allowing tweens to easily be defined or redefined as needed.
Code:
// Create an undefined tween, then define it with TweenDefine() before playing
tween = TweenCreate(id);
TweenDefine(tween, EaseOutQuad, TWEEN_MODE_ONCE, false, 0, 30, "x", x, mouse_x);
TweenPlay(tween);
 

N8M8

Member
I hate to use this thread to ask the question, but I'm not sure where else to go besides PMing the maker...

I am trying to figure out how to get a tween to animate while a key is held down, and then to revert to it's starting position (looks like I'd do this using a callback at the end of the initial tween) when it is let go.

Is there some base-level reading on how tweens work that could give me insight into how to do this? Googling hasn't helped a ton...

Thanks!
 
Last edited:

8BitWarrior

Member
I am trying to figure out how to get a tween to animate while a key is held down, and then to revert to it's starting position (looks like I'd do this using a callback at the end of the initial tween) when it is let go.
You could do something like...
Code:
/// CREATE EVENT
tween = TweenCreate(id);

/// KEY PRESSED EVENT
TweenPlay(tween, EaseLinear, 0, true, 0, 1.0, "x", 0, 100); // Play tween

/// KEY RELEASE EVENT
TweenPlay(tween) // This will restart the tween to start position
TweenStop(tween); // Then immediately stop the tween
Have you looked at the Demo Project for some basic examples?
Feel free to PM if you like. You can also contact me through the marketplace listing.
 
Last edited:

8BitWarrior

Member
I recently decided to set TweenGMS as a paid asset on the GameMaker Marketplace. This is with the hopes to promote asset creators being rewarded for their efforts. On the flip side, it also promotes consumers placing value on the products they use.

However, TweenGMS will remain available for free through a 3rd party site. The license has also remained open source, so you can still do with it as you like.
 
Last edited:

8BitWarrior

Member
TweenGMS update v1.0.5 is now available on the marketplace.
This update resolves warnings with the YYC compiler and other syntax errors.
Adjustments have also been made to the TweenMore() script for improving expected behavior.
In addition to the example projects being cleaned up, a new GUI Button example has also been added. This could be useful for those wanting to use the GUI layer for interactive UI elements.

This update is safe for adding to existing projects, as it presents no breaking changes.
However, a larger 1.1.0 update is in the works and DOES include breaking changes. Please consider carefully when updating past v1.0.5, as it may require you to make changes to your existing code.

Take care, all!
 

8BitWarrior

Member
Updated TweenGMS to v1.0.7 fixing a problem where TweenPlay() could fail when using TWEEN_MODE_BOUNCE.
Also, a big update is still in the works. It's taken a lot longer than expected to finish it, especially with the recent 2.3 and 2.3.1 changes! šŸ˜…
 

8BitWarrior

Member
An early beta for TweenGMS v2.0 is now available and can be download from HERE.

Do note that documentation is not yet finished. Please read "Beta_Notes" found inside the [TweenGMS Pro] -> [Docs] folder to review new features and changes.
Also, do not use this beta in live products, as it is not yet considered stable. Doing so is at your own risk!

The latest beta version of GameMaker Studio 2.3.1 is required.
The HTML5 target will not work as there is a bug in GMS regarding methods called directly from another array or data structure...
e.g.
array[0](arg1, arg2);

Input and bug reports are appreciated.
 

8BitWarrior

Member
An updated TweenGMS 2 beta is now available with new features and fixes.
Find it over on Itch.io.

For anyone interested, here are patch notes from the beta...

GML:
#0
=============================
Changes Since Previous Beta
=============================

-Added duration continue swapping
    TweenFire("$", [1,2], "~patrol", "x>", 10);

-Structs can now be used as valid tween targets
    TweenFire(aStruct, EaseLinear, 0, true, 0, 1, "x>", 10);
    ** Make sure to delete any structs that need to be cleared right away.
    ** Tween callbacks could continue to be fired if struct not cleared from memory.
    ** Otherwise, manually destroy tween's as needed.

-Default TweenFire() calls can now use "ease" and "mode" strings
    TweenFire(id, "ioSine", "patrol", true, 0, 1, "x>", 10);

-Default TweenFire() calls can now use advanced array parameters for MODE, DURATION, and DELAY
    TweenFire(id, ["linear","oQuad"], ["patrol",2], true, [0,1,2], [1,2], "x>", 10);
  
-TweenAddCallback()/TweenAddCallbackUser() now support "event" strings
    "finish", "@finish", etc...

-Default EASE functions are now internally converted to animation curves at startup for improved performance.
However, to make use of them, you must either use "ease" strings or the new Curve* macros
    TweenFire("$60", "~ioQuad", "x>", 10);            // Optimised
    TweenFire("$60", "~", CurveInOutQuad, "x>", 10);    // Optimised
    TweenFire("$60", "~", EaseInOutQuad, "x>", 10);    // Not Optimised -- still calls ease function directly

-Added support for object property prefixes -- "obj_Player.x"
    TweenFire("$60", "obj_Player.x", 0, 10);
    guy = o_Guy;
    TweenFire("$60", "guy.x", 0, 10);

-Fixed To/From support for structs when using TPTarget
    TweenFire("$60", TPTarget(o_Player, "x>"), 10);
    TweenFire("$60", TPTarget(aStruct, "y<"), 10);

-Change TGMS_PropertyMethod to TPFunc() and TPFuncX() -- Can also be directly used in a Tween function call
    // Create 'myProp' property to be used in tween call
    TPFunc("myProp", function(value,target){ target.myValue = value }, function(target){ return target.myValue });
    TweenFire("$60", "myProp>", 10);
      
    // Use TPFunc directly inside tween call
    TweenFire("$60", TPFunc("abc", function(v,t){t.abc=v}), 0, 10);
    // "abc" can still be resued in further calls
    TweenFire(">>", "$60", "abc", 10, 100);

-Added ability to pass target id for inline tween callbacks by passing a struct as first array element with target value
    TweenFire(..., "@finish", [{target:other}, Explode]);
  
-Added TWEEN_SELF so tweens can now reference themselves in functions/methods for event callbacks.
    TweenFire("$60", "#patrol", "x>", 100, "@continue", function(){ TweenPause(TWEEN_SELF) });
  
-TweenMore() now works with 0,-1,-2,... indexing
    TweenFire(...);
    TweenMore(0, "ioSine", "patrol", true, 0, 1, "x>", 10);

-Animation curve channels can now be directly passed as an ease type without the need for EaseCurve()
    TweenFire("$60", "~", aChannel", "x>", 20);
  
-Added 'Tweens' selection target support
    TweenPause({target: aStruct})
  
-EaseCurve() now takes an optional channel argument

-Added TGMS_ConvertEaseToCurve() for converting existing ease functions into animation curve channels

-Fixed issue where TweenEventClear() failed to actually clear the event... derp.

-TPStruct() has been merged into TPTarget()

-Fixed TweenIsPaused()


#1
===============
Tween From/To
===============

    TweenFireTo() and TweenFireFrom() are now obsolete.
    Instead, the ">" and "<" symbols are to be used with property strings.
    Here is a comparison between the old and new conventions...
  
        // Old
        TweenFireTo(id, EaseLinear, 0, 1, 0, 1, "x", mouse_x);
        //New
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "x>", mouse_x);
      
        // Old
        TweenFireFrom(id, EaseLinear, 0, 1, 0, 1, "x", mouse_x);
        // New
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "x<", mouse_x);
      
    You can also mix To/From properties in the same function call...
  
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "x>", mouse_x, "y<", mouse_y);
      
    You can even mix To/From with the standard convention...
  
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "x>", mouse_x, "y<", mouse_y, "image_scale", 0, 1);
      
    Note that the symbol ":" can *optionally* be used for properties using the
    default start/destination convention inorder to help with code clarity...
  
        // These both do the same thing
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "image_scale", 0, 1);
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "image_scale:", 0, 1);
      
      
#2
=======================
"Off-The-Rail" Tweens
=======================

    TweenFire()/TweenCreate()/ect... still support the previous convention by default, but a new
    "off-the-rails" convention has been added for more control.
  
    For example, both of these tweens will do the same thing...
  
        // Default Convention
        TweenFire(id, EaseLinear, 0, 1, 0, 1, "x", 0, 100);
        // Off the Rails
        TweenFire("-target", id, "-ease", EaseLinear, "-mode", 0, "-delta", 1, "-delay", 0, "-dur", 1, "x", 0, 100);
      
    The "off-the-rails" mode might seem worse at first, but it gets better!
    First, we can remove the tags which have default values we don't need to set,
    such as "-target", "-mode", and "-delay"...
  
        TweenFire("-ease", EaseLinear, "-delta", 1, "-dur", 1, "x", 0, 100);
      
    That is better, but we can do better! We can actually set a global default for "delta" as well...
  
        //This only needs to be set once
        TweenSet(TWEEN_DEFAULT, "delta", true);
      
        //Tween will now use delta=true as default so we don't have to set it each time
        TweenFire("-ease", EaseLinear, "-dur", 1, "x", 0, 100);
      
    But, we can still go further!
    Shorthand symbols are also supported for tween parameter tags.
    So, for example, we can use "~" instead of "-ease"...
  
        TweenFire("~", EaseLinear, "-dur", 1, "x", 0, 100);
      
    Likewise, we can replace "-dur" with "$"
  
        TweenFire("~", EaseLinear, "$", 1, "x", 0, 100);
      
    Here is a list of shorthand tags supported by TweenFire/TweenCreate/TweenPlay/TweenMore...
  
        "?" : "-target"
        "~" : "-ease"
        "#" : "-mode"
        "$" : "-duration" / "-dur"
        "^" : "-delta"
        "+" : "-delay"
        "|" : "-rest"
        ">" : "-continue_count" / "-count" / "-cc"
        "&" : "-group"
        "=" : "-time" ***Not to be conused with duration
        "%" : "-time_amount" / "-amount"
        "*" : "-time_scale" / "-scale"
        "!" : "-destroy
      
    Now, these shorthand tags also support being condensed with explicit values.
    So, the example above could be shortened like this...
  
        TweenFire("~Linear", "$1", "x", 0, 100);
  
    And! Because EaseLinear is actually a tween default, it could even be shortened to just this...
  
        TweenFire("$1", "x", 0, 100);
      
    If we wanted to make this even shorter, we could use a to "x>" property...
  
        TweenFire("$1", "x>", 100);
      
    I hope you are getting the point! The "off-the-rails" mode allows you to set only what you need to set.
  
    Now, I will cover other supported conventions for shorthand tags.
  
    *** Note that upper/lower case does NOT matter -- inQuad/INQUAD/iNqUaD all work the same***
  
    [EASE] Special Shorthand Tags
  
        "~linear"
      
        *** The SINE algorithm supports additional default shorthand tags... "~i", "~o", "~io", "~in", "~out", "inout" ***
      
        "~InSine", "~iSine", "~in", "~i"
        "~OutSine", "~oSine", "~out", ~o";
        "~InOutSine", "~ioSine", "~InOut", "~io"
      
        "~InQuad", "~iQuad"
        "~OutQuad", "~oQuad"
        "~InOutQuad", "~ioQuad"
      
        "~InCubic", "~iCubic"
        "~OutCubic", "~oCubic"
        "~InOutCubic", "~ioCubic"
      
        "~InElastic", "~iElastic"
        "~OutElastic", "~oElastic"
        "~InOutElastic", "~ioElastic"
      
        etc....
      
        Note:
            These can also be used in regular "on-rail" tween calls, but remove the prefix "~" -> "ioElastic"
      
    [MODE] Special Shorthand Tags
  
        "#0", "#o", "#once"
        "#1", "#b", "#bounce",
        "#2", "#p", "#patrol",
        "#3", "#l", "#loop",
        "#4", "#r", "#repeat
      
        Note:
            These can also be used in regular "on-rail" tween calls, but remove the prefix "#" -> "patrol"
      
    [ADDITONAL] shorthand tags take an explicit value...
  
        Delta
            "^0"
            "^1"
      
        Delay
            "+30"
      
        Duration
            "$30"
      
        Etc...
      
  
    Now, it is also possible to add CALLBACKS directly to a tween using the "@" shorthand tag.
    Let's take the previous example and extend it...
  
        // Call script 'ShowFireworks' when tween finishes
  
        // Original way (still valid!)
        t = TweenFire("$1", "x>", 100);
        TweenAddCallback(t, TWEEN_EV_FINISH, id, ShowFireworks);
  
        // New way (optional!)
        TweenFire("$1", "x>", 100, "@finish", ShowFireworks);
      
    All callback shorthand tags start with "@". Here is a list of them...
  
        "@finish" / "@" -- ** Note that these 2 are the same **
        "@continue"
        "@pause"
        "@play"
        "@resume"
        "@stop"
        "@rest"
        "@resting"
        "@reverse"
        "@finish_delay"
        "@pause_delay"
        "@resume_delay"
        "@stop_delay"
      
    If arguments need to be passed to the script, we can pass the callback as an array with additional arguments...
  
        // Show yellow fireworks at specific location
        TweenFire("$1", "x>", 100, "@finish", [ShowFireworks, c_yellow, x, y]);
      
        // Note that "@" is the same as "@finish" for extra convenience
        TweenFire("$1", "x>", 100, "@", [ShowFireworks, c_yellow, x, y]);
  
    You can optionally pass a struct as the first array element holding a value for 'target'...
  
        // This will do the same thing as above, except that it will use 'other' as the calling environment
        TweenFire("$1", "x>", 100, "@", [{target: other}, ShowFireworks, c_yellow, x, y]);
      
    If you want a callback to use a specific target environment, you can also use TweenAddCallback() instead.
      
      
#3
==============
Tween Select
==============

    The TWEENS SELECTION functions have been made obsolete. (However, TweensIncludeDeactivated still exists!)
  
    First, in addition to 'all', the keywords 'self' and 'other' have been added as a valid tween[s] id where supported.
    So, for example, here is a comparison between the old way and new way...
  
        // Pause all tweens associated with the calling target environment
  
        // OLD WAY
        TweenPause(TweensTarget(id));
      
        // NEW WAY
        TweenPause(self);
      
    You can likewise do this with 'other'
  
        TweenPause(other);
      
    For more advanced selection of tweens, we now use structs with the values 'tween', 'group', or 'target'.
    Here are some examples...
  
        // Pause tweens belonging to group 5
        TweenPause({group: 5});
      
        // Pause tweens associated with group 5 AND target 'id' AND tweenID 'myTween'
        TweenPause({group: 5, target: id, tween: myTween});
      
        // Use arrays to supply more than one value per struct value
        TweenPause({group:[5,10], target:[id,other.id], tween:[tween1,tween2,tween3]});
      
    And, don't forget! You can affect all tweens with the 'all' keyword
  
        TweenPause(all);
      
      
    Please note that 'self' and 'other' keywords do not work as valid target ids when using 'target' with structs.
    Instead use id or other.id in that specific case. (This might be updated in the future to be supported)
  
        // THIS WILL NOT WORK!!!
        TweenPause({target: [self, other]});
  
        // This works :)
        TweenPause({target: [id, other.id]});
      
      

#4
====================
Continue AND Rest
====================

    There are 3 play modes which support "countinue counts":

        PATROL
        LOOP
        REPEAT

    When a tween reaches the start/destination points of the tween,
    continue counts determine if the tween will continue or finish.
    By default, countinue counts are infinite (-1).
    Setting a tween with a 'patrol' mode to a continue count of 1
    will effectively make it the same as the 'bounce' mode.

    Setting a tween's continue count can be set in these various ways:

        // #1
        t = TweenFire(id, EaseLinear, "patrol", true, 0, 60, "x", 0, 100);
        TweenSet(t, "continue_count", 2);
      
        // #2 The following all do the same thing...
        TweenFire("$60", "#patrol", "-continue_count", 2, "x", 0, 100);
        TweenFire("$60", "#patrol", "-continue", 2, "x", 0, 100);
        TweenFire("$60", "#patrol", "-cc", 2, "x", 0, 100)
        TweenFire("$60", "#patrol", ">", 2, "x", 0, 100);        // Use ">" shorthand symbol
        TweenFire("$60", "#patrol", ">2", "x", 0, 100);            // Use ">2" codensed shorthand
  
    It is also possible to set the "rest" for tweens which continue.
    This is the amount of time a tween will wait before continuing.
    This value can be set in the following ways...

        // #1
        t = TweenFire(id, EaseLinear, "patrol", true, 0, 1, "x", 0, 100);
        TweenSet(t, "rest", 30);
  
        // #2
        TweenFire("$60", "#patrol", "-rest", 30, "x", 0, 100);
      
        // The following 2 examples are the same as above but with "|" shorthand rest symbol... one uses "condensed shorthand".
        TweenFire("$60", "#patrol", "|", 30, "x", 0, 100);
        TweenFire("$60", "#patrol", "|30", "x", 0, 100);
  
    The previous examples will cause the tween to rest for 30 steps before continuing.
    However, it also possible to have different rest durations for the start/destination points.
    This can be done by passing the rest parameter as an array...

        TweenFire("$60", "#patrol", "-rest", [30, 120], "x", 0, 100);
  
    This example above would cause the tween to rest for 30 steps when reaching
    the start position, and have it rest for 120 steps when reaching the finish position.

    Now, if using the default form of TweenFire() WITHOUT "going of the rails",
    you can still easily set these values by passing an array to the delay parameter.
    The first value is the main tween delay, and the second value the rest duration...

        // Delay = 0, Rest = 30
        TweenFire(id, EaseLinear, "patrol", false, [0, 30], 60, "x", 0, 100);
  
    To set the rest for the start/dest, a third argument can be passed...

        // Delay = 0, Rest = 30/120
        TweenFire(id, EaseLinear, "patrol", false, [0, 30, 120], 60, "x", 0, 100);
  
    Additionaly, you can also go "off the rails" after setting properties

        TweenFire(id, EaseLinear, "patrol", false, 0, 60, "x", 0, 100, "-rest", 30);
  
  
      
#5
=====================================
Property Start/Destination Strings
=====================================

    **Please be aware that this feature has limitations which will be explained further on**
  
    Start and destination values can now take string arguments which allow for more advanced uses.
    For example, the following can be done...
  
        TweenFire("$60", "x>", "x+100");
  
    The above example will move x to the *current* x position plus 100.
    Now, this isn't very useful in this case, as we, instead, could directly do...
  
        TweenFire("$60", "x>", x+100);
      
    However, if this tween adds a delay, then the string destination becomes useful.
  
        TweenFire("$60", "+30", "x>", "x+100");
      
    Now, after the delay finishes, the tween will check the *current* position of x
    and add 100 to that current value. So, if the target instance is moving around, this
    method can be used to adjust for a moving x value.
  
    There is also a shorthand symbol "@" for extra convenience.
    The "@" will represent which variable is being tweened.
    So, we could do this...
  
        TweenFire("$60", "+30", "image_scale>", "@*2", "image_angle>", "@+360");
      
    In the above example, the "@" symbol will be replaced with "image_scale" and "image_angle" respectively.
  
    Additionally, instance variables **from the current calling environment**
    and global variables can also be used in the string...
  
        value = 100;
        global.gValue = 200;
        TweenFire("$60", "+30", "x>", "@+value; "y>", "@+gValue");
      
    The above example will add 'value' and 'gvalue' to the respective properties.
    The 'global.' prefix is not to be used for string values. If TweenGMS does not detect an
    instance variable, it will automatically check for a global variable with the same name.
    **NOTE: LOCAL VARIABLES ARE NOT SUPPORTED (e.g. var _someVar) **
  
    Now, the use of string values are quite limited.
    You can only have 2 values added, subtracted, multiplied, or divided.
    Some examples...
          
            "value+2"
            "@-value"
            "value*2"
            "@/value"
          
    In addition to stringed values, you can also use an array to set values relative to
    the current value of the given property variable. For example...
  
        TweenFire("$60", "x>", [100], "y>", [-200]);
      
    The above example would move the 'x' right by 100 and 'y' up by 200.
    This could be the better option when wanting to use local temporary variables to set values.
  
    In addition to adjusting for value changes during a delay, this feature could also
    be useful when using TweenCreate() with TweenPlay().



#6
========================
TweenJust*() Functions
========================

    TweenJust*() functions allow you to check for when certain tween events JUST happen.
    Unlike TweenIs*() functions, TweenJust*() functions will only return true once.
  
        // STEP EVENT
      
        // Will only execute once
        if (TweenJustFinished(tween))
        {
            show_debug_message("Tween Finished!");
        }
      
        // Will continue to execute repeatedly until stopped
        if (TweenIsPlaying(tween))
        {
            show_debug_message("Tween is still going...");
        }
      
    These functions can be used as an alternative to Tween Callbacks.
  
    The following TweenJust*() functions are avaiable...
  
        TweenJustStarted()
        TweenJustFinished()
        TweenJustStopped()
        TweenJustPaused()
        TweenJustResumed()
        TweenJustRested()
        TweenJustContinued()
      
    The following TweenIs*() functions are avaiable...
  
        TweenIsActive()
        TweenIsPlaying()
        TweenIsPaused()
        TweenIsResting()


#7
=================================================
Methods can be used as property setters/getters
=================================================

    Methods can now be used as property 'setters' and, optionally, 'getters'.
    We use the function TPFunc() to set them up.
  
    The first method receives both a 'value' and 'target' argument.
    You can name these anything you like when passed to the function.
  
    The second optional method is used as the 'getter' which receives
    a target argument. Again, 'target' can be renamed to whatever you like.

    We can use TPFunc() like so...
  
        // Create custom property setter which adds a "shake" to the tweened 'x' variable
        TPFunc("shake_x",
                function(value,target) { target.x = value + random_range(-5, 5) }, // SETTER
              )

        // Fire tween using custom property method "shake_x"
        TweenFire("$60", "shake_x", x, mouse_x);
      
    We can optionally supply our own getter as well by extending the example above...
      
        // Create custom method property setter which adds a "shake" to the tweened value
        TPFunc("shake_x",
                function(value,target) { target.x = value + random_range(10) }, // SETTER
                function(target)       { return target.x }                    // GETTER
              )

        // The ">" syntax is now supported because of 'getter'
        TweenFire("$60", "shake_x>", mouse_x);
  
    TPFunc can also be used directly inside of a tween function like so...
  
        // Use TPFunc directly inside tween call
        TweenFire("$60", TPFunc("myXYZ",v,t){ t.xzy = v }), 0, 100);
      
        // Additional calls can simply use the previous "myXYZ" string instead of calling TPFunc again.
        // '0' in the following example points to the previously created tween above.
        TweenMore(0, "$60", "myXYZ", 0, 100);
      
    TPFuncX() adds an additional 'target' argument if wanting to set a target
    different from the tween's own target.
  
        // target will now point to obj_Baddie, regardless of the tween's target
        TPFuncX(obj_Baddie, "shake_x",
                function(value,target) { target.x = value + random_range(10) }, // SETTER
                function(target)       { return target.x }                        // GETTER
               )


#8
============================
Ease and Duration Swapping
============================

    For play modes which continue, different ease algorithms can be applied
    to the forward and backward motion of the tween.
  
        TweenFire("$60", "#patrol", "~", [EaseOutBounce, EaseLinear], "x>", x+200);

    Likewise, different durations can be supplied for the forward and backward motion of a tween...
  
        TweenFire("$", [60, 120], "#patrol", "x", 0, 100);
  
  
#9
=============================
Animation Curves Ease Types
=============================     
      
    Animation Curves can now be used in place of easing algorithms.
    To have it usable for TweenGMS, supply an animation curve's asset index or struct to EaseCurve().
  
        TweenFire("$60", "~", EaseCurve(aCurveIndex), "x>", mouse_x);
      
    Ease Curve can take an optional argument for selecting a curve's channel.
    If no channel is given, the first channel will be automatically selected.
      
        TweenFire("$60", "~", EaseCurve(aCurveIndex, "aChannel")), "x>", mouse_x);
      
    Animation Curve channel's can be directly supplied without the need for EaseCurve().
    However, if unsure, you can still pass the channel to EaseCurve() if you like, as it won't make a difference.
  
        // Both will work just the same
        TweenFire("$60", "~", aCurveChannel, "x>", mouse_x);
        TweenFire("$60", "~", EaseCurve(aCurveChannel), "x>", mouse_x);
      
    As an added optimisation, new macros have been added which are Animation Curve equivalents of
    the default easing algorithms. You can access them using Curve* macros...
  
        TweenFire("$60", "~", CurveInOutSine, "x>", mouse_x);
      
    If using "ease" strings, the optimised versions will automatically be supplied.
  
        TweenFire("$60", "~ioQuad", "x>", 10);                // Optimised
        TweenFire("$60", "~", CurveInOutQuad, "x>", 10);    // Optimised
        TweenFire("$60", "~", EaseInOutQuad, "x>", 10);        // Not Optimised -- still calls ease function directly
          
          
    To convert any existing custom easing algorithms, you can convert them using
    the new function TGMS_ConvertEaseToCurve().
  
        CurveCustom = TGMS_ConvertEaseToCurve(EaseCustom);
        TweenFire("$60", "~", CurveCustom, "x>", 100);
      
    A second optional argument can be supplied to change number of points for the curve.
    By default, this value is 180.
  
        CurveCustom = TGMS_ConvertEaseToCurve(EaseCustom, 50);
          
          
#10
===================
TweenPath Changes 
===================

    TweenPath() has has been made obsolete and is not split into 2 different functions...
  
        TweenEasyPath()
        TPPath()
      
    TweenEasyPath() is very similar to TweenPath() as before, however, it is now designated
    as an "easy tween" which is meant to be for easiest use.
  
    TPPath() can be used inside other Tween functions such as TweenFire().
    This means that path easing can now be combined with other properties.
  
        TweenFire("$60", "image_scale>", "@*2", TPPath(myPath, false), 0, 1);


#11
==============================
Tween Property Modifiers TP*
==============================

    Tween property modifiers can be used to manipulate tweened values.
    For example, we can apply a random shake...
  
        TweenFire("$60", TPShake("x>", 8), mouse_x);
      
    The above example will move 'x' to the mouse_x position while randomly shaking it by value of 8.
  
    Other modifiers include...
  
        TPRound()
        TPFloor()
        TPCeil()
        TPSnap()


#12
================
Lazy Tween IDs
================

    Previously created tweens can be addressed with the value '0'.
    For example...
  
        // Fire a tween but don't store its id
        TweenFire("$60", "x>", 100);
      
        // Use '0' to pass the previously created tween id
        TweenAddCallback(0, TWEEN_EV_FINISH, SomeScript);


#13
========================================
Negative delay values (jumps to start)
========================================

    This is bit of a hack at the moment which might not work in certain situations but
    it does remain as a cool nifty thing if you knot it's there!
  
    Using a negative delay value will cause the tween properties to jump to the initial
    values of the tween, however, the tween will still be delayed by the absolute value of the delay.
    I hope that makes sense... let me show you!
  
        TweenFire("$60", "+", -30, "x", x+100, x+200);
      
    In the above example, the 'x' variable will immediately jump to the start value right away,
    however, the tween will still be delayed for 30 steps.
    This is in contrast to regular delays which will not automatically jump values to the start
    until the delay has finished.
  
    This is still buggy for some use cases but should be fine for basic needs.
  

#14
=========================
Struct Tweening Support
=========================

    Structs are directly supported as both properties AND targets.
    So, you can do the following...
  
        aStruct = {val1:0, val2:0}
        TweenFire("$60", "aStruct.val1", 0, 100);
      
    But, we can also use a struct as a target and directly supply it's given variables...
  
        aStruct = {val1:0, val2:0}
        TweenFire("$60", "-target", aStruct, "val1>", 200, "val2>", 1200);
      
    If a tween is created within a struct, the structs "self" will be used as the default target.
      
          
#15
===================
Group Time Scales
===================

    Time scales can now be set per group by using the function TweenGroupSetTimeScale()...
  
        // Set group 10 to use a time scale of 0.5
        TweenGroupSetTimeScale(10, 0.5);
  
    Please note that this is different from the example below...
  
        // Set the time scale for EACH tween within the group
        TweenSet({group: 10}, "time_scale", 0.5);
      
    The example above would change the time scale for EACH tween individually within the group
    and not affect the ACTUAL group scale as a whole.
  
    With this new addition, there are now 3 levels of time scales...
      
        GLOBAL
        GROUP
        PER-TWEEN
  
    GLOBAL, GROUP, and PER-TWEEN time scales can all be stacked together for combined effects...
      
        // Set system scale to x10.0
        TweenSystemSet("time_scale", 10.0);
      
        // Set group 2 scale to x0.5
        TweenGroupSetTimeScale(2, 0.5);
      
        // Set specific tween scale to x.0.25
        TweenSet(myTween, "time_scale", 0.25);
      
    The final output scale for 'myTween' above would be 1.25

          
#16
====================
Relative Durations
====================

    This feature allows you to set the duration as an average speed per-step or per-second.
    Tweens that use step timing will change eased values, on average, by the given amount each step.
    Whereas, tweens that use delta timing will change eased values, on average, by the given amount each second.
    This feature is applied by passing duration as an array...

        TweenFire("$", [10], "x>", 100); // Move 10 pixels per frame, on average.
        TweenFire("^", true, "$", [50], "x>", 200); Move 50 pixels per second, on average.
      
    This can be useful for delayed tweens where you don't know the final start and/or destination values.

        TwenFire("+100", "$", [10], "~io", "x>", mouse_x);
  
    ** Please note that relative durations are not currently supported for ease/duration swapping **
  
        // This currently won't work
        TweenFire("$", [[100],[200]], "#patrol", "x", 0, 100);
 
Top