tModLoader / tModLoader

A mod to make and play Terraria mods. Supports Terraria 1.4 (and earlier) installations
https://www.tmodloader.net/
MIT License
4.09k stars 1.86k forks source link

Generation Passes modernization #2260

Open Mirsario opened 2 years ago

Mirsario commented 2 years ago

Similarly to #2139, this is a proposal for modernization of everything related to generation layers.

Current Design

First, have a look at the common usage of the current (1.3) TML's generation pass designs:

public class WorldGenSystem : ModSystem
{
    // ...

    public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
    {
        int index = tasks.FindLastIndex(x => x.Name == "Settle Liquids Again");

        if (index != -1) {
            tasks.Insert(index + 1, new PassLegacy("ModularTools:Sulfur", (progress, configuration) => {
                progress.Message = "Crystallizing sulfur";

                foreach (Point poolLocation in Hooking.PoolLocations) {
                    if (poolLocation.Y > WorldGen.lavaLine) {
                        WorldUtils.Gen(poolLocation, new Shapes.Circle(10), new GenerateSulfurAction());
                    }
                }
            }));
        }
    }
}

(Taken from Itorius' ModularTools)

Why do anything?

These are the 'problems' that the following design will attempt to solve:

Proposal

Everything past this point may be incomplete and poorly written, somewhat of a sketch.

The suggested solution for the first problem is nothing unexpected by now - like with interface layers, we somewhat copy the design of player layers from #1047.

The latter two problems are solvable by making generations be instanced, and perhaps having generation types use the type system.

Here's a short, non-final summary of suggested changes:

Generation Passes:

Generation Types:

New usage sketch

Each genpass will be able to go into its own file, and enable themselves for initializing world generations. Types deriving from WorldGeneration will be able to modify their own default lists of enabled generation passes. Hooks (supposedly in ModSystems) will allow people will be the last to modify already defined visibility of genpasses on world generations.

public sealed class SulfurOreGenerationPass : GenPass
{
    public override Position GetDefaultPosition()
        => new AfterParent(GenerationPasses.SettleLiquidsAgain);

    public override bool GetDefaultVisibility(WorldGeneration generation)
        => generation == WorldGeneration.Default;

    protected override void ApplyPass(GenerationProgress progress, GameConfiguration configuration)
    {
        progress.Message = "Crystallizing sulfur";

        foreach (Point poolLocation in Hooking.PoolLocations) {
            if (poolLocation.Y > WorldGen.lavaLine) {
                WorldUtils.Gen(poolLocation, new Shapes.Circle(10), new GenerateSulfurAction());
            }
        }
    }
}
Tyfyter commented 1 year ago

If this is added I believe it would benefit greatly from passes being able to be positioned relative to single other passes which they don't rely on

Chicken-Bones commented 1 year ago

Previous discussion summary (scroll up for context): https://discord.com/channels/103110554649894912/445276626352209920/1011402588371038251