diff --git a/README.md b/README.md
index 2a28029..8aafded 100644
--- a/README.md
+++ b/README.md
@@ -518,12 +518,15 @@ public abstract class FMLIgnoreMissingMappingExample {
}
```
-### 9. Versioned Chunk and Player Transformers
+### 9. Versioned Transformers
Postea provides some API endpoints to allow mods to have versioned changes. The mod declares that it
expects some version, and if Postea detects that a chunk or player was saved on a previous version, runs a transformer
to bring them up-to-date. Register an `IVersionedTransformer` through `VersionedReplacementManager.register`.
+Some mods keep item stacks stored outside chunks or player data. Postea provides an API, `CustomDataReplacementManager`,
+for those mods to allow that data to be transformed by an `IVersionedTransformer`.
+
> [!IMPORTANT]
>
> Versioned transformers run before every other Postea pass, in registration order, and are never disabled in a dev
@@ -600,31 +603,3 @@ When a name resolves only through retired ids, Postea logs it once per world loa
```
Block ExtraUtilities:cobblestone_compressed is no longer registered; its transformers target retired id(s) [3402]
```
-
-### 11. Custom World Data
-
-Some mods keep item stacks outside chunks and player data: a quest database, an ender chest table, per-player
-sidecar files. Postea never reads or writes such files itself -- the owning mod offers their content through
-`CustomDataReplacementManager` and versioned transformers reach it via `IVersionedTransformer.transformCustomData`.
-
-The contract for the owning mod:
-
-- Call `CustomDataReplacementManager.transform(storageId, root)` once on the NBT root read from disk, before
- consuming it. Postea runs every registered transformer whose stamp differs and writes updated `POSTEA_VERSIONS`
- stamps onto the root. Persist that root, stamps included, when writing the storage back.
-- A save path that rebuilds its NBT from scratch calls `CustomDataReplacementManager.stamp(freshRoot)` instead:
- once `transform` ran at load, the in-memory data is at the current version.
-- A consumer that never writes the storage back (a read-only restore of an archived file) calls only `transform`.
- An unstamped file re-transforms from the same baseline on every read, which is correct while its bytes never
- change.
-
-The `storageId` is a namespaced label used in logs and crash reports, e.g. `"betterquesting:questDatabase"`.
-`transform` must not run before FML has applied the world's saved id map (it throws otherwise); any call site at
-world load or later is safe. Stacks in custom storage may carry a string `id` (a registry name) instead of a
-numeric one; `CustomDataTransformContext.forEachItemStackTag` visits both forms.
-
-> [!NOTE]
->
-> Data derived from stacks rather than stored as stacks is out of reach of this API. Known cases that stay
-> untransformed: Thaumcraft's scanned-object hashes (players rescan after their items' metadata changes), fluid
-> names, MineTweaker script item literals, and the numeric item ids inside vanilla `stats/` files.
diff --git a/src/main/java/com/gtnewhorizons/postea/api/CustomDataReplacementManager.java b/src/main/java/com/gtnewhorizons/postea/api/CustomDataReplacementManager.java
index afccd3e..9bfc16e 100644
--- a/src/main/java/com/gtnewhorizons/postea/api/CustomDataReplacementManager.java
+++ b/src/main/java/com/gtnewhorizons/postea/api/CustomDataReplacementManager.java
@@ -12,25 +12,18 @@ import com.gtnewhorizons.postea.utility.VersionedTransformerLog;
import cpw.mods.fml.common.FMLCommonHandler;
/**
- * Versioned transformation of a mod's own world storage -- files outside chunks and player data, such as a quest
- * database or an ender chest table. Postea never reads or writes such files itself; the owning mod offers their
- * content at the moments it controls:
+ * Manages applying an {@link IVersionedTransformer} to mods' custom storage files.
*
* - Call {@link #transform} once on the root read from disk, before consuming it, and persist that root (stamps
* included) when writing the storage back.
- * - A save path that rebuilds its NBT from scratch calls {@link #stamp} on the fresh root instead; once
- * {@link #transform} ran at load, the in-memory data is at the current version, so stamping current is correct.
- * - A consumer that never writes the storage back (a read-only restore) calls only {@link #transform}: an
- * unstamped file re-transforms from the same baseline on every read, which is correct while its bytes never
- * change.
+ * - A save path that rebuilds its NBT from scratch calls {@link #stamp} on the fresh root instead.
*
*/
public abstract class CustomDataReplacementManager {
/**
* Transforms {@code root} in place through every registered transformer whose stamp differs from its current
- * version, then writes the updated stamps onto {@code root}. Does nothing without a running server (a
- * multiplayer client). Throws
+ * version, then writes the updated stamps onto {@code root}. Does nothing without a running server. Throws
* {@link IllegalStateException} when called before the world's saved id mappings were applied.
*/
public static void transform(String storageId, NBTTagCompound root) {
diff --git a/src/main/java/com/gtnewhorizons/postea/api/CustomDataTransformContext.java b/src/main/java/com/gtnewhorizons/postea/api/CustomDataTransformContext.java
index e12efbd..16e766b 100644
--- a/src/main/java/com/gtnewhorizons/postea/api/CustomDataTransformContext.java
+++ b/src/main/java/com/gtnewhorizons/postea/api/CustomDataTransformContext.java
@@ -8,10 +8,8 @@ import com.gtnewhorizons.postea.utility.NbtItemStacks;
import com.gtnewhorizons.postea.utility.VersionStamps;
/**
- * A mod's own world storage as handed to {@link IVersionedTransformer#transformCustomData}: the NBT root the
- * owning mod read from disk, before it consumes the data. Unlike chunk and player data, stacks here may carry a
- * string {@code id} (a registry name, as quest databases store) instead of a numeric one;
- * {@link #forEachItemStackTag} visits both forms.
+ * Context for a mod's custom world storage, used by {@link IVersionedTransformer#transformCustomData}. Stacks here
+ * may have string {@code id}s instead of numeric ones; {@link #forEachItemStackTag} visits both.
*/
public final class CustomDataTransformContext {
diff --git a/src/main/java/com/gtnewhorizons/postea/api/IVersionedTransformer.java b/src/main/java/com/gtnewhorizons/postea/api/IVersionedTransformer.java
index e311e1a..dbe21d3 100644
--- a/src/main/java/com/gtnewhorizons/postea/api/IVersionedTransformer.java
+++ b/src/main/java/com/gtnewhorizons/postea/api/IVersionedTransformer.java
@@ -42,7 +42,7 @@ public interface IVersionedTransformer {
default void transformPlayer(PlayerDataTransformContext ctx) {}
/**
- * Brings a mod's own world storage stamped at {@link CustomDataTransformContext#storedVersion()} to
+ * Brings a mod's custom world storage stamped at {@link CustomDataTransformContext#storedVersion()} to
* {@link #currentVersion()}. Stacks in such storage may carry a string {@code id} instead of a numeric one.
*/
default void transformCustomData(CustomDataTransformContext ctx) {}
diff --git a/src/main/java/com/gtnewhorizons/postea/utility/VersionStamps.java b/src/main/java/com/gtnewhorizons/postea/utility/VersionStamps.java
index cf51ab4..9c9fc5b 100644
--- a/src/main/java/com/gtnewhorizons/postea/utility/VersionStamps.java
+++ b/src/main/java/com/gtnewhorizons/postea/utility/VersionStamps.java
@@ -8,7 +8,7 @@ import net.minecraft.nbt.NBTTagCompound;
import com.gtnewhorizons.postea.api.IVersionedTransformer;
/**
- * The {@code POSTEA_VERSIONS} compound Postea keeps on a chunk's {@code Level} tag and on a player's root tag: one
+ * The {@code POSTEA_VERSIONS} compound Postea keeps on data handled by {@link IVersionedTransformer}s, one
* int per registered transformer key. Keys of transformers that are not registered in the running session are
* carried through unchanged so a mod that is temporarily absent does not lose its stamps.
*/