How to migrate an attachment
Learn how to make a backwards-compatible update to the data stored by your attachment.
Introduction
Suppose you made a RocketShipAttachment for your rocket ship mod, which stores the amount of fuel in a rocket ship. Previously, your attachment stored this data as a String, but you've since realized that it's probably better to store it as a Double, so you want to migrate it.
package my.packagename
class RocketShipAttachment(var fuel: String)
package my.packagename;
public final class RocketShipAttachment {
private String fuel;
public RocketShipAttachment(String fuel) {
this.fuel = fuel;
}
public void setFuel(String fuel) {
this.fuel = fuel;
}
public String getFuel() {
return fuel;
}
}
Steps
Identify the serialization key for your previous attachment
Find the serialization key you specified in the original AttachmentRegistration. If you did not specify a key, it defaults to the fully qualified name of the attachment class. In our case, that's my.packagename.RocketShipAttachment.
Rename your old attachment class, and then create the new one
You will need to keep your old attachment class, but you can rename it. We'll rename it to RocketShipAttachmentV1.
package my.packagename
class RocketShipAttachmentV1(var fuel: String)
class RocketShipAttachment(var fuel: Double)
package my.packagename;
public final class RocketShipAttachmentV1 {
private String fuel;
public RocketShipAttachmentV1(String fuel) {
this.fuel = fuel;
}
public void setFuel(String fuel) {
this.fuel = fuel;
}
public String getFuel() {
return fuel;
}
}
public final class RocketShipAttachment {
private double fuel;
public RocketShipAttachment(double fuel) {
this.fuel = fuel;
}
public void setFuel(double fuel) {
this.fuel = fuel;
}
public double getFuel() {
return fuel;
}
}
Update your attachment registrations
vsApi.registerAttachment(RocketShipAttachmentV1::class.java) {
// Explicitly specify the serialization key,
// since we renamed the class
key = "my.packagename.RocketShipAttachment"
useUpdater(RocketShipAttachment::class.java) { v1 ->
// Convert the v1 attachment into the new version
RocketShipAttachment(v1.fuel.toDouble())
}
}
vsApi.registerAttachment(RocketShipAttachment::class.java) {
// We need a new, unique serialization key,
// so we'll append :2 to the end of the original key
key = "my.packagename.RocketShipAttachment:2"
}
AttachmentRegistration r1 = ValkyrienSkies.api()
.newAttachmentRegistrationBuilder(RocketShipAttachmentV1.class)
// Explicitly specify the serialization key,
// since we renamed the class
.key("my.packagename.RocketShipAttachment")
.useUpdater(
RocketShipAttachment.class,
// Convert the v1 attachment into the new version
v1 -> new RocketShipAttachment(Double.parseDouble(v1.getFuel()))
)
.build();
ValkyrienSkies.api().registerAttachment(r1);
AttachmentRegistration r2 = ValkyrienSkies.api()
.newAttachmentRegistrationBuilder(RocketShipAttachment.class)
// We need a new, unique serialization key,
// so we'll append :2 to the end of the original key
.key("my.packagename.RocketShipAttachment:2")
.build();
ValkyrienSkies.api().registerAttachment(r2);
Last modified: 03 June 2026