Repository navigation
Releases: sya-ri/strata
Release list
Strata 0.2.2
Strata 0.2.2
Strata 0.2.2 reduces retained-frame, text-editing, CPU rasterization, and Minecraft presentation costs, and publishes a shared performance testkit for library and application developers.
Keep all Strata artifacts on version 0.2.2 and install the Fabric runtime for your exact Minecraft version.
Rendering and retained UI
- Clean timed frames reuse the current tree's callback capabilities instead of walking every passive node. Structural changes, time-aware callbacks, invalidation, and terminal cleanup retain their original behavior.
- Dense repeated image blits can use bounded pixel templates, including multi-texel patterns. Fractional or reflected transforms, mixed primitives, invalid grids, and patterns outside the admitted bounds retain the original drawing path.
- CPU composition avoids repeated coordinate/color calculations and reuses exactly equal sampled rows. Opaque, translucent, patterned, tinted, and clipped inputs keep their existing pixel equations.
- Minecraft presenters reuse unchanged frame inputs and shifted layers, omit wholly invisible portable inputs, bound raster regions to visible work, and share scratch pixels only within one preparation. Each native upload retains independent owned storage.
- Supported modern adapters use bounded lookup metadata to select the same source texels as CPU sampling. Minecraft 26.3 samples the source in the GUI pass; other supported modern adapters materialize an exact GPU output. Unsupported tint, cutoff, orientation, clipping, and legacy adapter combinations retain CPU fallback.
- Long TextField measurement and cursor positioning avoid repeatedly copying and measuring prefixes. Unicode scalar boundaries, custom-font metrics, native rounding, IME, selection, and input behavior remain intact.
- Resource identifier validation and remote value/tree processing reduce transient allocation while preserving admission limits, validation failures, and communication contracts.
Measured changes from 0.2.1
| Operation | Before (0.2.1) | After (0.2.2 candidate) | Time reduction (%) |
|---|---|---|---|
| Retained clean timed frame, Full HD | 0.578 µs | 0.062 µs | 89.3% |
| Fresh CPU composition, patterned 64×64 source, Full HD | 38.264 ms | 1.191 ms | 96.9% |
| Fresh CPU composition, translucent 1×1 source, Full HD, density 4 | 48.794 ms | 1.089 ms | 97.8% |
| Fresh CPU composition, translucent patterned 1024×1024 source, Full HD | 49.037 ms | 12.787 ms | 73.9% |
These are medians of three independent AverageTime runs per side. Time reduction is (Before − After) / Before × 100; positive values mean faster operations.
Ordinary Full-HD rasterization was nearly unchanged: 0.822 ms Before and 0.807 ms After (1.8% average-time improvement); the measured p95 values increased for the ordinary raster fixtures, so this is not a blanket speedup.
Fresh full-HD outputs still allocate about 8.3 MB per operation, and some sampled-image cases allocate roughly 8–19 KB more for bounded sampling scratch state.
Retained clean-frame allocation in this fixture remains about 112 B per operation.
The full comparison includes all 24 selected cases, p50/p95/p99, and allocation; remaining cost and regressions are tracked below.
These measurements use the actual Maven Central 0.2.1 JARs and the final optimized runtime source, with identical compiled fixtures, collector, JMH harness, machine, Java, and standard iteration settings.
They measure JVM retained-frame and fresh CPU-raster operations; they do not establish GPU completion time or a universal FPS improvement.
The complete comparison below records the selected matrix, conditions, binary identities, and remaining limits.
Shared performance testkit
The test-only artifact dev.s7a.strata:strata-performance-testkit:0.2.2 centralizes JVM collection, CPU/allocation/GC evidence, runtime work assertions, native presentation counters, and validated summaries/comparisons.
The multiplatform artifact is dev.s7a.strata:strata-performance-testkit-multiplatform:0.2.2.
Consumers provide their real UI or server fixtures, actions, readiness predicates, and expected work through the testkit contracts.
JVM measurement, validation, aggregation, and comparison run in Java without a Python runtime requirement.
Quick investigation and change-scoped selection have separate receipt identities and cannot replace standard acceptance.
The kit is a new optional testing dependency; existing screens do not need to adopt it to upgrade.
UI authoring guidance
The Strata skill keeps everyday component, modifier, content-slot, and state-ownership decisions in its entrypoint, with conditional references for inventory styling, remote extensions, and retained custom components.
Independent empty-project exercises cover standard controls, virtualized lists, shared application-local components, and an interactive primitive with its own drawing.
The authoring checks guide describes nine opt-in, type-aware Detekt rules covering retained-state creation and mutation, manual subscriptions, immutable modifier use and forwarding, parent-data placement, flat root counts, and runtime/opening boundaries.
Install dev.s7a.strata:strata-detekt-rules:0.2.2 through detektPlugins and enable the strata rule set with the compatible Detekt version.
The guide explains each rule with compiled incorrect and corrected examples and its detection limits; responsibility and rendered-tree review remain necessary.
Known limits and follow-up work
Performance depends on command composition and adapter support; some changing-image and list intervals still take longer despite lower allocation.
Remaining work is tracked as general rendering and testkit issues:
- Sampling metadata allocation and transfer.
- Broader exact GPU sampled-image composition.
- Complex CPU portable preparation.
- Preparation-time increases in general presentation workloads.
- Duplicated ownership code across version adapters.
- GPU completion, upload-byte, cold-resource, and cross-device evidence.
Upgrade
Update Maven dependencies and the installed Fabric runtime together to 0.2.2.
Existing screen definitions and remote communication contracts require no migration from 0.2.1.
The supported Minecraft version matrix is unchanged.
Runtime diagnostics add an optional bounded node-record capacity; the existing no-argument monitoring API retains its defaults.
Complete performance comparison
This compares Maven Central 0.2.1 with the final optimized runtime source in commit dc0f0cf32bc900bbd313b6dc4c8b40cd034e84dd, merged as 9f7078cb3243b87b3be507b50c8c42ee061b7f46.
The candidate archives were built from that source before the release version change; only release metadata and documentation changed afterward.
The baseline is the actual public binary distribution, not an intermediate optimization PR.
Conditions and coverage
- Windows 11, amd64, 32 logical processors; OpenJDK 25.0.2. The same machine and Java were used on both sides, with no overlapping builds or other benchmark invocations.
- The same compiled JMH fixtures, harness, shared collector, generated parameter matrix, and external input archives. The shared kit verified actual parent/fork origins and preserved the measured target, harness, collector, and input archives.
- AverageTime and SampleTime each ran three independent invocations per side, with three one-second warm-up iterations, five one-second measurement iterations, one fork, one thread, microsecond units, and the GC profiler.
- All 24 selected cases completed in each invocation. Both modes passed shared-kit summaries and comparisons. The original complete historical corpus and its acceptance contract were unchanged.
- Retained timed frames and ordinary rasterization use all three registered viewports. Sampled rasters use both registered physical sizes, both densities, and opaque/translucent/patterned sources. Dense rasters use all three source resolutions and both alpha varieties.
- Source construction, resource acquisition and PNG/hash verification are outside measurement. All 21 raster fixture outputs matched public 0.2.1 byte-for-byte as deterministic PNGs.
The selected methods are RenderingBenchmark.cleanTimedUiSessionFrame, RenderingBenchmark.headlessRasterization, SampledRasterBenchmark.composition, and DenseSampledRasterBenchmark.composition.
Their unchanged public-contract fixtures live in quality/benchmarks.
The shared JmhWorkloadInventory expands the generated registry, JmhPerformanceRunner delegates execution to JMH, and PerformanceEvidenceCli validates and compares the independent receipts.
These measurements do not certify every feature, input combination, host, or future extension.
Results
Before is the public Maven Central 0.2.1 distribution. After is the optimized 0.2.2 candidate.
Average time and allocation are the shared kit's medians of three independent per-run scores. Percentiles are its medians of three per-run SampleTime percentiles.
Reduction (%) = (Before − After) / Before × 100. Positive values mean less time or allocation; negative values mean a regression. Percentages are rounded to one decimal place; 0.0% can include a small change.
These figures describe this selected fixture matrix and host. They are not FPS measurements, significance tests, or CI thresholds.
Clean retained tim...
Strata 0.2.1
Strata 0.2.1
Strata 0.2.1 reduces drawing and CPU raster work for Minecraft screens without changing public APIs or remote communication contracts.
Keep all Strata artifacts on version 0.2.1 and install the Fabric runtime for your exact Minecraft version.
Rendering performance
Tiled nine-slice images now combine repetitions along source axes that contain exactly one texel.
A one-by-one center emits one drawing command instead of one command per tile.
Sources with multiple texels retain their repeated pattern and partial final tiles; the default Tiled mode is unchanged.
Integer and fractional scaling, clipping, transparent and translucent colors, semantics, input, scroll position, and invalidation retain their existing behavior.
CPU rasterization now uses direct row writes for opaque fills and avoids unnecessary blending for opaque pixels.
One-texel image draws reuse the fill path, and opaque sampled images avoid redundant color operations when the source or tint permits it.
These paths preserve the original pixels and add no cache.
In a measured SabMinato fishing challenge fixture, initial drawing commands decreased from 387,223 to 467.
The reduction depends on the source texture and screen contents; patterned sources with two or more texels still require tiling.
See the performance contract for measurement and parity requirements.
Upgrade
Existing screen definitions require no API migration from 0.2.0.
Update Maven dependencies and the installed Fabric runtime together to 0.2.1.
The runtime continues to support the existing Minecraft version matrix.
Strata 0.2.0
Strata 0.2.0
These notes describe the changes since 0.1.6.
They cover the common UI API, reactive state, Paper/Folia and Velocity integration, browser rendering, Minecraft compatibility, and extension contracts.
Rebuild consuming Mods and plugins for the callback API changes, and keep all installed Strata artifacts on the same release.
Common UI definitions, screens, and HUDs
UiDefinition describes content and presentation together and returns a UiSession when opened.
Use definition.open() on the client or the Paper extension definition.open(plugin, player) on the server.
Screen is the default presentation; HUD is selected on the definition.
The optional title is used for narration and is not drawn automatically.
The session can switch between Screen and HUD while retaining its content, input values, and scroll position, or close itself from an event handler.
onXxx callbacks receive the owning session as their receiver, so close() and switch(...) address the UI delivering that event.
Applied presentation and typed lifecycle status are available on the handle; remote presentation changes become visible there after client acknowledgement.
Multiple HUDs can coexist with an ordinary screen.
Namespaced categories and visibility rules control whether each HUD remains visible, temporarily hides, or closes when another screen opens.
HUDs follow F1 visibility and support explicit interaction without a new default keybinding.
Input policies separately allow movement, camera control, and other game actions while a UI is open; forwarded keys are released at input and ownership boundaries.
See screens and state for presentation, visibility, input, and lifetime contracts.
Reactive application and component state
mutableStateOf, MutableState, and read-only State add application-owned reactive values.
Reading a value during content evaluation tracks that dependency; changing it schedules reevaluation, while equal assignments skip invalidation.
Dependencies follow the reads made by the latest evaluation and are released when the UI closes.
Existing component values participate in the same tracking, including checkbox, slider, cycle-button, and text-editor values.
For example, a label that reads TextFieldState.value can update when the editor changes without a separate copied value.
State remains owned by its creating execution context and must be created outside content that can reevaluate.
Writes during declaration evaluation are rejected.
The existing StateSource inputs, mapped sources, and Observe regions remain available for external data and narrower update boundaries.
Compatible keyed content retains its nodes and editing state across reevaluation.
Server-owned Paper, Folia, and Velocity UIs
The new Paper and Velocity runtimes let plugins define UIs and execute their handlers on the server or proxy, with native rendering on a matching Strata Fabric client.
Paper uses the primary server thread; Folia follows each player through its entity scheduler and preserves a logical execution owner across region migrations.
Create Folia state in PaperUi.open(ownerPlugin, player) { ... } and enter PaperUi.execute(player) { ... } for later state or session access from the player's region.
Velocity creates state and runs callbacks on its dedicated UI thread through an asynchronous opening API.
The service negotiates supported declarations, sends retained updates, and keeps sessions isolated by player and owning plugin.
Plugin disable and player disconnection release associated handlers, observations, and pending transfers.
Screen and HUD sessions use the same definition and control API.
Remote components include editable form bindings, server-owned virtual-list rows, CPU Canvas snapshots, ready image tiles, and native inventory Slots.
Client edits and server replacements are ordered so older acknowledgements do not overwrite newer input.
Slot transactions use Minecraft's existing container handling, and container-bound HUDs close when their container changes.
Synchronous input-consumption decisions and custom native rendering require client-side implementations.
Install the appropriate platform plugin artifact and the matching client runtime; vanilla clients cannot display these UIs.
Proxy-owned and backend-owned sessions have independent negotiation and authenticated routing, and can coexist as one foreground Screen plus multiple HUDs.
The public Fabric runtime does not require Fabric API.
The Paper plugin also supports Folia; consuming plugins must declare folia-supported: true and obey native region ownership.
Ordinary movement, including riding a minecart, keeps UIs open; teleportation that replaces a native container retires its bound UI.
Velocity does not create native inventories or translate Minecraft protocol versions.
Remote peers use protocol version 1 and require matching Strata builds on both ends.
See Velocity setup and examples, Paper setup and examples and the exact-version compatibility matrix.
Platform APIs and lifecycle events
strata-paper-api and strata-velocity-api separate application-facing opening methods and event types from runtime implementation modules.
Consumers compile against the corresponding API and depend on the installed Strata plugin without bundling it.
PaperUi provides capabilities, owner-scoped factories and state access, and registration; VelocityUi provides owner-thread factories, queued work, and asynchronous capabilities.
Both platforms publish client-ready and connection-ended notifications, plus UI-opened, presentation-changed, and UI-closed events.
Opening and presentation notifications follow client application acknowledgement, and terminal events include the reason and last applied presentation.
Paper and Folia events use Bukkit listeners; Velocity listeners read event snapshots and queue live session operations through VelocityUi.execute.
See the event contract for ordering, failure, and threading details.
Kotlin/JavaScript and browser rendering
The platform-neutral API and retained core now target both JVM and JavaScript, allowing shared definitions and state logic across runtimes.
Existing JVM artifact coordinates remain available.
Portable profile identifiers use Uuid and parseUuid; the JVM identifier remains java.util.UUID.
The new Web runtime mounts retained layouts, text, buttons, and native progress elements into a browser DOM.
Keyed updates preserve compatible DOM elements, and unchanged text measurements are reused.
renderWebHtml produces initial content, while renderWebDocument produces a complete initial document with a deferred application script.
Mounting a matching definition adopts that initial DOM; inconsistent initial content is rejected.
WebTheme.Native and WebTheme.Minecraft select native browser styling or an original Minecraft-inspired CSS theme without requiring game assets; build rendering and mounting must use the same theme.
Web support is a subset of Minecraft capabilities: unavailable components, HUD presentation, and game-input controls fail explicitly.
Browser demos cover reactive counters, keyed lists, and progress, and are included with the generated API documentation.
See the Web examples for compiled applications and initial-document generation.
Custom declarations and remote extensions
Elements and modifiers can optionally expose typed declaration projections.
The projection SPI represents immutable properties, action endpoints, state bindings, and resource snapshots without transmitting application objects or executable code.
Typed input subscriptions add declared keyboard/button filters and propagation behavior with server-side event notifications, including capture and cancellation.
Event-dependent synchronous consumption remains a client responsibility.
Custom remote types must be registered on both endpoints with matching namespaced schema identities.
Unsupported types are rejected during admission rather than silently omitted.
Local custom components continue to work without projection registration.
For remote extensions, follow the declaration projection contract and the compiled Paper/client extension examples.
Minecraft compatibility and examples
Minecraft 26.3 gains its own Fabric runtime, native input and rendering integration, and distribution metadata.
Minecraft 1.20 remains the supported floor; select the exact versioned runtime and its required Java version from the compatibility matrix.
Loaded-client development and packaged-JAR checks remain distinct from exact-version Paper and Velocity server acceptance.
Documentation adds an animated player-list walkthrough with compiled source and still frames, interactive browser demos alongside Dokka, platform setup guides, and extension contracts.
Upgrading from 0.1.6
- Replace
ScreenDefinitionandScreens.open(...)withUiDefinitionanddefinition.open()for new code. The deprecated entries delegate to the common path. - Rebuild consumers after the event callback receiver change. Wrap stored callbacks or bound method references when necessary, for example
onActivate { handler() }; event arguments and return values are unchanged. - Close an unused definition with
definition.close()and an opened UI withsession.close(). Create a fresh definition for each opening. - Kee...
Strata 0.1.6
Strata 0.1.6
Per-editor input appearance
TextField and TextArea accept TextInputAppearance.Custom with normal, focused, and disabled nine-slice images, an insertion-caret color, and a composition-underline color. This supports search fields and message/note editors that blend into light or application-colored panels while using the standard retained editor. Text color and font remain controlled by the existing textStyle and font arguments.
The new overloads preserve all existing signatures, and omitting the appearance retains the previous profile frame and editing decorations. TextInputAppearance.Default explicitly selects that same behavior. Custom transparent pixels reveal the underlying background, and custom nine-slice centers stretch without changing editor padding or text metrics.
Appearance changes repaint the existing editor without remeasuring, replacing input nodes, or discarding focus, composition, or scroll. This is a paint optimization; changing pixels can still require native rasterization and upload. Retain immutable images and appearances outside observed content, and use a narrow Observe for a changing theme. Direct enabled State inputs remain available on every appearance overload.
The shared runtime tests cover default pixel compatibility, transparent frames, invalid borders, caret and composition colors, disabled frames, retained editing state, paint-only changes, and idle-frame reuse. The loaded-client scenario checks retained nodes, phase counts, idle native work, and exact native/headless image agreement through the existing version adapters.
Generated API references and the compiled reactive skill example include the new overloads and appearance selection. See the Strata skill and component reference.
Exact transformed viewport clipping
Fractional scaleToFit geometry now keeps scroll and explicit paint clips precise until final physical pixel coverage is determined.
A viewport edge at 43.5 logical pixels therefore clips at physical pixel 174 at density four, rather than admitting two pixels into an adjacent header.
Integer geometry and retained frame reuse remain unchanged.
Portable images crossing a fractional edge use the bounded fallback without changing their source mapping; images fully inside keep the direct native texture path.
Custom exhaustive display-list backends must handle the new DrawCommand.PushFractionalClip variant, balanced by the existing PopClip.
The Minecraft presenter rejects opaque platform payloads crossing fractional clips before frame-layer submission; wholly contained payloads remain supported.
Portable standard components require no screen API or layout changes.
Strata 0.1.5
Strata 0.1.5
Strata 0.1.5 adds direct state inputs, lazy projections, observed regions, and render monitoring so applications can update an open screen while retaining compatible input and scrolling nodes.
Applications keep the existing ScreenDefinition opening API and explicitly bind the parts of their tree that depend on changing state.
Install
Compile application UI source against the API, then install exactly one Fabric runtime matching the active Minecraft version together with Fabric Language Kotlin:
dependencies {
compileOnly("dev.s7a.strata:strata-api:0.1.5")
modRuntimeOnly("dev.s7a.strata:strata-runtime-minecraft-fabric-<minecraft-version>:0.1.5")
modRuntimeOnly("net.fabricmc:fabric-language-kotlin:<compatible-version>")
}The consuming Mod must require Strata in fabric.mod.json:
{
"depends": {
"strata": ">=0.1.5"
}
}Observe changing regions
Observe(source) { value -> ... } declares a region whose callback receives the source's committed value.
Generated overloads accept one through 22 StateSource<V> arguments with independently inferred value types and pass their values in declaration order.
Applications supply conforming sources through the existing StateSource contract; fixed values and ordinary captured Kotlin variables are not automatically reactive.
Observe owns one slot in its containing layout and accepts a modifier and optional stable key.
Its callback emits zero or one root; place an inner Row or Column around multiple components.
An empty region has zero natural size, subject to its parent's constraints and its own modifiers.
Apply parent data such as weight or alignment to Observe itself, and create child-layout parent data inside the callback's fresh layout scope.
The runtime shares one subscription and one committed snapshot per source reference identity within a retained tree.
This includes repeated arguments, nested Observe regions, and source-backed Text reading the same source.
At each frame cutoff it captures all pending observations before committing values and reconciling changed regions parent-first.
Multiple pending revisions coalesce to the newest snapshot, and equal committed values do not trigger a source-driven content evaluation.
Updates arriving after capture wait for the next frame.
Replacing the last reader's key or parent structure within a frame preserves that source instance's committed snapshot and pending notifications.
A source first referenced during deferred construction supplies its atomic subscription snapshot, which other readers in that tree reuse; subsequent notifications wait for the next cutoff.
A parent-supplied callback change also reevaluates its region even when that region's source values are unchanged, keeping captured parent values current.
Nested invalidations coalesce into one evaluation for each surviving region in the frame; a removed region does not run its pending content.
Unchanged regions reuse their retained child descriptions, and compatible keyed descendants keep their existing nodes.
Focus, text selection, IME preedit, and viewport state therefore survive compatible updates while the same screen remains open.
Changing a key or replacing a node still ends that node's ownership.
Keep editable state such as TextAreaState, TextFieldState, and scroll state outside observed callbacks.
Every callback runs on the tree owner thread with a fresh, callback-lifetime UiScope; it must not retain that scope or mutate its sources.
The tree releases subscriptions with no remaining reader before the frame returns, and releases all observation resources on terminal failure or close.
Source values remain application-owned and are not deep-copied.
Updates to independent sources are not an atomic application transaction; publish one immutable model through one source when multiple fields must change together.
Source-backed text
Text(source) accepts both StateSource<String> and StateSource<UiText> through the same Observe mechanism.
Both forms retain the existing text layout, wrapping, style, modifier, key, and optional explicit-font choices.
The complete modifier chain belongs to the actual text node; a transparent region owns its sibling key and delegates parent data to that node.
Text resolution and wrapping run on the tree owner thread against the committed value.
Existing literal Text overloads remain available.
The source overloads use distinct JVM names, TextStringSource and TextUiTextSource, to preserve the two Kotlin value types despite generic erasure.
The screens and state guide and compiled component example describe the ownership and composition contracts.
Compatibility with 0.1.4
Prefer literal values for fixed content, direct source inputs for changing component data, retained source.map { ... } projections for derived display values, and narrow Observe regions for structural or layout/style changes.
Direct overloads accept mixtures of sources and literals on ProgressBar, Image, PlayerHead, Canvas, TiledImage, Slot, Button, Tab, Checkbox, Slider, CycleButton, TextField, TextArea, VirtualList, and SelectionList.
Dedicated editing and navigation state remains caller-owned; indexed list count/lookups and refresh retain their existing API.
Canvas and tiled-image source replacement does not change their dedicated frame/tile delivery contracts.
Map construction is lazy, projections support nullable values and chains, and ordinary subscriptions preserve upstream revisions even for equal results.
The UI computes each retained projection from the committed frame input and only notifies its dependents when the result differs by ==.
Transforms must be pure and return normally; changing a parent callback still refreshes its captured content independently of source equality.
The opt-in runtime RuntimeUiDiagnosticsOwner capability supplies startRenderMonitoring() on sessions, Minecraft hosts, and Fabric screens.
It records actual content, node, subscription, and pipeline work without changing application screen definitions.
See render monitoring for owner-thread use, bounded retention, overflow, failure evidence, and native counter interpretation.
The public API change is additive and does not require a new screen factory or reopening a screen for each source update.
Applications choose explicit observed regions rather than acquiring implicit tracking of arbitrary Kotlin reads.
Custom runtime implementations opting into the internal StateObserverNode SPI must provide the same source identity, frame cutoff, and owner-thread observation contracts.
Keep all Strata artifacts aligned on 0.1.5.
Minecraft compatibility
The supported matrix remains Minecraft 1.20 through 1.20.6, Minecraft 1.21 through 1.21.11, 26.1, and 26.2.
Minecraft 1.20 through 1.20.4 use Java 17, Minecraft 1.20.5 through 1.21.11 use Java 21, and 26.1 through 26.2 use Java 25.
Distribution
- Maven Central contains the five common artifacts and 21 exact versioned Fabric runtimes.
- GitHub Releases contains 21 runtime JARs, 21 detached signatures, and
SHA256SUMS. - Modrinth contains one 0.1.5 version entry for each of the 21 exact Minecraft versions after project review.
Strata 0.1.4
Strata 0.1.4
Strata 0.1.4 adds a general scale-to-fit modifier for fixed design-space layouts.
It also preserves committed frame-layer order on deferred Fabric GUI renderers when fractional transforms make native overlap inference incomplete.
Install
Compile application UI source against the API, then install exactly one Fabric runtime matching the active Minecraft version together with Fabric Language Kotlin:
dependencies {
compileOnly("dev.s7a.strata:strata-api:0.1.4")
modRuntimeOnly("dev.s7a.strata:strata-runtime-minecraft-fabric-<minecraft-version>:0.1.4")
modRuntimeOnly("net.fabricmc:fabric-language-kotlin:<compatible-version>")
}The consuming Mod must require Strata in fabric.mod.json:
{
"depends": {
"strata": ">=0.1.4"
}
}Fixed design-space scaling
Modifier.scaleToFit(contentSize, contentAlignment, allowUpscaling) measures its component subtree once at the strictly positive fixed contentSize and uniformly contains that complete design surface in the modifier's outer bounds without cropping or distortion.
The smaller width or height ratio determines the scale, and contentAlignment positions any remaining space.
The default keeps the scale at or below one; set allowUpscaling = true when a filled outer viewport should also enlarge the design surface.
Place outer viewport modifiers before scaleToFit and design-space modifiers after it:
val modifier = Modifier.Empty
.fillMaxSize()
.scaleToFit(
contentSize = IntSize(640, 360),
allowUpscaling = true,
)The retained runtime applies the same accumulated transform to descendant geometry, portable painting, clips, pointer input, focus visibility, semantics, and root-overlay anchors.
This lets one screen keep its layout and interaction model while the host viewport or GUI density changes.
Zero-sized outer bounds leave the design subtree unplaced for that pass rather than producing an invalid scale.
Pointer event positions remain in tree space; local positions are inverse-mapped and floored, drag deltas inverse-scale, and scroll units remain unchanged.
Root-overlay commands remain in root space while only their anchors cross the child transform.
Fabric frame-layer ordering
Fractional transforms can make two visible layers overlap even when their transformed integer bounds do not express the last shared row or column.
Deferred Minecraft GUI renderers may otherwise keep those layers in one native node and reorder them by texture or pipeline state.
Deferred Fabric runtimes now advance the native ordering stratum between every adjacent resolved Strata frame layer.
Portable fills, direct sampled images, fallbacks, and platform draws therefore retain their committed display-list order without depending on native overlap inference.
Adapters for immediate-rendering Minecraft versions keep the same shared sequence through a no-op ordering boundary.
Compatibility with 0.1.3
The public API change is additive: existing modifiers remain available, and custom retained nodes can implement the new child-transform SPI only when they need equivalent subtree behavior.
A child transform applies to the provider node's child subtree, not to the provider node's own paint.
Custom implementations must invalidate layout whenever their reported transform can change without remeasurement because the runtime may retain that transform until layout invalidation.
Opaque platform draw commands, including native item rendering, still require unit scale and exact integer translation because their payload cannot be transformed generically.
Painting fails before adapter output when such a command appears below an unsupported transform.
Keep all Strata artifacts aligned on 0.1.4.
Minecraft compatibility
The supported matrix remains Minecraft 1.20 through 1.20.6, Minecraft 1.21 through 1.21.11, 26.1, and 26.2.
Minecraft 1.20 through 1.20.4 use Java 17, Minecraft 1.20.5 through 1.21.11 use Java 21, and 26.1 through 26.2 use Java 25.
Distribution
- Maven Central contains the five common artifacts and 21 exact versioned Fabric runtimes.
- GitHub Releases contains 21 runtime JARs, 21 detached signatures, and
SHA256SUMS. - Modrinth contains one 0.1.4 version entry for each of the 21 exact Minecraft versions after project review.
Strata 0.1.3
Strata 0.1.3
Strata 0.1.3 adds cyclic keyboard focus traversal and one shared pointer-and-keyboard activation modifier.
It also keeps resource-backed image identities stable within a Minecraft UI host while enforcing explicit retention limits.
Install
Compile application UI source against the API, then install exactly one Fabric runtime matching the active Minecraft version together with Fabric Language Kotlin:
dependencies {
compileOnly("dev.s7a.strata:strata-api:0.1.3")
modRuntimeOnly("dev.s7a.strata:strata-runtime-minecraft-fabric-<minecraft-version>:0.1.3")
modRuntimeOnly("net.fabricmc:fabric-language-kotlin:<compatible-version>")
}The consuming Mod must require Strata in fabric.mod.json:
{
"depends": {
"strata": ">=0.1.3"
}
}Keyboard focus and activation
An ignored Tab press moves focus cyclically through placed, focusable components in declared parent-before-child and sibling paint order.
Shift+Tab reverses the direction, while focused handlers retain first refusal by consuming the event.
Traversal skips targets fully outside the root viewport or an ancestor child clip, including clipped VirtualList overscan rows, and wraps at both ends.
Modifier.onActivate(action) combines a primary pointer press with focused Enter and Space presses without synthesizing pointer events.
Every delivered key press, including a repeat, invokes the action and consumes that event.
onActivate(enabled, action) returns the exact incoming modifier when disabled, retains no action, and creates no pointer, keyboard, or focus target.
Button and Tab continue to own appearance and semantics only, so callers opt into shared activation with the same enabled state or retain onPress for pointer-specific behavior.
Resource image identity retention
One Minecraft UI host now memoizes each admitted resource-backed image by structural ResourceId across immediate and deferred component evaluation.
Equivalent rebuilds therefore preserve the immutable image identity consumed by the retained sampled-image path and can reuse an existing native texture.
Direct pixel sources continue to bypass platform resource resolution.
The host admits at most 512 resource identifiers and 128 MiB of straight RGBA8 pixels without eviction.
Entries beyond either bound and failed resolutions bypass retention and remain retryable.
The cache is confined to the host's owner thread, each admitted entry remains fixed until host close, and every retained entry is cleared before terminal platform shutdown; a new host resolves against the then-active resource-pack stack.
Release and documentation consistency
The forward release controller now derives Maven coordinates, Modrinth entries, representative Minecraft checks, Java toolchains, Pages inventory, and README installation versions from canonical typed project metadata plus one current/predecessor identity pair.
The historical release workflows remain sealed, while a new release updates the same controller metadata instead of adding version-specific workflow copies, conditionals, or duplicated artifact inventories.
Compatibility with 0.1.2
The public API change is additive: the two Modifier.onActivate overloads are new, and existing component and modifier signatures remain available.
Automatic traversal is a behavioral addition only for an ignored Tab press; a focused handler that consumes Tab keeps its existing behavior.
Downstream adapters opting into the internal MinecraftUiPlatform SPI must not rely on image(ResourceId) being called for every declarative use because admitted successful resolutions may be reused for the host lifetime.
Keep all Strata artifacts aligned on 0.1.3.
Minecraft compatibility
The supported matrix remains Minecraft 1.20 through 1.20.6, Minecraft 1.21 through 1.21.11, 26.1, and 26.2.
Minecraft 1.20 through 1.20.4 use Java 17, Minecraft 1.20.5 through 1.21.11 use Java 21, and 26.1 through 26.2 use Java 25.
Distribution
- Maven Central contains the five common artifacts and 21 exact versioned Fabric runtimes.
- GitHub Releases contains 21 runtime JARs, 21 detached signatures, and
SHA256SUMS. - Modrinth contains one 0.1.3 version entry for each of the 21 exact Minecraft versions after project review.
Strata 0.1.2
Strata 0.1.2
Strata 0.1.2 corrects the retained presentation path for standard Minecraft images and player heads.
It keeps the 0.1.1 API and rendering contracts while allowing supported Fabric runtimes to retain these immutable images as native textures instead of rebuilding the whole portable viewport when only placement changes.
Install
Compile application UI source against the API, then install exactly one Fabric runtime matching the active Minecraft version together with Fabric Language Kotlin:
dependencies {
compileOnly("dev.s7a.strata:strata-api:0.1.2")
modRuntimeOnly("dev.s7a.strata:strata-runtime-minecraft-fabric-<minecraft-version>:0.1.2")
modRuntimeOnly("net.fabricmc:fabric-language-kotlin:<compatible-version>")
}The consuming Mod must require Strata in fabric.mod.json:
{
"depends": {
"strata": ">=0.1.2"
}
}Retained image presentation
The standard Minecraft Image component now emits DrawCommand.SampledImage for its selected source region and logical destination.
Supported Fabric presenters can therefore retain the immutable image in their bounded device-owned texture cache and draw placement-only changes without a full portable viewport upload.
Headless rendering continues to use the same portable command and nearest final-density sampling contract.
PlayerHead uses the same sampled-image path for the base face and optional hat.
Sizes expressed with PlayerHeadScale retain the normalized 64 by 64 skin and the exact Minecraft face and hat source regions, preserving equal source-texel sizes and face-before-hat composition.
Accepted legacy sizes not divisible by eight still use the bounded region-clamped premultiplied bilinear image introduced in 0.1.1; that derived image is now retained through SampledImage as well.
Transparent hat pixels remain composited without an alpha discard threshold.
Compatibility with 0.1.1
This patch does not add or remove public API members.
It changes the draw-command variant produced by standard Image and PlayerHead runtime implementations from integer BlitImage to SampledImage.
Custom backends must already support or explicitly reject DrawCommand.SampledImage, which became part of the sealed command hierarchy in 0.1.1.
Keep all Strata artifacts aligned on 0.1.2.
Minecraft compatibility
The supported matrix remains Minecraft 1.20 through 1.20.6, Minecraft 1.21 through 1.21.11, 26.1, and 26.2.
Minecraft 1.20 uses Java 17, the Minecraft 1.21 family uses its declared Java 21 boundary, and 26.x uses Java 25.
Distribution
- Maven Central contains the five common artifacts and 21 exact versioned Fabric runtimes.
- GitHub Releases contains 21 runtime JARs, 21 detached signatures, and
SHA256SUMS. - Modrinth contains one 0.1.2 version entry for each of the 21 exact Minecraft versions after project review.
Strata 0.1.1
Strata 0.1.1
Strata 0.1.1 expands the platform-neutral UI toolkit with Unicode and resource-pack fonts, multiline text editing, wrapping layout, extensible canvases, retained sampled-image acceleration, tiled pan-and-zoom images, and typed player-head scaling.
It also adds a Minecraft 1.20 runtime while keeping every common and versioned runtime on one aligned release.
Install
Compile application UI source against the API, then install exactly one Fabric runtime matching the active Minecraft version together with Fabric Language Kotlin:
dependencies {
compileOnly("dev.s7a.strata:strata-api:0.1.1")
modRuntimeOnly("dev.s7a.strata:strata-runtime-minecraft-fabric-<minecraft-version>:0.1.1")
modRuntimeOnly("net.fabricmc:fabric-language-kotlin:<compatible-version>")
}The consuming Mod must require Strata in fabric.mod.json:
{
"depends": {
"strata": ">=0.1.1"
}
}Layout, media, and navigation
FlowRow measures each child once, wraps exact-fit rows, and supports checked horizontal and vertical gaps, per-row arrangement, and child vertical alignment without synthetic retained parents.
Canvas embeds immutable CPU images, leased native textures, or per-attachment custom offscreen renderers in an explicitly sized component.
Native resources use bounded ownership, capture and consumption fences, deterministic retirement, and fail-closed terminal handling.
General captured pointer input supports drag and release delivery after the pointer leaves component bounds.
DrawCommand.SampledImage lets supported Fabric runtimes retain decoded images as bounded native textures instead of rerasterizing and uploading the whole viewport when only placement changes.
Portable rendering remains available for unsupported sources and capacity pressure.
TiledImage composes multiresolution tile sources with a bounded visible and overscan working set.
PanZoomState provides anchored zoom, fit modes, clamping, and world-to-local transforms while tile subscriptions follow the viewport.
Application-owned generation and invalidation remain outside the component cache.
PlayerHeadScale expresses a positive integer skin-texel scale directly: PlayerHeadScale(1) renders an 8 by 8 head, and larger factors keep every source texel equal in size.
The existing arbitrary size overload remains binary compatible but is deprecated; sizes divisible by eight retain nearest sampling and other accepted sizes use bounded region-clamped bilinear interpolation for the face and hat layers.
Text and fonts
Text, common labels, tooltips, TextField, and TextArea can select resource-pack fonts.
TextField remains a single-line editor; TextArea adds canonical LF values, visual-line navigation, a typed viewport, and vertical scrolling through its state-owned ScrollState.
Both edit at Unicode code-point boundaries and keep IME composition events supplied by Minecraft separate from the committed value.
Existing Text calls remain single-line; the required TextLayout.Multiline overload wraps to parent constraints with word or character wrapping, line limits, clipping or ellipsis, and line spacing.
See the text guide and compiled examples for editing and layout contracts.
The optional strata-runtime-minecraft-fonts-lwjgl CPU backend renders supplied font resources without launching Minecraft.
Glyph coverage, including emoji, follows the selected Minecraft font resources; this release does not add system fonts or a separate color-emoji engine.
Resource loading enforces explicit size and work budgets, and ordinary Fabric screen opens reuse one immutable profile generation until resource reload.
Signed and signed-zero TrueType settings follow the selected native provider, subject to the documented numeric safety boundary.
Native metrics and raw glyph data remain exact acceptance requirements.
Fabric and headless output match exactly at tested scales; final native image differences are accepted only with independent GPU evidence.
The acceptance scope identifies tested resources, targets, and device qualifications.
API migration from 0.1.0
This release intentionally adds UiText.WithFont and DrawCommand.SampledImage to existing sealed hierarchies.
Exhaustive Kotlin visitors need the new cases before recompilation, and previously compiled visitors can fail when a new case reaches them.
Existing JVM signatures, component overloads, and TextStyle remain available; that does not make old exhaustive visitors source or behavior compatible.
Custom rendering backends need the fractional sampled-image contract even for ordinary Text calls using the default resource-font profile.
Update custom visitors and keep all Strata artifacts aligned; the supplied Fabric and headless backends handle the new cases.
See Source compatibility for migration details.
Minecraft compatibility
The supported release floor is now Minecraft 1.20.
The complete supported matrix is Minecraft 1.20 through 1.20.6, Minecraft 1.21 through 1.21.11, 26.1, and 26.2.
The Minecraft 1.20 runtime targets Java 17.
Distribution
The aligned 0.1.1 release publishes the complete supported matrix so every runtime uses the same Strata version.
- Maven Central contains 26 coordinates: the five common artifacts, including the optional
strata-runtime-minecraft-fonts-lwjglCPU backend, and 21 versioned Fabric runtimes. - GitHub Releases contains 21 runtime JARs, 21 detached signatures, and
SHA256SUMS. - Modrinth contains one 0.1.1 version entry for each of the 21 exact Minecraft versions.
Minecraft 1.19 and older releases remain outside the project scope.
Strata 0.1.0
Strata 0.1.0
Strata 0.1.0 is the first public release of the platform-neutral authoring API, retained runtime, headless renderer, and separately installed client Fabric runtime.
Use it
Compile application UI definitions against dev.s7a.strata:strata-api:0.1.0 and install exactly one strata-runtime-minecraft-fabric-<minecraft-version>:0.1.0 Mod matching the client together with Fabric Language Kotlin.
Open a one-shot definition through ScreenDefinition.open() or Java's Screens.open(definition); ordinary UI source does not import a runtime implementation or receive MinecraftUiContext.
The compiled API-only opening example is the canonical snippet reused by the public skill and release-page metadata.
The supported Minecraft range is 1.20.1 through 1.21.11 plus 26.1 and 26.2.
Minecraft 1.19 and older versions are outside the release scope.
Highlights
- Structural Row, Column, Grid, and intentional-overlap Stack layout with arrangement, alignment, spacing, weight, checked constraints, and active modifiers.
- Text, TextField, Button, Checkbox, generic CycleButton, Slider, Tab, ScrollArea, independent Scrollbar, VirtualList, SelectionList, Image, Slot, PlayerHead, LoadingIndicator, and ProgressBar components.
- Leading and trailing infinite-list requests, index and stable-key jumps, resource-pack images and backgrounds, profile-driven player heads, and synchronized player, container, ender-chest, furnace, or custom-menu slot bindings.
- Public Element and Node SPI for downstream retained primitives, while purpose-specific Mod components remain ordinary compositions.
- Deterministic headless PNG and semantics output, loaded Minecraft native/Fabric/headless comparisons, real inventory interaction, and render/retention measurements.
Verification
The release commit passes Kotlin explicit API mode, warnings-as-errors, ABI validation, Detekt, Kotlinter, Qodana, JVM tests, Kover reports, all supported loaded-client suites, published-coordinate consumer tests, generated-skill checks, link and asset checks, and publication metadata inspection.
Component documentation images are complete dedicated ScreenDefinition frames rather than crops from a larger showcase.
Distribution
- Maven Central contains
strata-api, the common runtime modules, and all 20 versioned Fabric runtime artifacts with sources, Javadoc, signatures, Gradle metadata, and MIT license files. - The GitHub Release contains the same canonical 20 runtime JARs, detached signatures, checksums, and these notes.
- Modrinth contains one client-only Fabric release entry per exact Minecraft version and declares Fabric Language Kotlin as required.
- The public
skills/stratapackage contains mechanically checked API signatures and Strata-specific authoring guidance.
Generative AI substantially assisted implementation, review, tests, documentation, and release-page text.
The maintainer directed the design and validates release artifacts through the public test suite.
Known limitations
- The verified bitmap font path supports printable ASCII with the regular Minecraft glyph sheet.
- Forced Unicode and multi-resource font stacks are not supported in this release.
- Resource-backed images keep their declared logical dimensions when a resource pack replaces their pixels.