Maths

Easing functions and probability distributions for Kotlin Multiplatform.

Animations and randomness, done right

Two things come up constantly when building interactive UIs, simulations, or generative content: smooth transitions and controlled randomness. Most projects end up copy-pasting easing formulas from the web and rolling ad-hoc random distributions. Maths packages both into a small, tested library.

We needed easing for Kraft animations and distributions for procedural content. Bundling them together made sense — they're both pure math, both multiplatform, and both small enough to not justify separate libraries.

Easing functions

28 easing functions organized into Ease.In, Ease.Out, and Ease.InOut, plus basic ones like linear, stuck, and immediate. All implement Ease.Fn — a functional interface that takes progress (0.0–1.0) and returns the eased value.

import io.peekandpoke.ultra.maths.Ease

// Simple easing
val progress = 0.5
val eased = Ease.Out.cubic(progress)  // 0.875

// Bind to a range: ease from 0 to 100
val bound = Ease.InOut.sine.bindFromTo(0, 100)
println(bound(0.5))  // 50.0 (midpoint of sine InOut)

// Time-based: animate from 0 to 255 over 500ms
val timed = Ease.Out.quad.timed(from = 0, to = 255, duration = 500.milliseconds)
while (!timed.isDone) {
    val value = timed()  // current eased value based on elapsed time
}

Probability distributions

Four bucketed distributions — uniform, truncated normal, exponential, and triangular — all sampled via inverse-CDF interpolation. Distributions can be inverted, reversed, and blended.

import io.peekandpoke.ultra.maths.stochastic.BucketedDistribution
import kotlin.random.Random

val normal = BucketedDistribution.createTruncatedNormal(mean = 0.5, std = 0.15)
val sample = normal.sample(Random)  // values clustered around 0.5

// Map to a custom range
val damage = normal.sample(Random, from = 10.0, to = 50.0)

// Blend two distributions
val skewed = normal.blend(
    BucketedDistribution.createExponential(lambda = 2.0),
    ratio = 0.3,
)

What you get

28 Easing Functions

Sine, quad, cubic, quart, quint, elastic, bounce, circ — in In, Out, and InOut variants.

4 Distribution Types

Uniform, truncated normal, exponential, and triangular. All bucketed with inverse-CDF sampling.

Range Binding & Timed Easing

Bind easing to numeric ranges. Time-based easing with Kronos integration for testable animations.

Kotlin Multiplatform

Works on JVM, JS, and Native (linuxX64, linuxArm64, macosX64, macosArm64, mingwX64).

Distribution Combinators

inverse(), reversed(), and blend() let you reshape distributions without rebuilding from scratch.

Serializable

Distributions are kotlinx.serialization-friendly. Store and transmit distribution configs.