Smooth Terrain Generator

Kayaker Magic, May 2017


This is a script in a prim that you can use to generate smooth terrain in your regions. Instant terrain to order in large or small var regions. Check out this video for a flyover of an 8x8 var filled with terrain made by this script in less than a minute.

You specify a few control points and smooth terrain is made to connect your dots. Control points in an NC will force hills, plains, lakes and islands. Or the script can generate "random" terrain in adjacent regions that match perfectly at the borders. After the basic shape is determined by control points and randomness, you can specify other parameters to scale the land up by a factor, offset the terrain up or down, rotate or flip it. These parameters can be set by typing them in chat near the prim or adding them to the .params NC in the prim. The terrain is generated by a script, not by reading a RAW file, not by receiving the terrain via email or a server. But the result is real terrain data that can be saved in a RAW file. These RAW files are your creations that you can give away or sell if you wish. Terrain generated this way loads blindingly fast compared to a RAW file, taking seconds to fill a standard 256x256 region, under a minute for an 8x8 var. This is also much more reliable than uploading a RAW file.

Buy it on the Kitely Market here

This scripted object works on OpenSim 0.9 or 0.8, but it REQUIRES Owner permissions, Estate Manager and Threat Level HIGH. How do you know if you can use my terrain tools? Get a copy of the Terrain Test Prim first:

Terrain Test Prim

Test for these issues with the Terrain Test Prim which is available free in my Kitely world Fractalis. You can hypergrid there with this address: grid.kitely.com:8002:Fractalis . The full perm script from the test prim is available here. Or you can buy the Test Prim ready to go from the Kitely Market here for a small price.

The Terrain Test script also checks for a common OpenSim bug: On OpenSim regions hosted on Microsoft servers, some innocuous script calls take up to 10,000 times longer to run! The result of this is that it takes hours to generate terrain on a large var on a Microsoft Server, when it takes under a minute on a Linux server. The Test Terrain prim will stay yellow to warn you about this if you are running on a Microsoft Server.

Smooth Terrain Step-By-Step Tutorial:

The script that generates terrain has a bewildering array of options that will take you a while to learn. The tutorial below has step-by-step exercizes you can follow along with to learn progressively more complex tricks.
  • Terrain Test Prim, will this work for you?
  • Follow Along, Default Island
  • Options for Modifying Terrain
  • Terrain Cubic Control Points
  • Matching Terrain Across Borders
  • Parameters in Chat or Note-card
  • Special Control Point: 'ran'
  • Random Terrain Seeds
  • Random Terrain Crossing Borders
  • Identical Terrain in Another Region
  • Terrain in Part of a Region
  • Planning Terrain in Large Var Regions
  • Reference List of Parameters

    Follow Along

    You can follow along and do all the examples in this tutorial if you have a region where you don't mind changing the terrain. The easiest thing to do is to rez the Smooth Terrain prim in a 256x256 region and click on it (twice if it is still warning you with red floating text). It will fill your region with the default smooth island.

    This new terrain will overwrite the previous terrain, so I hope you did this in an empty region or one where you were not fond of the previous lay of the land. You may want to move the Smooth Terrain prim above the ground in case the new terrain rises up around it. Or wear the prim on you hand like a magic wand.

    Options for Modifying Terrain

    This terrain has a specific shape, but it can be modified to a great extent with several other commands in chat. You can make the terrain steeper by multiplying it by a factor:
    factor=2		//make all the terrain twice as tall
    gen
    


    You can also raise and lower the terrain fromthe bottom without stretching the tops:
    factor=1.0		//lets put the factor back to the default
    offset=20		//push the terrain up 20 meters
    gen
    


    The terrain can also be flipped north/south with ‘flipy=on’, (flips north/south), ‘flipx=on’ (flips east/west) and ‘rotate=90’ which can rotate the terrain in 90 degree increments.
    offset=0		//lets put the offset back to the default
    rotate=90		//rotates the land 90 degrees clockwise
    gen
    


    Terrain Cubic Control Points

    The default smooth terrain is an island with water around it, a 60 meter peak in the NW, a 40 meter peak in the SE. These high and low points are there because they are in a table in the default .params NC. You can edit this NC and enter a new table with a different starting shape. Try changing one of the peaks in the NC to a different value, save the NC and type 'gen' to generate new terrain. Let’s look at the default table first and see why it produces the island we have seen so far:
    sampx=7
    sampy=7
    samp = -20, -20, -20, -20, -20, -20, -20,
    samp = -20, 00, 00, 00, 00, 00, -20,
    samp = -20, 00, 60, 30, 20, 00, -20,
    samp = -20, 00, 30, 25, 25, 00, -20,
    samp = -20, 00, 20, 25, 40, 00, -20,
    samp = -20, 00, 00, 00, 00, 00, -20,
    samp = -20, -20, -20, -20, -20, -20, -20,
    The table has 3 important areas shown as different colors in the above picture:

    The area highlighted green in the middle of this table are the control points inside your terrain. You can see the 60 meter peak in the NW and the 40 meter peak in the SE. Note these values are all floating point, but I am entering all numbers as two digits to make the NC more readable.

    The area highlighted yellow are the control points around the edge of your terrain. The terrain edges end with these values. To force this to be an island in this case, I set all the edge values to zero. The water level is normally at 20 meters, so a value of 0 is 20 meters below water and the peak at 60 is only 40 meters above the water.

    The area highlightd in red are control points that determine where the terrain is sloping as it leaves the edge. These could be control points copied from regions next door to make region terrain meet seemlessly. I'll give an example of that next. In this case, the value of -20 makes the terrain slope as if it would continue going deeper if it extended off the edge. Above you have already seen the island that this set of control points produces.

    Matching Terrain Across Region Boundaries

    One way to make terrain match across region boundaries is to make sure that the edge and slope values match in the control points of both regions. The red slope zone of each side must match the first row of green interior values of the other. Here is a simple case where that has been done, and below that a picture of the terrain produced:
    sampx=7
    sampy=7
    samp = -20, 00, 20, 30, 20, 00, -20,
    samp = -20, 00, 20, 30, 20, 00, -20,
    samp = -20, 00, 20, 30, 20, 00, -20,
    samp = -20, 00, 20, 30, 25, 00, -20,
    samp = -20, 00, 15, 25, 40, 00, -20,
    samp = -20, 00, 00, 00, 00, 00, -20,
    samp = -20, -20, -20, -20, -20, -20, -20,


    You could make a copy of the table above, turn it upside down, overlap it with the original with the yellow values lined up. You would see that I made it to match up with itself like that. The red area of one of them has identical values with the green and other edge points. You could make a new .params file with the lines swapped around like that, or you could just put this terrain in the region north of the last one and rotate it 180 degrees:

    If you look closely at the border between the two regions, the terrain matches perfectly. Even the terrain texture has the same patterns in it, and there is only a shadow where they meet. This shadow is a feature of the viewer, there is nothing I can do about this!

    If your terrain is more complex, you may have to create a different .params file for each region. As much work as that may be, it is a LOT easier than making all this terrain by hand! However, the next example will show an even easier way of making seamless terrain:

    Random Terrain

    The special value 'ran' in the sample point of the NC means the script supplies a random number at that point. You can specify the range of the random numbers with two parameters 'ranmin' and 'ranmax'. Below is a simple .params file that sets all the values to 'ran' and lets the program generate all the terrain for you.
    hashtype=global//this will be described below
    ranmax=0
    ranmax=40
    sampx=6
    sampy=6
    samp = ran, ran, ran, ran, ran, ran,
    samp = ran, ran, ran, ran, ran, ran,
    samp = ran, ran, ran, ran, ran, ran,
    samp = ran, ran, ran, ran, ran, ran,
    samp = ran, ran, ran, ran, ran, ran,
    samp = ran, ran, ran, ran, ran, ran,
    This table has the same areas for the interior, edge and slope off the edge but they are all set to ran. These are not really random, they have some special features you will see in a minute. Here is the terrain that resulted:

    That has too much water for me, so I am going to type two commands in chat to randomize it and try again:
    ran		//ran is also the chat command to make up a new random seed
    gen		//gen generates all new terrain after you make any changes.
    


    You can just keep doing this, changing the random seed and generating new terrain until you find one that you like!

    Random Terrain Seeds

    These random terrains are not lost forever when you clobber them with new ones. You can ‘recover’ a lost terrain by remembering the random seed it was generated from. This is displayed in chat whenever you start generating terrain, so if you can scroll back and find this seed number, you can reproduce that terrain again. To exactly reproduce it, you must also return the offset and factor to the previous values.

    Matching Random Terrain Across Borders

    Notice that the terrain in the last picture ends with high values off the edge in several directions. If I bring the Smooth Terrain prim into the next region to the east and type 'gen' with it there, it generates new random terrain that exactly matches the random terrain in the region next door! These are special random numbers that always get the same value in the same place in your grid. Here are pictures looking back at the first region before and after I generated new terrain next to it:



    I'll move on to the next region to the north and do that again, looking back at the region to the south before and after putting in new random terrain:



    Finally, I'll put in the missing region in the northwest. Even on the corner where 4 regions come together the terrain matches seamlessly!



    Finally here is an arial view of what those 4 regions look like from above:

    There are a few conditions that have to be met to set this up: The 'hashtype=global' parameter must be set as I did in the sample NC above. You cannot use this trick and the flip or rotate options at the same time. (The matching edges will be rotated or flipped out of alignment). You must have the same offset and multiplicative factor in all the regions. But once you are set up like this you can march through a whole grid wearing the Smooth Terrain prim on your hand like a magic wand, bestowing matching terrain on every region! Note: You must keep the prim in a region until it says it is done. If you leave early it will stop, warn you not to do that again, and leave a mess behind. You can fix the mess by returning to the half finished region, clicking on the prim to start over and waiting for it to finish this time!

    If you have a more complex set of control points, it is up to you to make the values at the edges match. To do this, you may have to create a new .params file for every region and carefully edit the edges and slope values in the tables so they match on every region edge.

    Identical Terrain in Another Region

    If you set the hashtype to "hashtype=local", adjacent regions will not match up. Instead, the terrain generated will be exactly the same in every region (assuming the sample tables, factor, random seed, etc are identical). The terrain will be identical even if you take the Smooth Terrain Generator to a different grid, but don't forget to save the seed value and bring that with you. To demonstrate this I typed into local chat
    hashtype=local
    gen
    gen		//after moving into the region to the right
    


    Parameters in Chat or Note-card

    Did you notice that I have used the 'hashtype' parameter both in a NC and in open chat? All the parameters and commands that the Smooth Terrain understands can be typed in open chat or placed in the .params NC. Even the sample control point rows can be entered in open chat, but a large table is easier to edit in the NC. You can put important values you want to remember, like the seed and hashtype commands, in the NC to remember them and set them automatically. The .params NC is read by the script every time you edit it and save it. (This is a common mistake that I make! Don't forget to save it after you made changes!)

    You can over-ride the values in the .params NC by typing new values in local chat. Whatever values were entered last are the ones the script uses. Values you entered in chat will be remembered if you carry the Smooth Terrain across a border. It will even remember those values when saved in inventory and rezzed again later.

    Terrain in Part of a Region

    In a large var region, you may only need to generate new terrain in small areas. You can do this by setting the size and offset of the area to terraform.

    Type the following commands in chat to try this out, and see the result below:
    outxw=128		//half as wide as an old small 256x256 region
    outyw=128		//and half as tall
    gen
    


    Thia region started out all water, so we only see the new terrain in the SW quadrant. Next type:
    outxo=128		//move over half way
    outyo=128		//and up half way
    gen
    


    How I have filled in the NE quadrant. To fill in the SE quadrant I type:
    outyo=0
    gen
    


    Do you see the magic in the above picture? The new terrain matches the terrain to the west and north! If you keep the seed, offset, and other parameters the same, the terrain will always match up like this inside a single region, no matter what the hashtype is set to. One last set of commands to fill in the missing quadrant:
    outxo=0
    outyo=128
    gen
    


    When you do a small area like this, the control points apply to the area you are terraforming, not the whole region any more. Since I am using the same .params file with the same sample control points from the previous examples, there are now more control points inside this one region. This makes this one region have about the same amount of detail as 4 separate regions did. You can control the amount of detail by making the sample table larger and smaller, or using it on smaller areas like this.

    All these examples generated square areas and started with square sample tables. This is not a restriction, you can fill any odd sized and located area inside the region. Although you will find that the terrain looks stretched if the outxw:outyw has a different aspect ratio from the sampx:sampy values. For example:

    seed=8641258
    hashtype=local
    outxw=256		//output width is twice as wide
    outyw=128		//as it is tall
    sampx=15		//things look best if the aspect ration of 
    sampy=9			//the sample ratio is close to outxw:outyw
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran, ran,  00, -20,
    samp=-20,  00,  00,  00,  00,  00,  00,  00,  00,  00,  00,  00,  00,  00, -20,
    samp=-20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
    


    It is becoming common to build a var region and plop a few of your old favorite 256x256 OAR files into a few of the "sub regions" in the var. But vars are so big, how are you going to fill in the rest of all that terrain? Simple! Fill in the missing areas with the Smooth Terrain like I just showed you above. Be careful while you do this! It is easy to set one of the offset values wrong and clobber the terrain in an area you wanted to keep! For example, a mistake that I have made is to type outy0=0 (note the two zeros, one of them was supposed to the letter ‘o’). One way to check for this is to watch and make sure the Smooth Terrain always echos back what it is doing. If you miss-spell a parameter name there will be no echo and you will know to try again.

    Planning Terrain in Large Var Regions

    If you built a set of control points for an old 1x1 region, then use it in larger and larger vars, the terrain gets stretched out horizontally and the hills don't look as tall (even though they are just as tall as before). I have found that as I design for larger vars I want to have larger sample tables with higher peaks in them. A larger sample table also allows you to design the general outline of an island by setting the surrounding samples below water.

    Reference List of Parameters

    gen After changing any of the parameters below, this command starts the process of generating new terrain.
    stop Stops generating terrain part way through. Usually you cannot type this fast enough to stop your terrain from being clobbered! You might use this if you realize you forgot a parameter and want to change a value and start over.
    factor=1.0 Multiplies the terrain by the number provided. 0.0 produces flat terrain at 0.0 (push it up with 'offset' described below). 1.0 is the default that produces the heights listed in the 'samp' lines described below.
    offset=0.0 Offsets the terrain up or down. Default is zero, units is meters.
    rotate=90 Rotates the terrain in increments of 90 degrees.
    flipx=off If set to 'on', flips the shape of the terrain east-west.
    flipy=off If set to 'on', flips the shape of the terrain north-south. Flipping both x and y has the same effect as rotate=180. Rotating and flipping at the same time may not work as you want.
    tension=0.5The tension sets the curvature of the cubic splines. This is subtle unless you set it greadter than 1, then it creates WILD terrain.
    hashtype=global If set to 'global' the randomness of the terrain is different in every region AND the edges of adjacent regions line up perfectly. If set to 'local', the terrain generated is identical (for a given seed) in every region.
    ran Picks a new random seed at random. Any terrain generated after this will be different than what was generated before.
    seed=123456 Sets the random seed of the terrain. Each seed value produces entirely different pseudo-random terrain. With this you can pick your own random terrain, or return to a previous 'random' terrain.
    ranmin=10 Sets the minimum value of random terrain. Water defaults to 20, so this default value is 10 meters below water level.
    ranmax=30 Sets the maxim value of random terrain. This default is 10 meters above the default water level.
    sampx=5 Sets the width of the sample point and roughness tables. After changing this value you must enter a new 'samp' table.
    sampy=5 Sets the height (number of rows) in the sample point table.
    samp=10.0,... Enters one row of the sample point table. This must have the number of values across that is set my sampx. Values are separated by commas. There must be sampy rows in the table before you can generate terrain.
    outxw=256 Sets the width (east-west extent) of the terrain generated. This defaults to the width of your region. The only reason for ever changing this is to load only a small area of your region with new terrain.
    outyw=256 Sets the height (north-south extent) of the terrain generated. This defaults to the heigth of your region.
    outxo=0 Sets the east-west offset of where terrain generation starts. This defaults to 0 (the SW corner). This parameter should only be set when outxw is less than the width of your region.
    outxo=0 Sets the north-south offset of where terrain generation starts. This defaults to 0 (the SW corner). This parameter should only be set when outyw is less than the width of your region.
    list Displays a list of saved parameter settings in open chat. (Red text indicates new experimental commands, only available in future releases).
    load=name Loads one of the saved parammeter setting NCs. Normally the parameter NC used is named .params, this command allows you to switch to a different NC in the inventory of the prim. The new parameters are loaded and the next 'gen' command will make the terrain described in that NC.
    name=message Displays all the text after the equal sign in open chat. This allows you do document what your parameter NCs are doing.
    help This command gives you a short description of what all the parameters are and what they do. It also displays the current value of each parameter

  • Terrain Home, back to the list of other terrain programs.