Install
$ agentstack add skill-kyu-n-gdx-claude-skills-universal-tween-engine ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Universal Tween Engine (6.3.3)
Quick reference for consumers of aurelienribon.tweenengine. Covers factory construction, accessor registration, defaults/limits, semantic traps, callbacks, pooling lifecycle, and timeline composition. Full method signatures in references/api.md.
Defaults & Limits
| Setting | Default | Override | |---|---|---| | Easing equation | Quad.INOUT | .ease(equation) | | Path algorithm | CatmullRom spline | .path(TweenPaths.linear) | | Combined attributes limit | 3 | Tween.setCombinedAttributesLimit(n) at startup | | Waypoints limit | 0 | Tween.setWaypointsLimit(n) at startup | | Callback trigger | COMPLETE only | .setCallbackTriggers(flags) | | Tween.call() trigger | START (overrides default) | .setCallbackTriggers(flags) | | Duration units | Unitless (matches manager.update(delta)) | N/A | | Repeat count | 0 (no repeat) | .repeat(count, delay) or .repeatYoyo(count, delay) | | Auto-remove from manager | true | TweenManager.setAutoRemove(tween, false) | | Auto-start on manager add | true | TweenManager.setAutoStart(tween, false) | | Tween pool initial capacity | 20 | Tween.ensurePoolCapacity(n) | | Timeline pool initial capacity | 10 | Timeline.ensurePoolCapacity(n) |
Combined attributes limit = 3 means: tweening 4+ float values simultaneously (e.g., RGBA) throws at runtime unless you call Tween.setCombinedAttributesLimit(4) first.
Waypoints limit = 0 means: ANY .waypoint() call throws unless you call Tween.setWaypointsLimit(n) first.
Factory-Only Construction
Tween and Timeline have private constructors. All instances come from internal object pools via static factories.
// Tween factories — NEVER use new Tween()
Tween.to(target, tweenType, duration) // animate from current to target values
Tween.from(target, tweenType, duration) // animate from target values to current (reversed)
Tween.set(target, tweenType) // instantly set values (duration=0)
Tween.call(callback) // timer/callback only — no target needed
Tween.mark() // empty beacon for Timeline sequencing
// Timeline factories — NEVER use new Timeline()
Timeline.createSequence() // children play one after another
Timeline.createParallel() // children play all at once
TweenAccessor Registration
An accessor MUST be available before any tween on that type starts. Two approaches:
Approach 1: Register externally (most common)
// At application startup, once
Tween.registerAccessor(Sprite.class, new SpriteAccessor());
// Then anywhere:
Tween.to(mySprite, SpriteAccessor.POSITION_XY, 1f).target(100, 200).start(manager);
Approach 2: Target self-implements TweenAccessor
// No registration needed — engine detects TweenAccessor on the target
public class Particle implements TweenAccessor {
public static final int XY = 0;
float x, y;
@Override
public int getValues(Particle target, int tweenType, float[] returnValues) {
returnValues[0] = target.x;
returnValues[1] = target.y;
return 2; // MUST return count of values written
}
@Override
public void setValues(Particle target, int tweenType, float[] newValues) {
target.x = newValues[0];
target.y = newValues[1];
}
}
getValues() return value contract: The int returned is the count of float values written into returnValues[]. This count must be = 0 The javadoc on update(float delta) advertises negative delta for backward play. Do not use negative delta — backward play is unreliable and a source of bugs. Always clamp delta to >= 0 before passing to manager.update() or tween.update().
Default easing is NOT linear
Default is Quad.INOUT. For linear interpolation, explicitly set .ease(Linear.INOUT).
Default path is NOT linear
Default path is CatmullRom spline. Only matters when using waypoints. For straight-line waypoint interpolation, use .path(TweenPaths.linear).
Callback System
tween.setCallback((type, source) -> {
// 'type' is a single flag (e.g., TweenCallback.COMPLETE), NOT a combined mask
if (type == TweenCallback.COMPLETE) { /* ... */ }
}).setCallbackTriggers(TweenCallback.BEGIN | TweenCallback.COMPLETE);
Callback trigger constants (bitmask):
| Constant | Value | When | |---|---|---| | BEGIN | 0x01 | Right after initial delay ends (once) | | START | 0x02 | At each iteration beginning | | END | 0x04 | At each iteration ending, before repeat delay | | COMPLETE | 0x08 | At last END (once) | | BACK_BEGIN | 0x10 | First backward iteration beginning | | BACK_START | 0x20 | Each backward iteration beginning | | BACK_END | 0x40 | Each backward iteration ending | | BACK_COMPLETE | 0x80 | Last BACK_END (once) | | ANY_FORWARD | 0x0F | All forward events | | ANY_BACKWARD | 0xF0 | All backward events | | ANY | 0xFF | All events |
Timing diagram (canonical reference):
forward : BEGIN COMPLETE
forward : START END START END START END
|--------------[XXXXXXXXXX]------[XXXXXXXXXX]------[XXXXXXXXXX]
backward: bEND bSTART bEND bSTART bEND bSTART
backward: bCOMPLETE bBEGIN
Tween.call() overrides default trigger to START (not COMPLETE). All other factories default to COMPLETE.
Pooling Lifecycle
Managed tweens (started via .start(manager)) are fire-and-forget:
- Create via factory -> object pulled from pool
.start(manager)-> manager adds and starts itmanager.update(delta)-> two phases per call:
- Phase 1: Sweep — removes tweens that finished on a previous update, calling
free()on each (returns to pool) - Phase 2: Update — updates all remaining tweens with the delta
A tween that finishes during this frame's update is NOT removed until the next update() call. This means isFinished() returns true for one frame before the tween is freed.
Holding references to finished managed tweens is unsafe. After free(), the same object may be reused for a completely different tween.
To keep a tween reference alive after completion:
TweenManager.setAutoRemove(tween, false); // prevents automatic removal and pooling
// You must manually call tween.free() when done, or it leaks
For unmanaged tweens (.start() with no manager): you must call tween.update(delta) yourself and tween.free() when done.
Timeline Composition
Timeline.createSequence()
.push(Tween.set(obj, OPACITY).target(0)) // instant set
.beginParallel() // nested parallel
.push(Tween.to(obj, OPACITY, 0.5f).target(1))
.push(Tween.to(obj, SCALE, 0.5f).target(1, 1))
.end() // closes beginParallel
.pushPause(1.0f) // 1-second pause
.push(Tween.to(obj, POS_X, 0.5f).target(100))
.repeat(5, 0.5f)
.start(manager);
Rules:
- Every
beginParallel()/beginSequence()MUST be balanced with.end() - Children with infinite repeat (
Tween.INFINITY) throw on build when pushed to a Timeline pushPause()accepts negative values for overlap with the preceding child- Nested timelines pushed via
.push(timeline)must have their ownend()calls balanced before being pushed
Parameterizable Equations
Back and Elastic have mutable parameters:
Back.IN.s(2.5f) // overshoot amount (default 1.70158)
Elastic.IN.a(1.2f).p(0.4f) // amplitude / period
These mutate the static singleton instances. If you call Back.IN.s(2.5f) in one tween, ALL subsequent tweens using Back.IN see the changed value. This is NOT thread-safe and persists for the application lifetime.
Built-in Tweenables
The library includes MutableFloat and MutableInteger (in primitives subpackage) which self-implement TweenAccessor — no registration needed:
MutableFloat alpha = new MutableFloat(0f);
Tween.to(alpha, 0, 1f).target(1f).start(manager);
// alpha.floatValue() will interpolate from 0 to 1 over 1 unit of time
Common Mistakes
new Tween(...)ornew Timeline(...)— constructors are private. Use static factories.- Forgetting
Tween.registerAccessor()— throws "No TweenAccessor was found for the target" at.start()or.build(). getValues()returning 0 or wrong count — engine interpolates 0 values; nothing visibly happens.- Tweening 4+ values without raising limit — throws at runtime. Call
Tween.setCombinedAttributesLimit(n)at startup. - Using
.waypoint()without raising limit — throws immediately (default limit is 0). - Expecting
Tween.from()target values to be the end — they're the START. Current values are the end. - Assuming linear default easing — default is
Quad.INOUT. - Treating duration as milliseconds — it's unitless; matches
update(delta)time scale. - Holding reference to managed tween after completion — object is pooled and recycled.
- Unbalanced
beginParallel()/end()— throws "Nothing to end..." or "You forgot to call end()". - Pushing infinite-repeat child into Timeline — throws on build.
- Calling
Back.IN.s()orElastic.IN.a().p()without realizing it mutates the global static instance — affects all future tweens using that equation.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: kyu-n
- Source: kyu-n/gdx-claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.