Custom GeneratorType for Custom World Types
CheaterCodes opened this issue ยท 10 comments
Issue for pre 1.16: #297
Introduction
It's not uncommon for mods to provide their own world type, e.g. for skyblock.
Unfortunately, this isn't trivial for a mod to add and I'd propose to make a module for this in the API.
Some of the things that need to be done:
- Allow creation of a GeneratorType object.
- Simplify the process of providing ChunkGenerators for each dimension
- Fix the parsing of server.properties for the GeneratorOptions
So far I have a rough idea what this would look like, but this definitely requires some thought and some input from experienced contributors.
GeneratorType
GeneratorType is a client-only abstract class with private constructor.
It is required in order to provide the MinecraftClient with a selection on the world creation screen.
While there is no proper registry, there exists a protected (mutable) List<GeneratorType> VALUES
that allows aading new ones.
On the client, this class also provides the GeneratorOptions.
In order to make this class accessible to mods, I would suggest using an accesswidener to make the class extensible,
Then, Fabric could provide a FabricGeneratorType extends GeneratorType
which should be either extensible or use a builder pattern.
This then allows mods to provide their own ChunkGenerators/DimensionOptions for each dimension.
GeneratorOptions
GeneratorOptions is the class that actually holds all information needed to generate the world.
On the client, it's created using GeneratorType.method_29079(...)
,
on the server it is parsed from the properties file using GeneratorOptions.fromProperties(...)
This class is fairly accessible and doesn't need to be extended, however the parsing on the server side is not only hardcoded,
but also happens before ModInitializers are called.
Therefore a custom GeneratorType wouldn't have been registered yet and couldn't possibly be parsed.
This could be fixed by accessing the serverPropertiesLoader
local in the server main after the ModInitializers have been called
and then simply reparsing the world type.
Additional Nice-To-Haves
As already mentioned in #297, there are some nice-to-have features that may be out of scope.
- Cycling through different world types is a pain. Would be nice to have an easier method to select the desired type than just clicking a button repeatedly
- Changing the default world type. It's a simple mixin into the MoreOptionsDialogand possibly more relevant to packs than mods and therefore possibly better suited to a separate mod.
triviality is subjective, for example : https://github.com/Linguardium/WorldTypeFixer this allows mods to add world types already and it is a trivial change. Simplex and Ecotones does something similar as well.
That aside, it would be good to have a common mechanism for doing so.
additionally, i believe simple void world supplies a custom type in the json for the dimension
Correct me if I'm wrong, but registerLevelType
must be called from a static initializer, since the ModInitializer is too late, correct?
I'll do a quick test, but if so, this can be worked around via a onPreLaunch and custom entrypoints, correct?
Something like that. It'S not hard, no. It's definitely easier than in 1.15. Misread what you said
But there still needs to be some care given to e.g. allowing a worldtype config screen.
DO NOT TOUCH REGISTRIES IN PRE LAUNCH
I am about sure if you don't do preLaunch right you'll cause something to break loading.
I think the correct solution is to just reparse the GeneratorOptions after ModInitializers have been called.
Long term, this makes sense.
Loading a custom leveltype entrypoint from a mixin in fromProperties head works for a 3rd party lib.
One off/singular generator type mods can mixin to fromProperties to check their own type.
With fapi taking the charge, it makes more sense to allow GeneratorOptions to be modified by mods before world creation/generation
Just had a look at fabric-biomes-v1 and it seesm that one might conflict with custom GeneratorOptions?
At HEAD of startupServer it recreates the Nether chunk generator using the default DimensionType.createNetherGenerator
,
so a custom ChunkGenerator for te Nether provided by a custom GeneratorType/GeneratorOptions would be overwritten.