Dinkum

Creating a new world generator is just like creating any other Dinkum mod, except you are interacting with my mod instead of Dinkum. (You can still interact with Dinkum, of course, but you should ABSOLUTELY NOT be messing with the actual world data in the live Dinkum game, because your world generator must work in preview mode as well as live mode, and if you do it right, it will work in both modes with the exact same code. It is perfectly fine to use Dinkum data if you are only reading it, however, such as reading biome spawn tables, loot tables, tile type data, and tile object settings data. Just don't change anything.)

Create your mod project in whatever IDE you prefer, and add a project reference to "gmishaolem.CustomWorldGenerator.dll" "Snaitf.Dinkum.SeedyMcSeedFace1" just like you do for the Dinkum DLLs. You will be inheriting from the base class "CustomWorld", and this will be your world generator.

public class YourWorldGenerator : gmishaolem . CustomWorldGenerator . CustomWorld
Give your generator a name that the user will type into the generator box when creating a new world. It doesn't have to be crazy-long, but it should be something unique, because no two generators may share a name.

public override string GetGeneratorName ( ) { ... }
To make your generator available to use, call the "AddGenerator" method. You must do this during your mod's Awake() or Start() methods. (If the type you provide is not a CustomWorld, or the name you provide is already taken, the method will return 'false'.)

bool Success = gmishaolem . CustomWorldGenerator . Plugin . AddGenerator ( "yourworldgenerator" , typeof ( YourWorldGenerator ) ) ;
From this point, your generator will be available for use, and both preview mode and live mode will work automatically. The only thing remaining to do is provide the code that actually generates the world. (Once again and very importantly, your generator must NOT alter any normal live world data, such as WorldManager.onTileMap. You may read any data from anywhere that you need to, but you should only ever be messing with the data structures inside your CustomWorld instance.).

public override void GenerateNewMapContents ( ) { ... }
The "Seed" field will contain the world's random seed, but you generally don't need to use it: Use the MapRng instance instead, which is created for you. (Remember the general principle of pRNG and world generation from random seed: Don't create or use any other random generators, such as UnityEngine.Random or System.Random, unless you know what you are doing.)

public int Seed ;
public MapRand MapRng ;

Your CustomWorld instance will have internal versions of the important world-structure data, and no matter what, you need to be using these versions, not directly changing values in WorldManager or anywhere else.

public int [ , ] TileTypeMap , TileTypeStatusMap , TileObjectMap , TileObjectStatusMap , HeightMap ;
public Biome [ , ] BiomeMap ;
public bool [ , ] WaterMap ;

The biome map is how you specify which biome each tile is. Your CustomWorld instance will automatically respond to calls from the base game to check the biome type, and will automatically adjust for "shallow" billabong and ocean water when doing so. Remember that the tile type and water maps also matter: For example, mangroves require mud, rivers require soft rocky dirt and must not be billabong or ocean, and so forth. "BeachShore" is the part of the beach where shells are allowed to spawn each morning. Consult the base game's world-gen and daily-respawn code for more details.

public enum Biome
{
Beach , Tropical , Billabong , Bushland , Desert , ColdForest , Plains , Cold , WarmOcean , ColdOcean ,
NaturalQuarry , WaryMuNest , BushDevilDen , DiggoDen , BeachShore , TropicalIsland
}

Your instance will contain a large number of useful contents to help you.

  • MapSize -- the width/height of the map
  • MinCoord/MaxCoord -- the minimum and maximum possible map coordinates
  • MinSafeCoord/MaxSafeCoord -- the minimum and maximum safe map coordinates for you to alter
  • MinHeight/MaxHeight -- the minimum and maximum allowed height map values
  • MinLandHeight -- the lowest height that land should ever be
  • MaxWaterHeight -- the highest height that water should ever be
  • WorldBorderHeight -- the height at the world border, which you should match so things don't look weird
  • RiverBedHeight -- the height at the bottom of rivers in vanilla
  • MaxMapDeepWaterHeight -- the highest height that the in-game map will draw water as "deep water"
  • MaxOceanDeepWaterHeight -- the highest height that ocean will be considered deep rather than "shallow"
  • MaxBillabongDeepWaterHeight -- the highest height that billabong will be considered deep instead of "bank"
  • AbsoluteCenter -- the float value representing the literal center of the map
  • MapSizeScalingFactor = 1f / MapSize -- multiply any map coordinate by this to scale it to 0<=coord<=1 relative to the full map's size
  • CommonGrassTileTypeId/MowedCommonGrassTileTypeId/ColdGrassTileTypeId/MowedColdGrassTileTypeId/TropicalGrassTileTypeId/MowedTropicalGrassTileTypeId -- grass tile types
  • DirtTileTypeId/HardRockyDirtTileTypeId/SoftRockyDirtTileTypeId/SandTileTypeId/RedSandTileTypeId/MudTileTypeId -- ground tile types (hard rocky dirt for quarries, soft rocky dirt for water)

Your instance will contain helper functions for placing the dock and broken tele-towers.

  • public bool CheckIfDockCanBePlaced ( int CoordX , int CoordY )
  • public void PlaceDock ( int CoordX , int CoordY )
  • public bool CheckIfTowerCanBePlaced ( int CoordX , int CoordY )
  • public void PlaceNorthTower ( int CoordX , int CoordY )
  • public void PlaceEastTower ( int CoordX , int CoordY )
  • public void PlaceSouthTower ( int CoordX , int CoordY )
  • public void PlaceWestTower ( int CoordX , int CoordY )

Your instance will contain helper functions for placing single- and multi-tile objects. Many of these work similarly to the vanilla world-gen functions by the same names. Note that you should not place towers or the dock using these methods: Use the dedicated tower and dock methods.

  • public bool CheckIfTileObjectCanBePlaced ( int CoordX , int CoordY )
  • public bool CheckIfMultiTileObjectCanBePlaced ( int TileObjectId , int CoordX , int CoordY , int Rotation , bool RequireFlatGround )
  • public void PlaceMultiTileObject ( int TileObjectId , int CoordX , int CoordY , int Rotation , bool FlattenUnderneath )
  • public void QueueMultiTiledObject ( int TileObjectId , int CoordX , int CoordY , int Rotation )
  • public void PlaceQueuedMultiTileObjects ( )
  • public void PlaceBuriedTreasure ( int CoordX , int CoordY , float PercentChance )
  • public void PlaceWorldObject ( int TileObjectId , int CoordX , int CoordY )
  • public void PlaceWorldObject ( int CoordX , int CoordY , BiomSpawnTable SpawnTable )

Your instance will contain helper functions for arranging things in the world. If you decide to use any vanilla types or methods while generating your world, make absolutely certain that they are read-only or completely local to your code, so that you are not inadvertently changing the live world instead of your CustomWorld's internal values.

  • public float DistanceFromHorizontalLine ( int TileX , int TileY , float LinePosition )
  • public float DistanceFromVerticalLine ( int TileX , int TileY , float LinePosition )
  • public float DistanceFromPoint ( int TileX , int TileY , Vector2 Point )
  • public float DistanceFromAbsoluteCenter ( int TileX , int TileY )

Be certain to inform your users that it is not safe to remove your custom-generator mod, because they will no longer be able to correctly load any worlds made with it.

Article information

Added on

Edited on

Written by

Snaitf

0 comments