# GDScript: Adapters

Source: https://tweens.gd/gdscript/api/custom/

An adapter animates storage that a property path can’t reach. Pass Callables to `Tweens.custom()`, or extend `TweensGdAdapter` for setup and cleanup around each playback and assign an instance to a definition’s `adapter`. [Custom properties](https://tweens.gd/gdscript/custom-properties/) walks through both.

```gdscript
# Tweens a camera's zoom as one number, keeping X and Y equal.
var zoom := Tweens.custom(
  func(target): return target.zoom.x,
  func(target, value): target.zoom = Vector2(value, value))
zoom.to_value = 2.0
zoom.duration = 0.5

Tweens.play(camera, zoom)
```

uniform\_zoom\_adapter.gd

```gdscript
# Tweens a camera's zoom as one number, keeping X and Y equal.
class_name UniformZoomAdapter
extends "res://addons/tweens_gd/adapter.gd"

func read(target: Object) -> Variant:
  return target.zoom.x

func write(target: Object, value: Variant) -> String:
  target.zoom = Vector2(value, value)
  return ""
```

```gdscript
var zoom := TweensGdDefinition.new()
zoom.adapter = UniformZoomAdapter.new()
zoom.to_value = 2.0
zoom.duration = 0.5

Tweens.play(camera, zoom)
```

## Callables

| Factory | Purpose |
| --- | --- |
| [`Tweens.custom(getter, setter, interpolator, validator)`](https://tweens.gd/gdscript/api/custom/#tweens-custom-getter-setter-interpolator-validator) | Read with `getter(target)` and write with `setter(target, value)`; the optional `interpolator(from, to, weight)` and `validator(value)` replace the defaults |

Set endpoints and timing on the returned definition. The Callables and the objects they capture stay shared between starts.

## Methods to override

Override `read` and `write`; the rest are optional. Hooks that return a `String` return an empty one on success, and an error message to fail playback with `FAILED`.

| Method | Returns | Purpose |
| --- | --- | --- |
| [`read(target)`](https://tweens.gd/gdscript/api/custom/#read-target) | `Variant` | Read the current value |
| [`write(target, value)`](https://tweens.gd/gdscript/api/custom/#write-target-value) | `String` | Write a value |
| [`interpolate(from, to, weight)`](https://tweens.gd/gdscript/api/custom/#interpolate-from-to-weight) | `Variant` | Blend two values; `weight` leaves 0 to 1 when an ease overshoots. Handles every built-in value type unless overridden |
| [`interpolate_offset(from, to, weight)`](https://tweens.gd/gdscript/api/custom/#interpolate-offset-from-to-weight) | `Variant` | Blend relative offsets and factors through `interpolate`. The base color implementation uses RGBA components. Override this hook only when relative math differs from your custom `interpolate` |
| [`validate_value(value)`](https://tweens.gd/gdscript/api/custom/#validate-value-value) | `String` | Reject unsupported or non-finite values. Handles every built-in value type unless overridden |
| [`prepare(target)`](https://tweens.gd/gdscript/api/custom/#prepare-target) | `String` | Set up this playback’s state |
| [`restore(target, initial)`](https://tweens.gd/gdscript/api/custom/#restore-target-initial) | `String` | Undo the tween at a non-retaining end; calls `write()` unless overridden |
| [`release()`](https://tweens.gd/gdscript/api/custom/#release) | `String` | Free this playback’s state |
| [`copy()`](https://tweens.gd/gdscript/api/custom/#copy) | `TweensGdAdapter` | Create the per-playback copy; copies script variables shallowly unless overridden |

## Binding lifecycle

1.  **`copy()`.** Each start works on its own copy of the adapter. The default copies script variables shallowly, so Arrays, resources, and captured objects stay shared; override `copy()` when configuration needs another policy.
2.  **`prepare()`** runs on that copy before the first read. Initialize private playback state here.
3.  **`read()`** captures the start value.
4.  **`interpolate()` and `write()`** run on every update.
5.  **`restore()`** runs at a natural end whose fill doesn’t keep the final value. It can write `initial` back, or remove an override instead.
6.  **`release()`** runs after the ending callbacks and before waiters resume, and also after a failed `prepare()`. Release only what this copy owns.

## Rules

-   Adapter constructors must take no arguments.
-   An adapter script’s `extends` line needs a path or a global class: the base script’s path, or `TweensGdAdapter` once the editor has built its class cache.
-   If a setter or interpolator cancels its own tween, `release()` waits until that call returns.
-   Several detected failures are kept together in the handle’s `error`.

Script errors aren’t failures

The addon reports only problems it detects: error strings from hooks, invalid Callables, and non-finite values. A GDScript runtime error inside a hook or Callable remains an ordinary Godot script error, with no conversion to `FAILED`. Return an error string for recoverable problems.
