I know I'm almost there, but I'm just not grasping something in the way custom registries work. I'm following the steps outlined in the gemwire wiki:
I have a collection of classes that implement "GeneType" that can be instantiated multiple times as instances that extend the class "Gene". I've created the DeferredRegister of GeneTypes, I need the datapack directory of gene configurations read in and an entry placed in the Gene registry for each file in the directory. The end goal is to create my own GeneType and Genes and allow other modders to create GeneTypes and datapack designers to create their own Genes.
I'm stuck on #3 in the wiki instructions. I've looked at the Forge BiomeModifiers registry, and the RecipeManger (both similar in concept to what I'm trying to do) but they don't implement exactly what I need.
Here's what I have so far, Registry definitions:
public static final DeferredRegister<GeneType> GENE_TYPES = DeferredRegister.create(GeneticsRebirthAPI.GENE_TYPE_REGISTRY_NAME, GeneticsRebirth.MODID);
public static final Supplier<IForgeRegistry<GeneType>> GENE_TYPE_REGISTRY = GENE_TYPES.makeRegistry(RegistryBuilder::new);
public static final RegistryObject<GeneType> DROP = GENE_TYPES.register("drop", DropGeneType::new);
public static final DeferredRegister<Gene> GENES = DeferredRegister.create(GeneticsRebirthAPI.GENE_REGISTRY_NAME, GeneticsRebirth.MODID);
public static final Supplier<IForgeRegistry<Gene>> GENE_REGISTRY = GENES.makeRegistry(() -> new RegistryBuilder<Gene>().disableSaving().dataPackRegistry(/*something needs to go here*/));
First GeneType:
public class DropGeneType implements GeneType {
public static final Codec<DropGene> CODEC = RecordCodecBuilder.create((in) -> in.group(
BlockState.CODEC.fieldOf("source").forGetter(DropGene::source)
).apply(in, DropGene::new));
@Override
public List<GeneEvents> needsEvents() {
return List.of(GeneEvents.LOOT_DROP);
}
@Override
public Codec<? extends Gene> codec() {
return CODEC;
}
public record DropGeneLevel() implements GeneLevel {
}
public record DropGene(BlockState source) implements Gene {
@Override
public Supplier<GeneType> type() {
return GeneRegistry.DROP;
}
}
}
Can someone guide me on coding steps 3 and 4? Specifically:
How do I have the GeneType registry implement Codec?
What codec do I pass to dataPackRegistry()
Since DataPacks can be reloaded do I need to do anything special? or does the forge registry system handle all the reloading?
I found two examples of using dispatch().. and they are vastly different, and I'm not sure when I need the "Lazy protections" and when I don't.
public static final Codec<ParticleOptions> CODEC = Registry.PARTICLE_TYPE.byNameCodec().dispatch("type", ParticleOptions::getType, ParticleType::codec);
Codec<BiomeModifier> DIRECT_CODEC = ExtraCodecs.lazyInitializedCodec(() -> ForgeRegistries.BIOME_MODIFIER_SERIALIZERS.get().getCodec())
.dispatch(BiomeModifier::codec, Function.identity());
Thanks for your help.
-pete