• Labor of Love is here! Visit our Labor of Love thread for a special message from the team, a look at brand new Labor of Love merch, and the changelog (minus a few surprises 😉)

tModLoader Modding Tutorial: World Generation

Did this thread help you?

  • Yes it did!

    Votes: 54 93.1%
  • No, it didn't.

    Votes: 4 6.9%

  • Total voters
    58
  • Poll closed .

eutyjdghfja5

Terrarian
with the jungle one, you have to duplicate it for all jungle related steps. ie jungle temple, otherwise it gets stuck on those
 
Hello,

I am currently trying to understand structure generation, and I have found that the ExampleWell is perfect for what I am looking for. I managed to adapt it in order to spawn premade nests wherever Clouds are in order to spawn them on floating island.
However, I've been having trouble generating a multitile piece of furniture in the middle of every nest. I've been trying to generate kegs as a placeholder, as what i'm planning replace it with is a 2x2 modded tile.

Using Tiletype.Kegs leads to unconsistent, parts of kegs to spawn in place, while WorldGen.PlaceObject and WorldGen.Place2x2 will also either not spawn anything, or spawn half of it but at the wrong place.

I've been toying with it for several days, working on other things while the worlds generate, but I've not managed to find the answer as of yet...

As I've been coming here often to check for worldgen stuff, I thought that maybe I could directly ask, and hope for an answer.

Attached is the troubling code.
 

Attachments

  • ForgottenBiomesWorldTest.cs
    5.5 KB · Views: 80

Talus

The Destroyer
how to place a table:
WorldGen.PlaceTile(Main.spawnTileX - 3, Main.spawnTileY -13, TileID.Tables);
and random coordinates
 
how to place a table:
WorldGen.PlaceTile(Main.spawnTileX - 3, Main.spawnTileY -13, TileID.Tables);
and random coordinates
Thank you for your input, but as I've said, i know how to place a tile, but what I am looking for is how to specify, using a {0,0,0,0,0[...]} table by preference, where the tile is created.

I did managed to spawn full Kegs by putting the PlaceObject/PlaceTile outside of the cases,but it results in the kegs being spreadacross the surface and not just a single one.
 

Attachments

  • Kegsnest.png
    Kegsnest.png
    12.3 KB · Views: 82
Hello,

I am currently trying to understand structure generation, and I have found that the ExampleWell is perfect for what I am looking for. I managed to adapt it in order to spawn premade nests wherever Clouds are in order to spawn them on floating island.
However, I've been having trouble generating a multitile piece of furniture in the middle of every nest. I've been trying to generate kegs as a placeholder, as what i'm planning replace it with is a 2x2 modded tile...
While I understand why ExampleWell works well (haha) for you, I do not think it is a good implementation for world generation. The best way that I've found to do structures is to either make a way to save and load structures yourself, or use someone else's way of doing that. Personally, I've used Scalie's Structurizer for this, and it works with multitiles, chests (I think), tile entities, tiles, etc., and makes it very easy to do this on world generation. All you need to do is make a structure, save it with the Structure Wand, place the resulting structure file in your mod, then use StructureHelper.GenerateStructure to do the rest.
Elaborating a bit, the ExampleWell multidimensional array format is a super slow, manual way to do structures, which isn't even very flexible when put to the test. It's hard to update, slow to implement, slower to test, super difficult to read, and most of all, really, really large in your .cs files, something which I personally dislike.
As an aside, WorldGen.PlaceObject is also inconsistent (for some reason) - I'd recommend using your own custom PlaceObject, as not only would it be more consistent, but it'd also be more controllable, which is nice.
 
While I understand why ExampleWell works well (haha) for you, I do not think it is a good implementation for world generation. The best way that I've found to do structures is to either make a way to save and load structures yourself, or use someone else's way of doing that. Personally, I've used Scalie's Structurizer for this, and it works with multitiles, chests (I think), tile entities, tiles, etc., and makes it very easy to do this on world generation. All you need to do is make a structure, save it with the Structure Wand, place the resulting structure file in your mod, then use StructureHelper.GenerateStructure to do the rest.
Elaborating a bit, the ExampleWell multidimensional array format is a super slow, manual way to do structures, which isn't even very flexible when put to the test. It's hard to update, slow to implement, slower to test, super difficult to read, and most of all, really, really large in your .cs files, something which I personally dislike.
As an aside, WorldGen.PlaceObject is also inconsistent (for some reason) - I'd recommend using your own custom PlaceObject, as not only would it be more consistent, but it'd also be more controllable, which is nice.
Thank you so much for your reply. I had tried to use StructureHelper before but it was quite complicated and I couldn't figure much, and then ExampleWell came so close to what I was looking for that I trashed the idea completely. But you're right, ExampleWell might DROWN me in code that could be just as easily be contained within StructureHelper.

I am now trying to get StructureHelper to work, but that is by itself is a lot of work ^^' . The instructions on the mod's page are a bit... "shallow" ? (English isn't my first language so It may not be the right word and I don't want to be rude). Adding dependency is "easy", but when it comes to calling StructureHelper.GenerateStructure() I have many issues, like having to call StructureHelper.StructureHelper.GenerateStructure (maybe some dependancy issues i may have to look into) for tmodloader to recognize the line, or the "mod" param that i have no idea what to put there. If there were a few examples... but i'd rather not bother you with it ^^' I will try to toy with it for a while, and as a last resort I may contact the mod's author (I don't want to be a bother, and I bet a lot of people have already bothered them with it ^^')

Again thank you for steering me toward this direction ~
 
Last edited:
Again, I want to thank you, I did manage to find a way to use StructureHelper ! It is far easier now ^^', with the added bonus of being able to randomize the structure !

FinalNest.png


Now all I need to do is find out how to actually spawn those Nests randomly in the sky (WorldSurface*0.35f, MaxWorldY...) as my code is only made to detect cloud blocks and place the structure there. I tried to remove the block checking and look for !tile.active, but I may not be doing the right thing as I'm always getting outofIndex errors ^^'. Guess I'll have to try to loop the generation through randomized locations instead of looking for airblocks... or something.

Worldgen is very hard to learn (especially for a begineer, but i'm getting somewhat better, thanks to your tutorials ~).
 
Again, I want to thank you, I did manage to find a way to use StructureHelper ! It is far easier now ^^', with the added bonus of being able to randomize the structure...
No problem!
If you're still stuck on placing it properly in the sky, try using a nested for loop to check a rectangle to make sure no other tiles are there, and spawn your structure if it's open.
If you have further questions feel free to ask 👍
cool, this mod looks awesome
I'm afraid this isn't a mod at all, lol. This is a tutorial for mod world generation.
 

erikobryant

Terrarian
Hey, I'm trying to get a custom biome to generate randomly in my world after a boss has been defeated, I'm totally lost here, thanks in advance.
 
Hey, I'm trying to get a custom biome to generate randomly in my world after a boss has been defeated, I'm totally lost here, thanks in advance.
This depends on your organization, but this is how I'd go about this -

In your boss's NPCLoot() method, call another method that contains your generation code. So, if I wanted to make a biome called the Anti-Guide biome on killing my custom enemy, I'd call MyModWorld.AntiGuideGen(); in order to make it easy to read that I'm spawning the Anti-Guide biome when the NPC is killed without making the NPC's code too lengthy with worldgen code.
In short - just call your world generation in your npc's NPCLoot() method.
Note that you should not use a GenPass as those are only to be used during world generation, not during play.
 

erikobryant

Terrarian
Hey, thanks for the reply! I used your advice and it built and reloaded without error, but when I killed the NPC during testing tModLoader crashed, so I altered the code a bit, but the same thing happened. Here's my code:

using Luminesque;
using System.IO;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.World.Generation;
using Microsoft.Xna.Framework;
using Terraria.GameContent.Generation;
using System.Linq;
using System;


namespace TutorialMOD.NPCs
{
public class NpcDrops : GlobalNPC
{
public override void NPCLoot(NPC npc)
{


if (npc.type == NPCID.EyeofCthulhu) //this is where you choose what vanilla npc you want , for a modded npc add this instead if (npc.type == mod.NPCType("ModdedNpcName"))
{
{


{

for (int i = 0; i < Main.maxTilesX / 900; i++) //900 is how many biomes. the bigger is the number = less biomes
{
int X = WorldGen.genRand.Next(1, Main.maxTilesX - 300);
int Y = WorldGen.genRand.Next((int)WorldGen.rockLayer - 100, Main.maxTilesY - 200);
int TileType = mod.TileType("LumTile"); //this is the tile u want to use for the biome , if u want to use a vanilla tile then its int TileType = 56; 56 is obsidian block

WorldGen.TileRunner(X, Y, 350, WorldGen.genRand.Next(100, 200), TileType, false, 0f, 0f, true, true);
//350 is how big is the biome 100, 200 this changes how random it looks.
//add this under public override void ModifyWorldGenTasks(List<GenPass> tasks, ref float totalWeight)
for (int k = 0; k < 750; k++) //750 is the ore spawn rate. the bigger is the number = more ore spawns
{
int Xo = X + Main.rand.Next(-240, 240);
int Yo = Y + Main.rand.Next(-240, 240);
if (Main.tile[Xo, Yo].type == mod.TileType("LumTile")) //this is the tile where the ore will spawn
{

{
WorldGen.TileRunner(Xo, Yo, (double)WorldGen.genRand.Next(5, 10), WorldGen.genRand.Next(5, 10), mod.TileType("SphyntTile"), false, 0f, 0f, false, true); // 5, 10 is how big is the ore veins. mod.TileType("CustomOreTile") is the custom ore tile, if u want a vanila ore just do this: TileID.Cobalt, for cobalt spawn
}
}
}
}

};

}
}
}
}
}
 

Attachments

  • client.txt
    1.7 KB · Views: 38
Top Bottom