add world-generator.md (WIP)

This commit is contained in:
MihailRis 2024-10-16 03:00:54 +03:00
parent c340eba358
commit b44ccebc95
2 changed files with 248 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

248
doc/ru/world-generator.md Normal file
View File

@ -0,0 +1,248 @@
# Генератор мира
## Основные понятия
Понятия используемые далее по тексту.
- **Комбинируемый массив/объект** - TOML или JSON файл, который комбинируется из нескольких версий в разных паках, что позволяет добавлять в него данные извне. Поля комбинированного объекта перезаписываются в порядке от первого к последнему, так же, как и другие ресурсы в паках. В случае комбинируемого массива, проверка на дубликаты **не** выполняется.
- **Биом** - информация, определяющая то, из каких блоков и какими слоями генерируется ландшафт, а так же набор растений, структур.
- **Растение** - случайно расставляемый на поверхности блок.
- **Малая структура** - структура, размер которой не превышает размера чанка. Пример: деревья.
## Файл конфигурации
Генератор мира распознается при наличии файла `generators/имя_генератора.toml`. Другие файлы, относящиеся к генератору, должны находиться в директории `generators/имя_генератора.files/`:
- biomes.toml - объявления биомов
- structures.toml - объявления структур
- script.lua - скрипт генератора
- fragments - директория в которой располагаются файлы фрагментов
Основные свойства, описываемые в файле конфигурации:
- **caption** - отображаемое имя генератора. По-умолчанию генерируется из id.
- **biome-parameters** - количество параметров выбора биомов (от 0 до 4). По-умолчанию: 0.
- **sea-level** - уровень моря (ниже этого уровня вместо воздуха будут генерироваться слои моря (sea-layers)). По-умолчанию: 0.
- **biomes-bpd** - количество блоков на точку карты параметра выбора биомов. По-умолчанию: 8.
- **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 4.
## Фрагменты
Фрагмент является сохраненной для дальнейшего использования, областью мира, как и чанк, ограниченную некоторой шириной, высотой и длиной. Фрагмент может содержать данные не только о блоках, попадающих в область, но и о инвентарях блоков области, а так же сущностях. В отличие от чанка, размер фрагмента произволен.
На данный момент, фрагмент может быть создан при помощи команды `fragment.save`, либо через функцию `generation.create_fragment`.
Фрагменты, используемые генератором, должны находиться в директории:
`generators/имя_генератора.files/fragments/`
## Структуры
Структура - набор правил по вставке фрагмента в мир генератором. На данный момент не имеет свойств, создаваясь в виде пустых объектов в файле `generators/имя_генератора.files/structures.json`. Пример:
```lua
{
"tree0": {},
"tree1": {},
"tree2": {},
"tower": {},
"coal_ore0": {}
}
```
На данный момент, имя структуры должно совпадать с именем использованного фрагмента.
## Биомы
Биом определяет то, из каких блоков и какими слоями генерируется ландшафт, а так же набор растений, структур.
Биомы объявляются в комбинируемом объекте:
`generators/имя_генератора.files/biomes.toml`
Разберем структуру биома на примере леса из генератора base:demo:
```toml
[forest]
parameters = [
{weight=1, value=1},
{weight=0.5, value=0.2}
]
layers = [
{below-sea-level=false, height=1, block="base:grass_block"},
{below-sea-level=false, height=7, block="base:dirt"},
{height=-1, block="base:stone"},
{height=1, block="base:bazalt"}
]
sea-layers = [
{height=-1, block="base:water"}
]
plant-chance = 0.4
plants = [
{weight=1, block="base:grass"},
{weight=0.03, block="base:flower"}
]
structure-chance = 0.032
structures = [
{name="tree0", weight=1},
{name="tree1", weight=1},
{name="tree2", weight=1},
{name="tower", weight=0.002}
]
```
- ключ forest - имя биома
- parameters - веса и центральные значения параметров для биома. См. раздел [выбор биома](#выбор-биома). Количество записей должно соответствовать количеству параметров выбора биомов.
- layers - слои блоков от верхнего к нижнему.
- height - высота слоя в блоках. -1 используется для обозначения безразмерного (заполняющего) слоя, который может быть только один. Его высота вычисляется автоматически.
- block - полное имя блока
- below-sea-level - может ли слой быть сгенерированным ниже уровня моря (пример: дёрн). При значении false, при генерации ниже уровня моря, слой будет заменён на следующий.
- sea-layers - слои океана. Положение верхнего слоя совпадает с высотой уровня моря.
- plant-chance - вероятность генерации растения на блоке поверхности.
- plants - растения, случайно расставляемые на поверхности.
- weight - вес, напрямую влияющий на шанс выбора конкретного растения.
- block - блок растения
- structure-chance - вероятность генерации малой структуры на блоке поверхности.
- structures - структуры, случайно расставляемые на поверхности.
- name - имя структуры, объявленной в `structures.json`.
- weight - вес, напрямую влияющий на шанс выбора конкретной структуры.
### Параметры биомов
Параметр генератора `biome-parameters` определяет количество параметров биомов, используемых при их выборе (примеры: температура, влажность).
Карты значений параметров биомов генеруются так же, как и карты высот.
Требуется реализовать функцию:
```lua
-- x, y - позиция начала карты (в точках)
-- w, h - ширина и высота карты (в точках)
-- bpd - (blocks per dot) число блоков на точку (масштаб)
function generate_biome_parameters(x, y, w, h, seed, bpd)
-- создание карт высот (Heightmap) для каждого параметра биомов
-- ...
return карты_через_запятую
end
-- пример
function generate_biome_parameters(x, y, w, h, seed, s)
-- карта температур
local tempmap = Heightmap(w, h)
tempmap.noiseSeed = seed + 5324
tempmap:noise({x, y}, 0.04*s, 6)
tempmap:pow(3)
-- карта влажности
local hummap = Heightmap(w, h)
hummap.noiseSeed = seed + 953
hummap:noise({x, y}, 0.04*s, 6)
hummap:pow(3)
return tempmap, hummap
end
```
### Выбор биома
После генерации карт параметров для каждого биома вычисляются оценки по всем параметрам:
$score = \frac{|V - V_b|}{W_b}$
Где $V$ - значение параметра, $V_b$ центральное значение параметра для биома, $W_b$ - вес биома для параметра.
Генератор выбирает биом с **наименьшей** суммой оценок для параметров.
>[!WARNING]
> При неудачной настройке значений и весов параметров у биомов может возникать эффект, имеющий ту же природу, что и конфликт глубины в 3D графике при наложении двух поверхностей.
>
В случае биомов, узор выглядит случайным из-за искривления этих 'поверхностей' шумом, используемым при генерации карт параметров.
>
Для избавления от эффекта можно либо скорректировать веса или значения параметров биомов, либо увеличить разницу в генерации карт параметров.
## Heightmap (карта высот)
Heightmap это класс для работы с картами высот (матрицами чисел с плавающей точкой произвольного размера).
### Конструктор
Конструктор карты высот требует указания целочисленных ширины и высоты.
```lua
local map = Heightmap(ширина, высота)
```
### heightmap:dump(...)
Метод используемый для отладки, создает изображение на основе карты высот переводя значения из дипазона \[-1.0, 1.0\] в значения яркости \[0, 255\], сохраняя в указанный файл.
```lua
map:dump('export:test.png')
```
### heightmap:noise(...)
Метод генерирующий симплекс-шум, прибавляя его к имеющимся значениям.
Зерно шума может быть указано в поле `map.noiseSeed`.
```lua
map:noise(
-- смещение координат
offset: {number, number},
-- коэфициент масштабирования координат
scale: number,
-- число октав шума (по-умолчанию: 1)
[опционально] octaves: integer,
-- множитель амплитуды шума (по-умолчанию: 1.0)
[опционально] multiplier: number,
-- карта смещений координаты X при генерации шума
[опционально] shiftMapX: Heightmap,
-- карта смещений координаты Y при генерации шума
[опционально] shiftMapY: Heightmap,
) -> nil
```
Визуализация шума с октавами 1, 2, 3, 4 и 5.
![image](../images/simplex-noise.md)
### heightmap:cellnoise(...)
Аналог heightmap:noise генерирующий клеточный шум.
Зерно шума может быть указано в поле `map.noiseSeed`.
## VoxelFragment (фрагмент)
Фрагмент создается вызовом функции:
```lua
generation.create_fragment(
-- точка A
a: vec3,
-- точка B
b: vec3,
-- автоматически обрезать фрагмент, если возможно
crop: bool
) -> VoxelFragment
```
Фрагмент может быть загружен из файла:
```lua
generation.load_fragment(
-- файл фрагмента
filename: str
) -> VoxelFragment
```
Фрагмент может быть сохранен в файл:
```lua
generation.save_fragment(
-- сохраняемый фрагмент
fragment: VoxelFragment,
-- файл
filename: str
) -> nil
```
Размер фрагмента доступен как свойство `size`.
Фрагмент может быть обрезан до размеров содержимого (воздух игнорируется) вызовом метода `fragment:crop()`.
## Структурный воздух
`core:struct_air` - блок, которые следует использовать в фрагментах для обозначения пустого пространства, которое не должно заполняться блоками при генерации в мире.