@@ -69,9 +69,10 @@ Define the data structure at version 100:
6969``` java
7070package com.example.game.schema ;
7171
72- import de.splatgames.aether.datafixers.api.DataVersion ;
7372import de.splatgames.aether.datafixers.api.dsl.DSL ;
7473import de.splatgames.aether.datafixers.api.schema.Schema ;
74+ import de.splatgames.aether.datafixers.api.type.TypeRegistry ;
75+ import de.splatgames.aether.datafixers.api.type.template.TypeTemplate ;
7576import de.splatgames.aether.datafixers.core.type.SimpleTypeRegistry ;
7677import com.example.game.TypeReferences ;
7778
@@ -87,20 +88,30 @@ import com.example.game.TypeReferences;
8788public class Schema100 extends Schema {
8889
8990 public Schema100 () {
90- super (new DataVersion (100 ), null , SimpleTypeRegistry :: new );
91+ super (100 , null ); // No parent - this is the first version
92+ }
93+
94+ @Override
95+ protected TypeRegistry createTypeRegistry () {
96+ return new SimpleTypeRegistry ();
9197 }
9298
9399 @Override
94100 protected void registerTypes () {
95- registerType(TypeReferences . PLAYER , DSL . and(
101+ registerType(TypeReferences . PLAYER , player());
102+ }
103+
104+ /* * Player type template for v1.0.0 */
105+ public static TypeTemplate player () {
106+ return DSL . and(
96107 DSL . field(" playerName" , DSL . string()),
97108 DSL . field(" xp" , DSL . intType()),
98109 DSL . field(" x" , DSL . doubleType()),
99110 DSL . field(" y" , DSL . doubleType()),
100111 DSL . field(" z" , DSL . doubleType()),
101112 DSL . field(" gameMode" , DSL . intType()),
102113 DSL . remainder()
103- )) ;
114+ );
104115 }
105116}
106117```
@@ -114,9 +125,10 @@ Define the updated structure:
114125``` java
115126package com.example.game.schema ;
116127
117- import de.splatgames.aether.datafixers.api. DataVersion ;
118128import de.splatgames.aether.datafixers.api.dsl.DSL ;
119129import de.splatgames.aether.datafixers.api.schema.Schema ;
130+ import de.splatgames.aether.datafixers.api.type.TypeRegistry ;
131+ import de.splatgames.aether.datafixers.api.type.template.TypeTemplate ;
120132import de.splatgames.aether.datafixers.core.type.SimpleTypeRegistry ;
121133import com.example.game.TypeReferences ;
122134
@@ -131,23 +143,33 @@ import com.example.game.TypeReferences;
131143 */
132144public class Schema110 extends Schema {
133145
134- public Schema110 (Schema parent ) {
135- super (new DataVersion (110 ), parent, SimpleTypeRegistry :: new );
146+ public Schema110 () {
147+ super (110 , new Schema100 ()); // Extends from v1.0.0
148+ }
149+
150+ @Override
151+ protected TypeRegistry createTypeRegistry () {
152+ return new SimpleTypeRegistry ();
136153 }
137154
138155 @Override
139156 protected void registerTypes () {
140- registerType(TypeReferences . PLAYER , DSL . and(
157+ registerType(TypeReferences . PLAYER , player());
158+ }
159+
160+ /* * Player type template for v1.1.0 */
161+ public static TypeTemplate player () {
162+ return DSL . and(
141163 DSL . field(" name" , DSL . string()),
142164 DSL . field(" experience" , DSL . intType()),
143165 DSL . field(" position" , position()),
144166 DSL . field(" gameMode" , DSL . string()),
145167 DSL . remainder()
146- )) ;
168+ );
147169 }
148170
149171 /* * Position type template */
150- public static DSL . TypeTemplate position() {
172+ public static TypeTemplate position () {
151173 return DSL . and(
152174 DSL . field(" x" , DSL . doubleType()),
153175 DSL . field(" y" , DSL . doubleType()),
@@ -172,40 +194,45 @@ import de.splatgames.aether.datafixers.api.rewrite.Rules;
172194import de.splatgames.aether.datafixers.api.rewrite.TypeRewriteRule ;
173195import de.splatgames.aether.datafixers.api.schema.Schema ;
174196import de.splatgames.aether.datafixers.api.schema.SchemaRegistry ;
197+ import de.splatgames.aether.datafixers.codec.json.gson.GsonOps ;
175198import de.splatgames.aether.datafixers.core.fix.SchemaDataFix ;
176- import com.example.game . TypeReferences ;
199+ import org.jetbrains.annotations.NotNull ;
177200
178201/**
179202 * Migrates player data from v1.0.0 (100) to v1.1.0 (110).
180203 */
181- public class PlayerV1ToV2Fix extends SchemaDataFix {
204+ public class PlayerV100ToV110Fix extends SchemaDataFix {
182205
183- public PlayerV1ToV2Fix (SchemaRegistry schemas ) {
206+ public PlayerV100ToV110Fix (SchemaRegistry schemas ) {
184207 super (
185- " player_v1_to_v2 " ,
208+ " player_v100_to_v110 " ,
186209 new DataVersion (100 ),
187210 new DataVersion (110 ),
188211 schemas
189212 );
190213 }
191214
192215 @Override
193- protected TypeRewriteRule makeRule (Schema inputSchema , Schema outputSchema ) {
216+ @NotNull
217+ protected TypeRewriteRule makeRule (@NotNull Schema inputSchema ,
218+ @NotNull Schema outputSchema ) {
194219 return Rules . seq(
195220 // 1. Rename fields
196- Rules . renameField(TypeReferences . PLAYER , " playerName" , " name" ),
197- Rules . renameField(TypeReferences . PLAYER , " xp" , " experience" ),
221+ Rules . renameField(GsonOps . INSTANCE , " playerName" , " name" ),
222+ Rules . renameField(GsonOps . INSTANCE , " xp" , " experience" ),
198223
199224 // 2. Transform gameMode from int to string
200- Rules . transformField(TypeReferences . PLAYER , " gameMode" , this :: gameModeToString),
225+ Rules . transformField(GsonOps . INSTANCE , " gameMode" ,
226+ PlayerV100ToV110Fix :: gameModeToString),
201227
202228 // 3. Group coordinates into position object
203- Rules . transform( TypeReferences . PLAYER , this :: groupPosition )
229+ Rules . groupFields( GsonOps . INSTANCE , " position " , " x " , " y " , " z " )
204230 );
205231 }
206232
207- private Dynamic<?> gameModeToString (Dynamic<?> value ) {
208- int mode = value. asInt(). orElse(0 );
233+ @NotNull
234+ private static Dynamic<?> gameModeToString (@NotNull Dynamic<?> value ) {
235+ int mode = value. asInt(). result(). orElse(0 );
209236 String modeName = switch (mode) {
210237 case 0 - > " survival" ;
211238 case 1 - > " creative" ;
@@ -215,26 +242,6 @@ public class PlayerV1ToV2Fix extends SchemaDataFix {
215242 };
216243 return value. createString(modeName);
217244 }
218-
219- private Dynamic<?> groupPosition (Dynamic<?> player ) {
220- // Extract coordinates
221- double x = player. get(" x" ). asDouble(). orElse(0.0 );
222- double y = player. get(" y" ). asDouble(). orElse(0.0 );
223- double z = player. get(" z" ). asDouble(). orElse(0.0 );
224-
225- // Create position object
226- Dynamic<?> position = player. emptyMap()
227- .set(" x" , player. createDouble(x))
228- .set(" y" , player. createDouble(y))
229- .set(" z" , player. createDouble(z));
230-
231- // Remove old fields and add position
232- return player
233- .remove(" x" )
234- .remove(" y" )
235- .remove(" z" )
236- .set(" position" , position);
237- }
238245}
239246```
240247
@@ -254,6 +261,7 @@ import de.splatgames.aether.datafixers.api.schema.SchemaRegistry;
254261import com.example.game.fix.PlayerV1ToV2Fix ;
255262import com.example.game.schema.Schema100 ;
256263import com.example.game.schema.Schema110 ;
264+ import org.jetbrains.annotations.NotNull ;
257265
258266/**
259267 * Bootstrap for the game data fixer.
@@ -266,21 +274,18 @@ public class GameDataBootstrap implements DataFixerBootstrap {
266274 private SchemaRegistry schemas;
267275
268276 @Override
269- public void registerSchemas (SchemaRegistry schemas ) {
277+ public void registerSchemas (@NotNull SchemaRegistry schemas ) {
270278 this . schemas = schemas;
271279
272280 // Register schemas in version order
273- Schema100 v100 = new Schema100 ();
274- Schema110 v110 = new Schema110 (v100);
275-
276- schemas. register(v100);
277- schemas. register(v110);
281+ schemas. register(new Schema100 ());
282+ schemas. register(new Schema110 ());
278283 }
279284
280285 @Override
281- public void registerFixes (FixRegistrar fixes ) {
286+ public void registerFixes (@NotNull FixRegistrar fixes ) {
282287 // Register fixes
283- fixes. register(TypeReferences . PLAYER , new PlayerV1ToV2Fix (schemas));
288+ fixes. register(TypeReferences . PLAYER , new PlayerV100ToV110Fix (schemas));
284289 }
285290}
286291```
@@ -337,7 +342,6 @@ public class GameExample {
337342
338343 // 5. Print result
339344 System . out. println(" \n === Migrated Data (v1.1.0) ===" );
340- @SuppressWarnings (" unchecked" )
341345 Dynamic<JsonElement > result = (Dynamic<JsonElement > ) migrated. value();
342346 System . out. println(GSON . toJson(result. value()));
343347 }
@@ -398,7 +402,7 @@ Define all type references in one class for easy discovery.
398402
399403### 4. Use Parent Schemas
400404
401- Chain schemas : `Schema110(v100)` inherits from ` Schema100`.
405+ Each schema creates its own parent internally : ` Schema110 ` extends ` Schema100 ` via ` super(110, new Schema100()) ` .
402406
403407### 5. Test Your Fixes
404408
0 commit comments