Types/NoiseExpression: Difference between revisions
m (→variable: word) |
Tag: Rollback |
||
Line 3: | Line 3: | ||
A fragment of a functional program used to generate coherent noise, probably for purposes related to terrain generation. | A fragment of a functional program used to generate coherent noise, probably for purposes related to terrain generation. | ||
Noise expressions can be provided as | Noise expressions can be provided as object literals or built using functions in the built-in <code>noise</code> library. | ||
<code>noise.define_noise_function</code> allows noise expressions to be defined using a shorthand | |||
that's a subset of Lua (see [[#Example definition|example definition]] for an example and its literal equivalent). | that's a subset of Lua (see [[#Example definition|example definition]] for an example and its literal equivalent). | ||
== Mandatory properties == | == Mandatory properties == | ||
Line 21: | Line 19: | ||
=== variable === | === variable === | ||
Reference to a pre-defined variable, constant, or a | Reference to a pre-defined variable, constant, or a named noise expression. | ||
Predefined variables | Predefined variables include "x", "y", and "distance". | ||
Properties: | |||
* '''variable_name''': a [[Types/string]] | |||
=== function-application === | === function-application === | ||
Line 101: | Line 36: | ||
Properties: | Properties: | ||
* '''function_name''' (a string; see | * '''function_name''' (a string; see functions, below) | ||
* '''arguments''' (a list or associative array of argument expressions) | * '''arguments''' (a list or associative array of argument expressions) | ||
=== literal-boolean === | === literal-boolean === | ||
Evaluates to the same boolean value (true or false) every time, given by the '''literal_value''' property | Evaluates to the same boolean value (true or false) every time, given by the '''literal_value''' property. | ||
=== literal-number === | === literal-number === | ||
Evaluates to the same number every time, given by the '''literal_value''' property. | Evaluates to the same number every time, given by the '''literal_value''' property. | ||
=== literal-string === | === literal-string === | ||
Line 160: | Line 82: | ||
Returns the expression represented by its '''literal-value''' property. | Returns the expression represented by its '''literal-value''' property. | ||
Useful mostly for passing expressions (to be evaluated later) to the | Useful mostly for passing expressions (to be evaluated later) to the '''spot-noise''' function. | ||
=== array-construction === | === array-construction === | ||
Line 168: | Line 90: | ||
in the resulting array. | in the resulting array. | ||
Can be used to construct map positions ([x, y]) and map position lists ([[x0,y0], [y1,y1], ...]). | |||
=== procedure-delimiter === | === procedure-delimiter === | ||
Line 226: | Line 125: | ||
=== add === | === add === | ||
'''Arguments (positional)''': | '''Arguments (positional)''': term, other term | ||
Takes | Takes 2 positional arguments and adds them. | ||
=== subtract === | === subtract === | ||
'''Arguments (positional)''': | |||
'''Arguments (positional)''': minuend, subtrahend | |||
Takes 2 positional arguments and subtracts the second from the first. | Takes 2 positional arguments and subtracts the second from the first. | ||
=== multiply === | === multiply === | ||
Takes | '''Arguments (positional)''': factor, other factor | ||
Takes 2 positional arguments and multiplies them. | |||
=== divide === | === divide === | ||
'''Arguments (positional)''': | |||
'''Arguments (positional)''': dividend, divisor | |||
Takes 2 positional arguments and divides the first by the second. | Takes 2 positional arguments and divides the first by the second. | ||
=== exponentiate === | === exponentiate === | ||
'''Arguments (positional)''': | |||
'''Arguments (positional)''': base, exponent | |||
Takes 2 positional arguments, and raises the first to the second power. | Takes 2 positional arguments, and raises the first to the second power. | ||
=== absolute-value === | === absolute-value === | ||
'''Arguments (positional)''': value to be absoluted | '''Arguments (positional)''': value to be absoluted | ||
Line 262: | Line 160: | ||
=== clamp === | === clamp === | ||
'''Arguments (positional)''': | |||
'''Arguments (positional)''': value to be clamped, lower limit, upper limit | |||
First argument is clamped between the second and third. The second is treated as a lower limit and the third the upper limit. | First argument is clamped between the second and third. The second is treated as a lower limit and the third the upper limit. | ||
=== | === ridge === | ||
'''Arguments (positional)''': value to be ridged, lower limit, upper limit | |||
'''Arguments (positional)''': | |||
Similar to clamp but the input value is folded back across the upper and lower limits | Similar to clamp but the input value is folded back across the upper and lower limits | ||
until it lies between them. | until it lies between them. | ||
=== factorio-basis-noise === | === factorio-basis-noise === | ||
Line 432: | Line 178: | ||
* '''x''' | * '''x''' | ||
* '''y''' | * '''y''' | ||
* '''seed0''' | * '''seed0''' - integer between 0 and 4294967295 (inclusive) used to populate the backing random noise | ||
* '''seed1''' | * '''seed1''' - integer between 0 and 255 (inclusive) used to provide extra randomness when sampling | ||
* '''input_scale''' ( | * '''input_scale''' (default: 1) - x and y will be multiplied by this before sampling | ||
* '''output_scale''' ( | * '''output_scale''' (default: 1) - output will be multiplied by this before being returned | ||
Scaling input and output can be accomplished other ways, but are done so commonly | Scaling input and output can be accomplished other ways, but are done so commonly | ||
as to be built into this function for performance reasons. | as to be built into this function for performance reasons. | ||
=== factorio-multioctave-noise === | |||
'''Arguments (named)''': | '''Arguments (named)''': | ||
Line 513: | Line 192: | ||
* '''x''' | * '''x''' | ||
* '''y''' | * '''y''' | ||
* '''seed0''' - integer between 0 and 4294967295 (inclusive) used to populate the backing random noise | |||
* '''seed1''' - integer between 0 and 255 (inclusive) used to provide extra randomness when sampling | |||
* '''octaves''' - how many layers of noise at different scales to sum | |||
* '''persistence''' (constant) - how strong is each layer compared to the next larger one | * '''persistence''' (constant) - how strong is each layer compared to the next larger one | ||
* '''input_scale''' (default: 1) - x and y will be multiplied by this before sampling | |||
* '''output_scale''' (default: 1) - output will be multiplied by this before being returned | |||
* '''input_scale''' ( | |||
* '''output_scale''' ( | |||
=== spot-noise === | === spot-noise === | ||
Line 546: | Line 225: | ||
* '''spot_radius_expression''' (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's radius (this, together with quantity, will determine the spots peak value) | * '''spot_radius_expression''' (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's radius (this, together with quantity, will determine the spots peak value) | ||
* '''spot_favorability_expression''' (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's favorability; spots with higher favorability will be considered first when building the final list of spots for a region | * '''spot_favorability_expression''' (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's favorability; spots with higher favorability will be considered first when building the final list of spots for a region | ||
The infinite series of candidate points (of which '''candidate_point_count''' are actually considered) generated by '''spot-noise''' expressions with the same '''seed0''', '''seed1''', '''region_size''', and '''suggested_minimum_candidate_point_spacing''' will be identical. This allows multiple spot-noise expressions (e.g. for different ore patches) to avoid overlap by using different points from the same list, determined by '''skip_span''' and '''skip_offset'''. | The infinite series of candidate points (of which '''candidate_point_count''' are actually considered) generated by '''spot-noise''' expressions with the same '''seed0''', '''seed1''', '''region_size''', and '''suggested_minimum_candidate_point_spacing''' will be identical. This allows multiple spot-noise expressions (e.g. for different ore patches) to avoid overlap by using different points from the same list, determined by '''skip_span''' and '''skip_offset'''. | ||
Line 562: | Line 238: | ||
{ | { | ||
type = "noise-expression", | type = "noise-expression", | ||
name = "new-temperature-function", | name = "togs-new-temperature-function", | ||
intended_property = "temperature", -- Makes this available in the 'temperature generator' drop-down | intended_property = "temperature", -- Makes this available in the 'temperature generator' drop-down | ||
expression = noise.define_noise_function( function(x,y,tile,map) | expression = noise.define_noise_function( function(x,y,tile,map) | ||
Line 574: | Line 250: | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
local noise = require("noise"); | |||
data:extend{ | data:extend{ | ||
{ | { | ||
type = "noise-expression", | type = "noise-expression", | ||
name | name = "temperature", | ||
expression = { | expression = { | ||
type = "function-application", | type = "function-application", |
Revision as of 09:59, 21 October 2020
Basics
A fragment of a functional program used to generate coherent noise, probably for purposes related to terrain generation.
Noise expressions can be provided as object literals or built using functions in the built-in noise
library.
noise.define_noise_function
allows noise expressions to be defined using a shorthand
that's a subset of Lua (see example definition for an example and its literal equivalent).
Mandatory properties
type
Type: Types/string
Name of the type of this expression. Which other properties apply depend on the expression type.
Expression types
variable
Reference to a pre-defined variable, constant, or a named noise expression.
Predefined variables include "x", "y", and "distance".
Properties:
- variable_name: a Types/string
function-application
Apply a function to a list or associative array of arguments. Some functions expect arguments to be named and some expect them not to be.
Function calls are their own class of expression (as opposed to every function just being its own expression type) because function calls all have similar properties -- arguments are themselves expressions, a function call with all-constant arguments can be constant-folded (due to referential transparency), etc.
Properties:
- function_name (a string; see functions, below)
- arguments (a list or associative array of argument expressions)
literal-boolean
Evaluates to the same boolean value (true or false) every time, given by the literal_value property.
literal-number
Evaluates to the same number every time, given by the literal_value property.
literal-string
Evaluates to the same string every time, given by the literal_value property.
Since the noise generation runtime has no notion of strings or use for them, this is useful only in constant contexts.
literal-object
Evaluates to the same object every time, given by the literal_value property.
e.g.
{
type = "literal-object",
literal_value = {
name = "Bob Hope",
birth_date = {
year = 1903,
month = 5,
day_of_month = 29
}
}
}
Since the noise generation runtime has no notion of objects or use for them, this is useful only in constant contexts, such as the argument of the autoplace-probability function (where the 'literal object' is an AutoplaceSpecitication)
literal-expression
Returns the expression represented by its literal-value property.
Useful mostly for passing expressions (to be evaluated later) to the spot-noise function.
array-construction
value_expressions property should be a list of expressions, each of which will be evaluated to come up with the corresponding value in the resulting array.
Can be used to construct map positions ([x, y]) and map position lists ([[x0,y0], [y1,y1], ...]).
procedure-delimiter
Evaluates and returns the value of its expression property, which is itself an expression.
This hints to the compiler that it should break the subexpression into its own procedure so that the result can be re-used in multiple places. For instance if you want to re-use the same multioctave noise for determining probability of multiple tiles/entities, wrap the multioctave noise expression in a procedure-delimiter. Alternatively, make the noise its own NamedNoiseExpression and reference it by name, using a variable.
if-else-chain
Has an arguments property that is a list of condition-result expression pairs followed by a default result expression, like so:
{
type = "if-else-chain",
arguments = {
condition1, result1,
condition2, result2,
...
defaultResult
}
}
The result of the if-else-chain is the value of the first result expression whose condition expression evaluated to true, or the value of the default result ('else') expression.
Functions
add
Arguments (positional): term, other term
Takes 2 positional arguments and adds them.
subtract
Arguments (positional): minuend, subtrahend
Takes 2 positional arguments and subtracts the second from the first.
multiply
Arguments (positional): factor, other factor
Takes 2 positional arguments and multiplies them.
divide
Arguments (positional): dividend, divisor
Takes 2 positional arguments and divides the first by the second.
exponentiate
Arguments (positional): base, exponent
Takes 2 positional arguments, and raises the first to the second power.
absolute-value
Arguments (positional): value to be absoluted
Takes a single positional argument and returns its absolute value. i.e. If the argument is negative, it is inverted.
clamp
Arguments (positional): value to be clamped, lower limit, upper limit
First argument is clamped between the second and third. The second is treated as a lower limit and the third the upper limit.
ridge
Arguments (positional): value to be ridged, lower limit, upper limit
Similar to clamp but the input value is folded back across the upper and lower limits until it lies between them.
factorio-basis-noise
Arguments (named):
- x
- y
- seed0 - integer between 0 and 4294967295 (inclusive) used to populate the backing random noise
- seed1 - integer between 0 and 255 (inclusive) used to provide extra randomness when sampling
- input_scale (default: 1) - x and y will be multiplied by this before sampling
- output_scale (default: 1) - output will be multiplied by this before being returned
Scaling input and output can be accomplished other ways, but are done so commonly as to be built into this function for performance reasons.
factorio-multioctave-noise
Arguments (named):
- x
- y
- seed0 - integer between 0 and 4294967295 (inclusive) used to populate the backing random noise
- seed1 - integer between 0 and 255 (inclusive) used to provide extra randomness when sampling
- octaves - how many layers of noise at different scales to sum
- persistence (constant) - how strong is each layer compared to the next larger one
- input_scale (default: 1) - x and y will be multiplied by this before sampling
- output_scale (default: 1) - output will be multiplied by this before being returned
spot-noise
Generates random conical spots. The map is divided into square regions, and within each region, candidate points are chosen at random and target density, spot quantity, and radius are calculated for each point (or one of every skip_span candidate points) by configured expressions. Each spot contributes a quantity to a regional target total (which is the average of sampled target densities times the area of the region) until the total has been reached or a maximum spot count is hit. The output value of the function is the maximum height of any spot at a given point.
The parameters that provide expressions to be evaluated for each point (all named something_expression) need to actually return expression objects.
The quantity of the spot is assumed to be the same as its volume. Since the volume of a cone is pi * radius^2 * height / 3, the height ('peak value') of any given spot is calculated as 3 * quantity / (pi * radius^2)
Arguments (named):
- x (number)
- y (number)
- seed0 (constant integer) - random seed, part 1 - usually the map seed is used
- seed1 (constant integer) - random seed, part 2 - usually chosen to identify the noise layer
- region_size (constant integer, default: 512) - width/height of each region
- skip_offset (constant integer, default: 0) - offset of the first candidate point to use
- skip_span (constant integer, default: 1) - number of candidate points to skip over after each one used as a spot, including the used one
- candidate_point_count (constant integer, default:256) - how many candidate points to generate
- candidate_spot_count (constant integer, default depends on skip_span) - an alternative to candidate_point_count - number of spots to generate: candidate_spot_count = X is equivalent to candidate_point_count / skip_span = X
- suggested_minimum_candidate_point_spacing (constant number, default depends on region size and candidate_point_count) - minimum spacing to *try* to achieve while randomly picking points; spot noise may end up placing spots closer than this in crowded regions
- hard_region_target_quantity (constant boolean, default: true) - whether to place a hard limit on the total quantity in each region by reducing the size of any spot (which will be the last spot chosen) that would put it over the limit.
- density_expression (number-returningexpression) - an expression that will be evaluated for each candidate spot to calculate density at that point
- spot_quantity_expression (number-returningexpression) - an expression that will be evaluated for each candidate spot to calculate the spot's quantity
- spot_radius_expression (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's radius (this, together with quantity, will determine the spots peak value)
- spot_favorability_expression (number-returning expression) - an expression that will be evaluated for each candidate spot to calculate the spot's favorability; spots with higher favorability will be considered first when building the final list of spots for a region
The infinite series of candidate points (of which candidate_point_count are actually considered) generated by spot-noise expressions with the same seed0, seed1, region_size, and suggested_minimum_candidate_point_spacing will be identical. This allows multiple spot-noise expressions (e.g. for different ore patches) to avoid overlap by using different points from the same list, determined by skip_span and skip_offset.
Example definition
To override the 'temperature' named noise expression with one that linearly increases to the southeast:
local noise = require("noise");
data:extend{
{
type = "noise-expression",
name = "togs-new-temperature-function",
intended_property = "temperature", -- Makes this available in the 'temperature generator' drop-down
expression = noise.define_noise_function( function(x,y,tile,map)
return (x + y) / 1000
end)
}
}
Which is equivalent to:
local noise = require("noise");
data:extend{
{
type = "noise-expression",
name = "temperature",
expression = {
type = "function-application",
function_name = "divide",
arguments = {
{
type = "function-application",
function_name = "add",
arguments = {
{
type = "variable",
variable_name = "x"
},
{
type = "variable",
variable_name = "y"
}
}
},
{
type = "literal-number",
literal_value = 1000
}
}
}
}
}