Skip to content

Instantly share code, notes, and snippets.

@Genhis
Created December 22, 2023 13:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Genhis/b4c88f47bb39e06a0739a1c177e13d4a to your computer and use it in GitHub Desktop.
Save Genhis/b4c88f47bb39e06a0739a1c177e13d4a to your computer and use it in GitHub Desktop.
Factorio main resource autoplace function using the new noise expressions format (incomplete)
data:extend{
{
type = "noise-function",
name = "resource_autoplace_all_patches",
parameters =
{
"base_density",
"base_spots_per_km2",
"candidate_spot_count",
"frequency_multiplier",
"has_starting_area_placement",
"random_spot_size_minimum",
"random_spot_size_maximum",
"regular_blob_amplitude_multiplier", -- Amplitude of spot 'blob noise' relative to typical spot amplitude
"regular_patch_set_count",
"regular_patch_set_index",
"regular_rq_factor", -- rq_factor is the ratio of the radius of a patch to the cube root of its quantity,
-- i.e. radius of a quantity=1 patch; higher values = fatter, shallower patches
"seed1",
"size_multiplier",
"starting_blob_amplitude_multiplier",
"starting_patch_set_count",
"starting_patch_set_index",
"starting_rq_factor"
},
expression = "if(has_starting_area_placement == 1, max(starting_patches, regular_patches), regular_patches)",
local_expressions =
{
-- Since starting and regular spots get maxed together, the basement value should be the lower of the two.
-- This value needs to be low enough that any noise added to it is still below zero, so that we don't get bits of ores
-- sticking out between spot noise spots. It also needs to be constant because that's how the spot noise op works.
-- Simply using -infinity would work, but calculating it based on blob amplitude:
-- a) looks nicer if you render the value on a map preview
-- b) acts as a check on our blob_amplitude calculations
basement_value = "-6 * max(regular_blob_amplitude_at(regular_blob_amplitude_maximum_distance), starting_blob_amplitude)",
blobs0 = "basis_noise{x = x, y = y, seed0 = map_seed, seed1 = seed1, input_scale = 1/8, output_scale = 1} + \z
basis_noise{x = x, y = y, seed0 = map_seed, seed1 = seed1, input_scale = 1/24, output_scale = 1}",
double_density_distance = 1300, -- Distance at which patches have twice as much stuff in them.
regular_patch_fade_in_distance = 300,
starting_resource_placement_radius = 120, -- The starting area size option should not affect regular ore placement, so it is hard-coded.
starting_patches_split = 0.5, -- Lower numbers decrease the likelihood that the starting patches get split.
-- Starting patches
starting_patches = "spot_noise{x = x,\z
y = y,\z
density_expression = starting_amount / (pi * starting_resource_placement_radius * starting_resource_placement_radius) * \z
starting_modulation,\z
spot_quantity_expression = starting_area_spot_quantity,\z
spot_radius_expression = starting_rq_factor * starting_area_spot_quantity ^ (1/3),\z
spot_favorability_expression = clamp((elevation - 1) / 10, 0, 1) * starting_modulation * 2 - \z
distance / starting_resource_placement_radius + random_penalty_at(0.5, 1),\z
seed0 = map_seed,\z
seed1 = seed1 + 1,\z
skip_span = starting_patch_set_count,\z
skip_offset = starting_patch_set_index,\z
region_size = starting_resource_placement_radius * 2,\z
candidate_spot_count = 32,\z
suggested_minimum_candidate_point_spacing = 32,\z
hard_region_target_quantity = 1,\z
basement_value = basement_value,\z
maximum_spot_basement_radius = 128} + \z
(blobs0 - 0.25) * starting_blob_amplitude",
starting_amount = "20000 * base_density * (frequency_multiplier + 1) * size_multiplier",
starting_area_spot_quantity = "starting_amount / starting_patches_split / frequency_multiplier",
starting_blob_amplitude = "starting_blob_amplitude_multiplier / (pi/3 * starting_rq_factor ^ 2) * starting_area_spot_quantity ^ (1/3)",
starting_modulation = "starting_resource_placement_radius > distance",
-- Regular patches
regular_patches = "spot_noise{x = x,\z
y = y,\z
density_expression = regular_density_at(distance),\z
spot_quantity_expression = regular_spot_quantity_expression,\z
spot_radius_expression = min(32, regular_rq_factor * regular_spot_quantity_expression ^ (1/3)),\z
spot_favorability_expression = 1,\z
seed0 = map_seed,\z
seed1 = seed1,\z
region_size = 1024,\z
candidate_spot_count = candidate_spot_count,\z
suggested_minimum_candidate_point_spacing = 45.254833995939045,\z
skip_span = regular_patch_set_count,\z
skip_offset = regular_patch_set_index,\z
hard_region_target_quantity = 0,\z
basement_value = basement_value,\z
maximum_spot_basement_radius = 128} + \z
(blobs0 + basis_noise{x = x, y = y, seed0 = map_seed, seed1 = seed1, input_scale = 1/64, output_scale = 1.5} - 1/3) * \z
regular_blob_amplitude_at(distance)",
regular_blob_amplitude_maximum_distance = "if(has_starting_area_placement == -1,\z
double_density_distance,\z
double_density_distance + regular_patch_fade_in_distance)",
regular_spot_quantity_expression = "random_penalty_between(random_spot_size_minimum, random_spot_size_maximum, 1) * \z
regular_spot_quantity_base_at(distance)"
},
local_functions =
{
size_effective_distance_at =
{
parameters = {"distance"},
expression = "if(has_starting_area_placement == -1, distance, distance - regular_patch_fade_in_distance)"
},
regular_density_at =
{
parameters = {"distance"},
expression = "base_density * frequency_multiplier * size_multiplier * \z
if(has_starting_area_placement == -1, 1, clamp((distance - starting_resource_placement_radius) / regular_patch_fade_in_distance, 0, 1)) * \z
(1 + clamp(size_effective_distance_at(distance) / double_density_distance, 0, 1))"
},
regular_spot_quantity_base_at =
{
parameters = {"distance"},
expression = "1000000 / base_spots_per_km2 / frequency_multiplier * regular_density_at(distance)"
},
regular_spot_height_typical_at =
{
parameters = {"distance"},
expression = "((random_spot_size_minimum + random_spot_size_maximum) / 2 * regular_spot_quantity_base_at(distance)) ^ (1/3) / (pi/3 * regular_rq_factor ^ 2)"
},
regular_blob_amplitude_at =
{
parameters = {"distance"},
expression = "regular_blob_amplitude_multiplier * min(regular_spot_height_typical_at(regular_blob_amplitude_maximum_distance),\z
regular_spot_height_typical_at(distance))"
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment