From c2cfe64b7e01d822bca7a9299c994b5ffa610292 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 02:00:46 +0300 Subject: [PATCH 01/16] update doc/ru/** scripting-related docs --- doc/ru/scripting.md | 214 +--------------------- doc/ru/scripting/builtins/libhud.md | 52 ++++++ doc/ru/scripting/builtins/libinventory.md | 66 +++++++ doc/ru/scripting/builtins/libworld.md | 38 ++++ src/logic/scripting/lua/libs/libworld.cpp | 4 +- 5 files changed, 163 insertions(+), 211 deletions(-) create mode 100644 doc/ru/scripting/builtins/libhud.md create mode 100644 doc/ru/scripting/builtins/libinventory.md create mode 100644 doc/ru/scripting/builtins/libworld.md diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index 9025f798..d8db4557 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -10,14 +10,17 @@ - [Сущности и компоненты](scripting/ecs.md) - [Библиотеки](#) - [block](scripting/builtins/libblock.md) - - [item](scripting/builtins/libitem.md) - - [entities](scripting/builtins/libentities.md) - [cameras](scripting/builtins/libcameras.md) + - [entities](scripting/builtins/libentities.md) + - [hud](scripting/builtins/libhud.md) + - [inventory](scripting/builtins/libinventory.md) + - [item](scripting/builtins/libitem.md) - [mat4](scripting/builtins/libmat4.md) - [pack](scripting/builtins/libpack.md) - [player](scripting/builtins/libplayer.md) - [quat](scripting/builtins/libquat.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) + - [world](scripting/builtins/libworld.md) - [Модуль core:bit_converter](scripting/modules/core_bit_converter.md) - [Модуль core:data_buffer](scripting/modules/core_data_buffer.md) - [Модули core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md) @@ -38,71 +41,6 @@ require "контентпак:имя_модуля" -- загружает lua модуль из папки modules (расширение не указывается) ``` -## Библиотека *world* - -```python -world.get_list() -> массив таблиц { - name: str, - icon: str -} -``` - -Возвращает информацию о мирах: название и предпросмотр (автоматически загружаемая текстура). - -```python -world.get_day_time() -> number -``` - -Возвращает текущее игровое время от 0.0 до 1.0, где 0.0 и 1.0 - полночь, 0.5 - полдень. - -```python -world.set_day_time(time: number) -``` - -Устанавливает указанное игровое время. - -```python -world.set_day_time_speed(value: number) -``` - -Устанавливает указанную скорость для игрового времени. - -```python -world.get_day_time_speed() -> number -``` - -Возвращает скорость для игрового времени. - -```python -world.get_total_time() -> number -``` - -Возвращает общее суммарное время, прошедшее в мире - -```python -world.get_seed() -> int -``` - -Возвращает зерно мира. - -```python -world.exists() -> bool -``` - -Проверяет существование мира по имени. - -```python -world.is_day() -> bool -``` - -Проверяет является ли текущее время днём. От 0.2(8 утра) до 0.8(8 вечера) - -```python -world.is_night() -> bool -``` - -Проверяет является ли текущее время ночью. От 0.8(8 вечера) до 0.2(8 утра) - ## Библиотека *gui* Библиотека содержит функции для доступа к свойствам UI элементов. Вместо gui следует использовать объектную обертку, предоставляющую доступ к свойствам через мета-методы __index, __newindex: @@ -142,148 +80,6 @@ get_locales_info() -> таблица таблиц где Возвращает информацию о всех загруженных локалях (res/texts/\*). -## Библиотека *inventory* - -Библиотека функций для работы с инвентарем. - -```python -inventory.get(invid: int, slot: int) -> int, int -``` - -Принимает id инвентаря и индекс слота. Возвращает id предмета и его количество. id = 0 (core:empty) обозначает, что слот пуст. - -```python -inventory.set(invid: int, slot: int, itemid: int, count: int) -``` - -Устанавливает содержимое слота. - -```python -inventory.size(invid: int) -> int -``` - -Возращает размер инвентаря (число слотов). Если указанного инвентаря не существует, бросает исключение. - -```python -inventory.add(invid: int, itemid: int, count: int) -> int -``` - -Добавляет предмет в инвентарь. Если не удалось вместить все количество, возвращает остаток. - -```python -inventory.get_block(x: int, y: int, z: int) -> int -``` - -Функция возвращает id инвентаря указанного блока. Если блок не может иметь инвентарь - возвращает 0. - -```python -inventory.bind_block(invid: int, x: int, y: int, z: int) -``` - -Привязывает указанный инвентарь к блоку. - -```python -inventory.unbind_block(x: int, y: int, z: int) -``` - -Отвязывает инвентарь от блока. - -> [!WARNING] -> Инвентари, не привязанные ни к одному из блоков, удаляются при выходе из мира. - -```python -inventory.clone(invid: int) -> int -``` - -Создает копию инвентаря и возвращает id копии. Если копируемого инвентаря не существует, возвращает 0. - -```python -inventory.move(invA: int, slotA: int, invB: int, slotB: int) -``` - -Перемещает предмет из slotA инвентаря invA в slotB инвентаря invB. -invA и invB могут указывать на один инвентарь. -slotB будет выбран автоматически, если не указывать явно. - -## Библиотека hud - -```python -hud.open_inventory() -``` - -Открывает инвентарь - -```python -hud.close_inventory() -``` - -Закрывает инвентарь - -```python -hud.open_block(x: int, y: int, z: int) -> int, str -``` - -Открывает инвентарь и UI блока. Если блок не имеет макета UI - бросается исключение. - -Возвращает id инвентаря блока (при *"inventory-size"=0* создаётся виртуальный инвентарь, который удаляется после закрытия), и id макета UI. - -```python -hud.show_overlay(layoutid: str, playerinv: bool) -``` - -Показывает элемент в режиме оверлея. Также показывает инвентарь игрока, если playerinv - **true** - -> [!NOTE] -> Одновременно может быть открыт только один блок - -```python -hud.open_permanent(layoutid: str) -``` - -Добавляет постоянный элемент на экран. Элемент не удаляется при закрытии инвентаря. Чтобы не перекрывать затенение в режиме инвентаря нужно установить z-index элемента меньшим чем -1. В случае тега inventory, произойдет привязка слотов к инвентарю игрока. - -```python -hud.close(layoutid: str) -``` - -Удаляет элемент с экрана. - -```python -hud.get_block_inventory() -> int -``` - -Дает ID инвентаря открытого блока или 0. - -```python -hud.get_player() -> int -``` - -Дает ID игрока, к которому привязан пользовательский интерфейс. - -```python -hud.pause() -``` - -Открывает меню паузы. - -```python -hud.resume() -``` - -Закрывает меню паузы. - -```python -hud.is_paused() -> bool -``` - -Возвращает true если открыто меню паузы. - -```python -hud.is_inventory_open() -> bool -``` - -Возвращает true если открыт инвентарь или оверлей. - ## Библиотека time ```python diff --git a/doc/ru/scripting/builtins/libhud.md b/doc/ru/scripting/builtins/libhud.md new file mode 100644 index 00000000..cba34dee --- /dev/null +++ b/doc/ru/scripting/builtins/libhud.md @@ -0,0 +1,52 @@ +# Библиотека hud + +```lua +-- Открывает инвентарь. +hud.open_inventory() + +-- Закрывает инвентарь. +hud.close_inventory() + +-- Открывает инвентарь и UI блока. +-- Если блок не имеет макета UI - бросается исключение. +-- Возвращает id инвентаря блока +-- (при *"inventory-size"=0* создаётся виртуальный инвентарь, +-- который удаляется после закрытия), и id макета UI. +hud.open_block(x: int, y: int, z: int) -> int, str +``` + +> [!NOTE] +> Одновременно может быть открыт только один блок + +```lua +-- Показывает элемент в режиме оверлея. +-- Также показывает инвентарь игрока, если playerinv - **true**. +hud.show_overlay(layoutid: str, playerinv: bool) + +-- Добавляет постоянный элемент на экран. Элемент не удаляется при +-- закрытии инвентаря. Чтобы не перекрывать затенение в режиме +-- инвентаря нужно установить z-index элемента меньшим чем -1. +-- В случае тега inventory, произойдет привязка слотов к инвентарю игрока. +hud.open_permanent(layoutid: str) + +-- Удаляет элемент с экрана. +hud.close(layoutid: str) + +-- Дает ID инвентаря открытого блока или 0. +hud.get_block_inventory() -> int + +-- Дает ID игрока, к которому привязан пользовательский интерфейс. +hud.get_player() -> int + +-- Открывает меню паузы. +hud.pause() + +-- Закрывает меню паузы. +hud.resume() + +-- Возвращает true если открыто меню паузы. +hud.is_paused() -> bool + +-- Возвращает true если открыт инвентарь или оверлей. +hud.is_inventory_open() -> bool +``` diff --git a/doc/ru/scripting/builtins/libinventory.md b/doc/ru/scripting/builtins/libinventory.md new file mode 100644 index 00000000..4d937358 --- /dev/null +++ b/doc/ru/scripting/builtins/libinventory.md @@ -0,0 +1,66 @@ +# Библиотека *inventory* + +Библиотека функций для работы с инвентарем. + +```lua +-- Возвращает id предмета и его количество. id = 0 (core:empty) обозначает, что слот пуст. +inventory.get( + -- id инвентаря + invid: int, + -- индекс слота + slot: int +) -> int, int + +-- Устанавливает содержимое слота. +inventory.set( + -- id инвентаря + invid: int, + -- индекс слота + slot: int, + -- id предмета + itemid: int, + -- количество предмета + count: int +) + +-- Возращает размер инвентаря (число слотов). +-- Если указанного инвентаря не существует, бросает исключение. +inventory.size(invid: int) -> int + +-- Добавляет предмет в инвентарь. +-- Если не удалось вместить все количество, возвращает остаток. +inventory.add( + -- id инвентаря + invid: int, + -- id предмета + itemid: int, + -- количество предмета + count: int +) -> int + +-- Функция возвращает id инвентаря блока. +-- Если блок не может иметь инвентарь - возвращает 0. +inventory.get_block(x: int, y: int, z: int) -> int + +-- Привязывает указанный инвентарь к блоку. +inventory.bind_block(invid: int, x: int, y: int, z: int) + +-- Отвязывает инвентарь от блока. +inventory.unbind_block(x: int, y: int, z: int) +``` + +> [!WARNING] +> Инвентари, не привязанные ни к одному из блоков, удаляются при выходе из мира. + +```lua +-- Создает копию инвентаря и возвращает id копии. +-- Если копируемого инвентаря не существует, возвращает 0. +inventory.clone(invid: int) -> int + +-- Перемещает предмет из slotA инвентаря invA в slotB инвентаря invB. +-- invA и invB могут указывать на один инвентарь. +-- slotB будет выбран автоматически, если не указывать явно. +inventory.move(invA: int, slotA: int, invB: int, slotB: int) +``` + + diff --git a/doc/ru/scripting/builtins/libworld.md b/doc/ru/scripting/builtins/libworld.md new file mode 100644 index 00000000..2c95e578 --- /dev/null +++ b/doc/ru/scripting/builtins/libworld.md @@ -0,0 +1,38 @@ +# Библиотека *world* + +```lua +-- Возвращает информацию о мирах. +world.get_list() -> массив таблиц { + -- название мира + name: str, + -- предпросмотр (автоматически загружаемая текстура) + icon: str +} + +-- Возвращает текущее игровое время от 0.0 до 1.0, где 0.0 и 1.0 - полночь, 0.5 - полдень. +world.get_day_time() -> number + +-- Устанавливает указанное игровое время. +world.set_day_time(time: number) + +-- Устанавливает указанную скорость смены времени суток. +world.set_day_time_speed(value: number) + +-- Возвращает скорость скорость смены времени суток. +world.get_day_time_speed() -> number + +-- Возвращает суммарное время, прошедшее в мире. +world.get_total_time() -> number + +-- Возвращает зерно мира. +world.get_seed() -> int + +-- Проверяет существование мира по имени. +world.exists() -> bool + +-- Проверяет является ли текущее время днём. От 0.333(8 утра) до 0.833(8 вечера). +world.is_day() -> bool + +-- Проверяет является ли текущее время ночью. От 0.833(8 вечера) до 0.333(8 утра). +world.is_night() -> bool +``` diff --git a/src/logic/scripting/lua/libs/libworld.cpp b/src/logic/scripting/lua/libs/libworld.cpp index 168edb28..d9ee3412 100644 --- a/src/logic/scripting/lua/libs/libworld.cpp +++ b/src/logic/scripting/lua/libs/libworld.cpp @@ -77,12 +77,12 @@ static int l_world_exists(lua::State* L) { static int l_world_is_day(lua::State* L) { auto daytime = level->getWorld()->getInfo().daytime; - return lua::pushboolean(L, daytime >= 0.2 && daytime <= 0.8); + return lua::pushboolean(L, daytime >= 0.333 && daytime <= 0.833); } static int l_world_is_night(lua::State* L) { auto daytime = level->getWorld()->getInfo().daytime; - return lua::pushboolean(L, daytime < 0.2 || daytime > 0.8); + return lua::pushboolean(L, daytime < 0.333 || daytime > 0.833); } const luaL_Reg worldlib[] = { From f7462a8bcbc82338295f738794d65c9b249e6f50 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 02:05:38 +0300 Subject: [PATCH 02/16] extract libgui.md, libtime.md --- doc/ru/scripting.md | 55 +--------------------------- doc/ru/scripting/builtins/libgui.md | 38 +++++++++++++++++++ doc/ru/scripting/builtins/libtime.md | 13 +++++++ 3 files changed, 53 insertions(+), 53 deletions(-) create mode 100644 doc/ru/scripting/builtins/libgui.md create mode 100644 doc/ru/scripting/builtins/libtime.md diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index d8db4557..1f582d46 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -12,6 +12,7 @@ - [block](scripting/builtins/libblock.md) - [cameras](scripting/builtins/libcameras.md) - [entities](scripting/builtins/libentities.md) + - [gui](scripting/builtins/libgui.md) - [hud](scripting/builtins/libhud.md) - [inventory](scripting/builtins/libinventory.md) - [item](scripting/builtins/libitem.md) @@ -19,6 +20,7 @@ - [pack](scripting/builtins/libpack.md) - [player](scripting/builtins/libplayer.md) - [quat](scripting/builtins/libquat.md) + - [time](scripting/builtins/libtime.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) - [world](scripting/builtins/libworld.md) - [Модуль core:bit_converter](scripting/modules/core_bit_converter.md) @@ -40,56 +42,3 @@ ```lua require "контентпак:имя_модуля" -- загружает lua модуль из папки modules (расширение не указывается) ``` - -## Библиотека *gui* - -Библиотека содержит функции для доступа к свойствам UI элементов. Вместо gui следует использовать объектную обертку, предоставляющую доступ к свойствам через мета-методы __index, __newindex: - -```lua -print(document.some_button.text) -- где 'some_button' - id элемета -document.some_button.text = "новый текст" -``` - -В скрипте макета `layouts/файл_макета.xml` - `layouts/файл_макета.xml.lua` уже доступна переменная **document** содержащая объект класса Document - -```python -gui.str(text: str, context: str) -> str -``` - -Возращает переведенный текст. - -```python -gui.get_viewport() -> {int, int} -``` - -Возвращает размер главного контейнера (окна). - -```python -gui.get_env(document: str) -> table -``` - -Возвращает окружение (таблица глобальных переменных) указанного документа. - -```python -get_locales_info() -> таблица таблиц где - ключ - id локали в формате isolangcode_ISOCOUNTRYCODE - значение - таблица { - name: str # название локали на её языке - } -``` - -Возвращает информацию о всех загруженных локалях (res/texts/\*). - -## Библиотека time - -```python -time.uptime() -> float -``` - -Возвращает время с момента запуска движка в секундах. - -```python -time.delta() -> float -``` - -Возвращает дельту времени (время прошедшее с предыдущего кадра) diff --git a/doc/ru/scripting/builtins/libgui.md b/doc/ru/scripting/builtins/libgui.md new file mode 100644 index 00000000..eb81cd5f --- /dev/null +++ b/doc/ru/scripting/builtins/libgui.md @@ -0,0 +1,38 @@ +# Библиотека *gui* + +Библиотека содержит функции для доступа к свойствам UI элементов. Вместо gui следует использовать объектную обертку, предоставляющую доступ к свойствам через мета-методы __index, __newindex: + +```lua +print(document.some_button.text) -- где 'some_button' - id элемета +document.some_button.text = "новый текст" +``` + +В скрипте макета `layouts/файл_макета.xml` - `layouts/файл_макета.xml.lua` уже доступна переменная **document** содержащая объект класса Document + +```python +gui.str(text: str, context: str) -> str +``` + +Возращает переведенный текст. + +```python +gui.get_viewport() -> {int, int} +``` + +Возвращает размер главного контейнера (окна). + +```python +gui.get_env(document: str) -> table +``` + +Возвращает окружение (таблица глобальных переменных) указанного документа. + +```python +gui.get_locales_info() -> таблица таблиц где + ключ - id локали в формате isolangcode_ISOCOUNTRYCODE + значение - таблица { + name: str # название локали на её языке + } +``` + +Возвращает информацию о всех загруженных локалях (res/texts/\*). diff --git a/doc/ru/scripting/builtins/libtime.md b/doc/ru/scripting/builtins/libtime.md new file mode 100644 index 00000000..d62a7af2 --- /dev/null +++ b/doc/ru/scripting/builtins/libtime.md @@ -0,0 +1,13 @@ +# Библиотека time + +```python +time.uptime() -> float +``` + +Возвращает время с момента запуска движка в секундах. + +```python +time.delta() -> float +``` + +Возвращает дельту времени (время прошедшее с предыдущего кадра) From c340eba358623597ba06faa3873526ee15021525 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 02:23:29 +0300 Subject: [PATCH 03/16] update doc/en/** --- doc/en/scripting.md | 274 +--------------------- doc/en/scripting/builtins/libgui.md | 41 ++++ doc/en/scripting/builtins/libhud.md | 50 ++++ doc/en/scripting/builtins/libinventory.md | 56 +++++ doc/en/scripting/builtins/libtime.md | 13 + doc/en/scripting/builtins/libworld.md | 40 ++++ 6 files changed, 207 insertions(+), 267 deletions(-) create mode 100644 doc/en/scripting/builtins/libgui.md create mode 100644 doc/en/scripting/builtins/libhud.md create mode 100644 doc/en/scripting/builtins/libinventory.md create mode 100644 doc/en/scripting/builtins/libtime.md create mode 100644 doc/en/scripting/builtins/libworld.md diff --git a/doc/en/scripting.md b/doc/en/scripting.md index c0fdcb5e..2ed46bdb 100644 --- a/doc/en/scripting.md +++ b/doc/en/scripting.md @@ -10,14 +10,19 @@ Subsections: - [Entities and components](scripting/ecs.md) - [Libraries](#) - [block](scripting/builtins/libblock.md) - - [item](scripting/builtins/libitem.md) - - [entities](scripting/builtins/libentities.md) - [cameras](scripting/builtins/libcameras.md) + - [entities](scripting/builtins/libentities.md) + - [gui](scripting/builtins/libgui.md) + - [hud](scripting/builtins/libhud.md) + - [inventory](scripting/builtins/libinventory.md) + - [item](scripting/builtins/libitem.md) - [mat4](scripting/builtins/libmat4.md) - [pack](scripting/builtins/libpack.md) - [player](scripting/builtins/libplayer.md) - [quat](scripting/builtins/libquat.md) + - [time](scripting/builtins/libtime.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) + - [world](scripting/builtins/libworld.md) - [Module core:bit_converter](scripting/modules/core_bit_converter.md) - [Module core:data_buffer](scripting/modules/core_data_buffer.md) - [Module core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md) @@ -40,268 +45,3 @@ not part of Lua syntax. require "packid:module_name" -- load Lua module from pack-folder/modules/ -- no extension included, just name ``` - -## *world* library - -## Библиотека *world* - -```python -world.get_list() -> tables array { - name: str, - icon: str -} -``` - -Retuns worlds information: name and preview/icon (loading automatically). - -```python -world.get_day_time() -> number -``` - -Returns current day time in range \[0.0-1.0\] where 0.0 and 1.0 - midnight, 0.5 - noon. - -```python -world.set_day_time(time: number) -``` - -Set day time value. - -```python -world.set_day_time_speed(value: number) -``` - -Sets the specified speed for game time. - -```python -world.get_day_time_speed() -> number -``` - -Returns the speed for game time. - -```python -world.get_total_time() -> number -``` - -Returns total time passed in the world - -```python -world.get_seed() -> int -``` - -Returns world seed. - -``` python -world.is_day() -> boolean -``` - -Proves that this is the current time during the day. From 0.2(8 am) to 0.8(8 pm) - -``` python -world.is_night() -> bool -``` - -Checks that it is the current time at night. From 0.8(8 pm) to 0.2(8 am) - -```python -world.exists() -> bool -``` - -Checks the existence of a world by name. - - -## *gui* library - -The library contains functions for accessing the properties of UI elements. Instead of gui, you should use an object wrapper that provides access to properties through the __index, __newindex meta methods: - -Example: - -```lua -print(document.some_button.text) -- where 'some_button' is an element id -document.some_button.text = "new text" -``` - -```python -gui.str(text: str, context: str) -> str -``` - -Returns translated text. - -```python -gui.get_viewport() -> {int, int} -``` - -Returns size of the main container (window). - -```python -gui.get_env(document: str) -> table -``` - -Returns environment (global variables table) of the specified document. - -```python -gui.get_locales_info() -> table of tables where - key - locale id following isolangcode_ISOCOUNTRYCODE format - value - table { - name: str # name of the locale in its language - } -``` - -Returns information about all loaded locales (res/texts/\*). - -## *inventory* library - -Library for inventories interaction. - -```python -inventory.get(invid: int, slot: int) -> int, int -``` - -Requires an inventory ID and slot index. Returns item ID and count. ID = 0 (core:empty) means that slot is empty. - -```python -inventory.set(invid: int, slot: int, itemid: int, count: int) -``` - -Set slot content. - -```python -inventory.size(invid: int) -> int -``` - -Returns inventory size (slots number). Throws an exception if there's no inventory having specified ID. - -```python -inventory.add(invid: int, itemid: int, count: int) -> int -``` - -Add an item to the specified inventory. Returns remaining count if could not to add fully. - -```python -inventory.get_block(x: int, y: int, z: int) -> int -``` - -Returns block inventory ID or 0. - -```python -inventory.bind_block(invid: int, x: int, y: int, z: int) -``` - -Bind inventory to the specified block. - -```python -inventory.unbind_block(x: int, y: int, z: int) -``` - -Unbind inventory from the specified block. - -> [!WARNING] -> Unbound inventories will be deleted on world close. - -```python -inventory.clone(invid: int) -> int -``` - -Create inventory copy. Returns the created copy ID. - -```python -inventory.move(invA: int, slotA: int, invB: int, slotB: int) -``` - -Move item from slotA of invA to slotB of invB. invA may be the same as invB. -If slotB will be chosen automaticly if argument is not specified. - -## *hud* library - - -```python -hud.open_inventory() -``` - -Open player inventory - -```python -hud.close_inventory() -``` - -Close inventory - -```python -hud.open_block(x: int, y: int, z: int) -> int, str -``` - -Open block UI and inventory. Throws an exception if block has no UI layout. - -Returns block inventory ID (if *"inventory-size"=0* a virtual inventory will be created), and UI layout ID. - -```python -hud.show_overlay(layoutid: str, playerinv: bool) -``` - -Show overlay with layout specified. Shows player inventory also if playerinv is **true** - -> [!NOTE] -> Only one block may be open at same time - -```python -hud.open_permanent(layoutid: str) -``` - -Add element to the screen. The element will be removed on world close only. -**inventory** element will be bound to the player inventory. - -```python -hud.close(layoutid: str) -``` - -Remove an element from the screen - - -```python -hud.get_block_inventory() -> int -``` - -Get open block inventory ID or 0. - -```python -hud.get_player() -> int -``` - -Gives the ID of the player that the UI is bound to. - -```python -hud.pause() -``` - -Opens the pause menu - -```python -hud.resume() -``` - -Closes the pause menu. - -```python -hud.is_paused() -> bool -``` - -Returns true if pause menu is open. - -```python -hud.is_inventory_open() -> bool -``` - -Returns true if inventory is open or overlay is shown. - -### *time* library - -```python -time.uptime() -> float -``` - -Returns time elapsed since the engine started. - -```python -time.delta() -> float -``` - -Returns time elapsed since the last frame. diff --git a/doc/en/scripting/builtins/libgui.md b/doc/en/scripting/builtins/libgui.md new file mode 100644 index 00000000..5ec2490f --- /dev/null +++ b/doc/en/scripting/builtins/libgui.md @@ -0,0 +1,41 @@ +# *gui* library + +The library contains functions for accessing the properties of UI elements. Instead of gui, you should use an object wrapper that provides access to properties through the __index, __newindex meta methods: + +Example: + +```lua +print(document.some_button.text) -- where 'some_button' is an element id +document.some_button.text = "new text" +``` + +```python +gui.str(text: str, context: str) -> str +``` + +Returns translated text. + +```python +gui.get_viewport() -> {int, int} +``` + +Returns size of the main container (window). + +```python +gui.get_env(document: str) -> table +``` + +Returns environment (global variables table) of the specified document. + +```lua +gui.get_locales_info() -> table of tables { + name: str + } +-- where +-- key - locale id following isolangcode_ISOCOUNTRYCODE format +-- value - table { +-- name: str # locale display name +-- } +``` + +Returns information about all loaded locales (res/texts/\*). diff --git a/doc/en/scripting/builtins/libhud.md b/doc/en/scripting/builtins/libhud.md new file mode 100644 index 00000000..b823ab50 --- /dev/null +++ b/doc/en/scripting/builtins/libhud.md @@ -0,0 +1,50 @@ +# *hud* library + +```lua +-- Open player inventory. +hud.open_inventory() + +-- Close inventory. +hud.close_inventory() + +-- Open block UI and inventory. +-- Throws an exception if block has no UI layout. +-- Returns block inventory ID (if *"inventory-size"=0* a virtual +-- inventory will be created), and UI layout ID. +hud.open_block(x: int, y: int, z: int) -> int, str +``` + +> [!NOTE] +> Only one block may be open at same time + +```lua +-- Show overlay with layout specified. +-- Shows player inventory also if playerinv is true. +hud.show_overlay(layoutid: str, playerinv: bool) + +-- Add element to the screen. +-- The element will be removed on world close only. +-- inventory element will be bound to the player inventory. +hud.open_permanent(layoutid: str) + +-- Remove an element from the screen. +hud.close(layoutid: str) + +-- Get open block inventory ID or 0. +hud.get_block_inventory() -> int + +-- Gives the ID of the player that the UI is bound to. +hud.get_player() -> int + +-- Opens the pause menu +hud.pause() + +-- Closes the pause menu. +hud.resume() + +-- Returns true if pause menu is open. +hud.is_paused() -> bool + +-- Returns true if inventory is open or overlay is shown. +hud.is_inventory_open() -> bool +``` diff --git a/doc/en/scripting/builtins/libinventory.md b/doc/en/scripting/builtins/libinventory.md new file mode 100644 index 00000000..a719878a --- /dev/null +++ b/doc/en/scripting/builtins/libinventory.md @@ -0,0 +1,56 @@ +# *inventory* library + +Library for inventories interaction. + +```lua +-- ID = 0 (core:empty) means that slot is empty. +inventory.get( + -- inventory ID + invid: int, + -- slot index + slot: int +) -> int, int +-- Returns item ID and count. + +-- Set slot content. +inventory.set( + -- inventory ID + invid: int, + -- slot index + slot: int, + -- item index + itemid: int, + -- item count + count: int +) + +-- Returns inventory size (slots number). +-- Throws an exception if there's no inventory having specified ID. +inventory.size(invid: int) -> int + +-- Add an item to the specified inventory. +-- Returns remaining count if could not to add fully. +inventory.add(invid: int, itemid: int, count: int) -> int + +-- Returns block inventory ID or 0. +inventory.get_block(x: int, y: int, z: int) -> int + +-- Bind inventory to the specified block. +inventory.bind_block(invid: int, x: int, y: int, z: int) + +-- Unbind inventory from the specified block. +inventory.unbind_block(x: int, y: int, z: int) +``` + +> [!WARNING] +> Unbound inventories will be deleted on world close. + +```lua +-- Create inventory copy. Returns the created copy ID. +inventory.clone(invid: int) -> int + +-- Move item from slotA of invA to slotB of invB. +-- invA may be the same as invB. +-- If slotB will be chosen automaticly if argument is not specified. +inventory.move(invA: int, slotA: int, invB: int, slotB: int) +``` diff --git a/doc/en/scripting/builtins/libtime.md b/doc/en/scripting/builtins/libtime.md new file mode 100644 index 00000000..8fcd4035 --- /dev/null +++ b/doc/en/scripting/builtins/libtime.md @@ -0,0 +1,13 @@ +# *time* library + +```python +time.uptime() -> float +``` + +Returns time elapsed since the engine started. + +```python +time.delta() -> float +``` + +Returns time elapsed since the last frame. diff --git a/doc/en/scripting/builtins/libworld.md b/doc/en/scripting/builtins/libworld.md new file mode 100644 index 00000000..143fded1 --- /dev/null +++ b/doc/en/scripting/builtins/libworld.md @@ -0,0 +1,40 @@ +# *world* library + +```lua +world.get_list() -> tables array { + -- world name + name: str, + -- world icon/preview (loading automatically) + icon: str +} + +-- Returns current day time in range \[0.0-1.0\] +-- where 0.0 and 1.0 - midnight, 0.5 - noon. +world.get_day_time() -> number + +-- Set day time value. +world.set_day_time(time: number) + +-- Sets the specified day time cycle speed. +world.set_day_time_speed(value: number) + +-- Returns the day time cycle speed. +world.get_day_time_speed() -> number + +-- Returns total time passed in the world. +world.get_total_time() -> number + +-- Returns world seed. +world.get_seed() -> int + +-- Proves that this is the current time during the day +-- from 0.333(8 am) to 0.833(8 pm). +world.is_day() -> boolean + +-- Checks that it is the current time at night +-- from 0.833(8 pm) to 0.333(8 am). +world.is_night() -> bool + +-- Checks the existence of a world by name. +world.exists() -> bool +``` From b44ccebc95a0063be1fa435c1d397c395ce9bc36 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 03:00:54 +0300 Subject: [PATCH 04/16] add world-generator.md (WIP) --- doc/images/simplex-noise.gif | Bin 0 -> 143006 bytes doc/ru/world-generator.md | 248 +++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 doc/images/simplex-noise.gif create mode 100644 doc/ru/world-generator.md diff --git a/doc/images/simplex-noise.gif b/doc/images/simplex-noise.gif new file mode 100644 index 0000000000000000000000000000000000000000..8eca11aec7b1d2cc2a55147c74e41d1cd272bb01 GIT binary patch literal 143006 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

eTd^E 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[!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` - блок, которые следует использовать в фрагментах для обозначения пустого пространства, которое не должно заполняться блоками при генерации в мире. From 478d0ceb415e11158333098506f6158c51d58213 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 03:08:40 +0300 Subject: [PATCH 05/16] add animations to world-generator.md --- doc/images/cell-noise.gif | Bin 0 -> 27851 bytes doc/ru/world-generator.md | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 doc/images/cell-noise.gif diff --git a/doc/images/cell-noise.gif b/doc/images/cell-noise.gif new file mode 100644 index 0000000000000000000000000000000000000000..52e7af3269d94aba50c6736ea12e3abb29323f77 GIT binary patch literal 27851 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 bpGL%R>f^!`_9;I;kIE`>rU$-xBlMpD`kY-l literal 0 HcmV?d00001 diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index 38e1fd92..e55f565a 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -168,7 +168,7 @@ local map = Heightmap(ширина, высота) ### heightmap:dump(...) -Метод используемый для отладки, создает изображение на основе карты высот переводя значения из дипазона \[-1.0, 1.0\] в значения яркости \[0, 255\], сохраняя в указанный файл. +Метод используемый для отладки, создает изображение на основе карты высот переводя значения из дипазона `[-1.0, 1.0]` в значения яркости `[0, 255]`, сохраняя в указанный файл. ```lua map:dump('export:test.png') @@ -199,7 +199,7 @@ map:noise( Визуализация шума с октавами 1, 2, 3, 4 и 5. -![image](../images/simplex-noise.md) +![image](../images/simplex-noise.gif) ### heightmap:cellnoise(...) @@ -207,6 +207,8 @@ map:noise( Зерно шума может быть указано в поле `map.noiseSeed`. +![image](../images/cell-noise.gif) + ## VoxelFragment (фрагмент) Фрагмент создается вызовом функции: From 8961c24b601e926c2f57570b1193e4fd63ec0c4f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 04:34:30 +0300 Subject: [PATCH 06/16] update world-generator.md --- doc/ru/world-generator.md | 177 ++++++++++++++++++++++++++++++-------- 1 file changed, 142 insertions(+), 35 deletions(-) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index e55f565a..6c193ab1 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -88,18 +88,18 @@ structures = [ - ключ forest - имя биома - parameters - веса и центральные значения параметров для биома. См. раздел [выбор биома](#выбор-биома). Количество записей должно соответствовать количеству параметров выбора биомов. - layers - слои блоков от верхнего к нижнему. - - height - высота слоя в блоках. -1 используется для обозначения безразмерного (заполняющего) слоя, который может быть только один. Его высота вычисляется автоматически. - - block - полное имя блока - - below-sea-level - может ли слой быть сгенерированным ниже уровня моря (пример: дёрн). При значении false, при генерации ниже уровня моря, слой будет заменён на следующий. + - height - высота слоя в блоках. -1 используется для обозначения безразмерного (заполняющего) слоя, который может быть только один. Его высота вычисляется автоматически. + - block - полное имя блока + - below-sea-level - может ли слой быть сгенерированным ниже уровня моря (пример: дёрн). При значении false, при генерации ниже уровня моря, слой будет заменён на следующий. - sea-layers - слои океана. Положение верхнего слоя совпадает с высотой уровня моря. - plant-chance - вероятность генерации растения на блоке поверхности. - plants - растения, случайно расставляемые на поверхности. - - weight - вес, напрямую влияющий на шанс выбора конкретного растения. - - block - блок растения + - weight - вес, напрямую влияющий на шанс выбора конкретного растения. + - block - блок растения - structure-chance - вероятность генерации малой структуры на блоке поверхности. - structures - структуры, случайно расставляемые на поверхности. - - name - имя структуры, объявленной в `structures.json`. - - weight - вес, напрямую влияющий на шанс выбора конкретной структуры. + - name - имя структуры, объявленной в `structures.json`. + - weight - вес, напрямую влияющий на шанс выбора конкретной структуры. ### Параметры биомов @@ -113,14 +113,14 @@ structures = [ -- w, h - ширина и высота карты (в точках) -- bpd - (blocks per dot) число блоков на точку (масштаб) function generate_biome_parameters(x, y, w, h, seed, bpd) - -- создание карт высот (Heightmap) для каждого параметра биомов - -- ... - return карты_через_запятую + -- создание карт высот (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) @@ -182,18 +182,18 @@ map:dump('export:test.png') ```lua map:noise( - -- смещение координат - offset: {number, number}, - -- коэфициент масштабирования координат - scale: number, - -- число октав шума (по-умолчанию: 1) - [опционально] octaves: integer, - -- множитель амплитуды шума (по-умолчанию: 1.0) - [опционально] multiplier: number, - -- карта смещений координаты X при генерации шума - [опционально] shiftMapX: Heightmap, - -- карта смещений координаты Y при генерации шума - [опционально] shiftMapY: Heightmap, + -- смещение координат + offset: {number, number}, + -- коэфициент масштабирования координат + scale: number, + -- число октав шума (по-умолчанию: 1) + [опционально] octaves: integer, + -- множитель амплитуды шума (по-умолчанию: 1.0) + [опционально] multiplier: number, + -- карта смещений координаты X при генерации шума + [опционально] shiftMapX: Heightmap, + -- карта смещений координаты Y при генерации шума + [опционально] shiftMapY: Heightmap, ) -> nil ``` @@ -214,30 +214,30 @@ map:noise( Фрагмент создается вызовом функции: ```lua generation.create_fragment( - -- точка A - a: vec3, - -- точка B - b: vec3, - -- автоматически обрезать фрагмент, если возможно - crop: bool + -- точка A + a: vec3, + -- точка B + b: vec3, + -- автоматически обрезать фрагмент, если возможно + crop: bool ) -> VoxelFragment ``` Фрагмент может быть загружен из файла: ```lua generation.load_fragment( - -- файл фрагмента - filename: str + -- файл фрагмента + filename: str ) -> VoxelFragment ``` Фрагмент может быть сохранен в файл: ```lua generation.save_fragment( - -- сохраняемый фрагмент - fragment: VoxelFragment, - -- файл - filename: str + -- сохраняемый фрагмент + fragment: VoxelFragment, + -- файл + filename: str ) -> nil ``` @@ -245,6 +245,113 @@ generation.save_fragment( Фрагмент может быть обрезан до размеров содержимого (воздух игнорируется) вызовом метода `fragment:crop()`. +## Генерация карты высот + +По-умолчанию, движок генерирует карту высот, состоящую из нулей. + +Для генерации пользовательских карт высот требуется реализовать функцию: +```lua +function generate_heightmap( + x, y, -- смещение карты высот + w, h, -- размер карты высот, ожидаемый движком + seed, -- зерно мира + bpd, -- число блоков на точку карты (blocks per dot) - масштаб + [опционально] inputs -- массив входных карт параметров биомов + -- (см. свойство heightmap-inputs генератора) +) --> Heightmap +``` + +Пример генерации карты высот из простого симплекс-шума с приведением +к нужному диапазону: + +```lua +function generate_heightmap(x, y, w, h, seed, bpd) + -- создаем карту высот с заданным размером + local map = Heightmap(w, h) + -- настраиваем зерно шума + map.noiseSeed = seed + -- шум с масштабом 1/10 на 4 октавы с амплитудой 0.5 + map:noise({x, y}, 0.1*bpd, 4, 0.5) + -- сдвигаем высоты к положительному диапазону + map:add(0.5) + return map +end +``` + +## Ручная расстановка структур + +### Размещения структур/тоннелей + +Размещение структуры / линии представляет собой массив из заданного +набора параметров. + +Структура: +```lua +{имя_структуры, позиция_структуры, поворот, [опционально] приоритет} +``` + +Где: +- имя_структуры - строка содержащая имя структуры, зарегистрированная в structures.toml. +- позиция_структуры - vec3 (массив из трех чисел) относительно позиции чанка. +- поворот - число от 0 до 3 обозначающая поворот структуры по оси Y. +- приоритет - число определяющее порядок установки структур. Структуры с меньшем приоритетом перекрываются структурами с большим. + +Тоннель: +```lua +{":line", блок_заполнитель, точка_а, точка_б, радиус} +``` + +Где: +- блок_заполнитель - числовой id блока, из которого будет состоять структура. +- точка_а, точка_б - vec3, vec3 позиции начала и конца тоннеля. +- радиус - радиус тоннеля в блоках + + +### Расстановка малых структур + +```lua +function place_structures( + x, z, -- позиция начала области в блоках + w, d, -- размер области в блоках + seed, -- зерно мира + heights, -- карта высот чанка + chunk_height, -- высота чанка +) --> массив размещений структур +``` + +Структуры могут размещаться за пределами чанка, но не дальше, чем на один чанк. + +Пример: + +```lua +function place_structures(x, z, w, d, seed, hmap, chunk_height) + local placements = {} + local height = hmap:at(w/2, h/2) * chunk_height + + -- устанавливает башню по центру чанка + table.insert(placements, { + 'tower', {w/2, height, d/2}, math.random() * 4, 2 + }) + return placements +end +``` + +### Расстановка 'широких' структур + +Структуры и тоннели могут размещаться за пределами чанка, но не дальше, чем на число чанков, указанное в свойстве генератора `wide-structs-chunks-radius`. + +В отличие от прошлой функции, сюда не передается карта высот, +так как вызов происходит на ранних этапах генерации чанка. + +```lua +function place_structures_wide( + x, z, -- позиция начала области в блоках + w, d, -- размер области в блоках + seed, -- зерно мира + chunk_height, -- высота чанка +) --> массив размещений структур / тоннелей +``` + ## Структурный воздух `core:struct_air` - блок, которые следует использовать в фрагментах для обозначения пустого пространства, которое не должно заполняться блоками при генерации в мире. From 7330896eb4fc1ad31df18af5830d773502caed24 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 05:15:07 +0300 Subject: [PATCH 07/16] add heightmap:sub(...) operation --- src/logic/scripting/lua/usertypes/lua_type_heightmap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/logic/scripting/lua/usertypes/lua_type_heightmap.cpp b/src/logic/scripting/lua/usertypes/lua_type_heightmap.cpp index 5dde49f7..cdefa4f0 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_heightmap.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_heightmap.cpp @@ -256,6 +256,7 @@ static std::unordered_map methods { {"cellnoise", lua::wrap>}, {"pow", lua::wrap>}, {"add", lua::wrap>}, + {"sub", lua::wrap>}, {"mul", lua::wrap>}, {"min", lua::wrap>}, {"max", lua::wrap>}, From 0c282d44a03f64072f9fd166718a3f9bf409c6b5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 05:21:17 +0300 Subject: [PATCH 08/16] update world-generator.md --- doc/ru/world-generator.md | 77 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index 6c193ab1..fd697f92 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -9,7 +9,6 @@ - **Растение** - случайно расставляемый на поверхности блок. - **Малая структура** - структура, размер которой не превышает размера чанка. Пример: деревья. - ## Файл конфигурации Генератор мира распознается при наличии файла `generators/имя_генератора.toml`. Другие файлы, относящиеся к генератору, должны находиться в директории `generators/имя_генератора.files/`: @@ -24,6 +23,7 @@ - **sea-level** - уровень моря (ниже этого уровня вместо воздуха будут генерироваться слои моря (sea-layers)). По-умолчанию: 0. - **biomes-bpd** - количество блоков на точку карты параметра выбора биомов. По-умолчанию: 8. - **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 4. +- **wide-structs-chunks-radius** - масимальный радиус размещения 'широких' структур, измеряемый в чанках. ## Фрагменты @@ -166,6 +166,53 @@ Heightmap это класс для работы с картами высот (м local map = Heightmap(ширина, высота) ``` +### Унарные операции + +Операции применяются ко всем значениям высоты. + +```lua +map:abs() +``` + +Приводит значения высот к абсолютным. + + +### Бинарные операции + +Операции с применением второй карты или скаляра. + +Арифметические операции: + +```lua +-- Прибавление +map:add(value: Heightmap|number) + +-- Вычитание +map:sub(value: Heightmap|number) + +-- Умножение +map:mul(value: Heightmap|number) + +-- Возведение в степень +map:pow(value: Heightmap|number) +``` + +Другие операции: + +```lua +-- Минимум +map:min(value: Heightmap|number) + +-- Максимум +map:max(value: Heightmap|number) + +-- Примешивание +map:mixin(value: Heightmap|number, t: Heightmap|number) +-- t - фактор смешивания от 0.0 до 1.0 +-- смешивание производится по формуле: +-- map_value * (1.0 - t) + value * t +``` + ### heightmap:dump(...) Метод используемый для отладки, создает изображение на основе карты высот переводя значения из дипазона `[-1.0, 1.0]` в значения яркости `[0, 255]`, сохраняя в указанный файл. @@ -209,6 +256,34 @@ map:noise( ![image](../images/cell-noise.gif) +### heightmap:resize(...) + +```lua +map:resize(ширина, высота, интерполяция) +``` + +Изменяет размер карты высот. + +Доступные режимы интерполяции: +- 'nearest' - без интерполяции +- 'linear' - билинейная интерполяция + +### heightmap:crop(...) + +```lua +map:crop(x, y, ширина, высота) +``` + +Обрезает карту высот до заданной области. + +## heightmap:at(x, y) + +```lua +map:at(x, y) --> number +``` + +Возвращает значение высота на заданной позиции. + ## VoxelFragment (фрагмент) Фрагмент создается вызовом функции: From 15b0b04ac91c507cbc188ee494eba2bd149e5ce0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 06:58:40 +0300 Subject: [PATCH 09/16] update doc/*/main-page.md --- doc/en/main-page.md | 20 ++++++++++++-------- doc/ru/main-page.md | 21 +++++++++++++-------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/doc/en/main-page.md b/doc/en/main-page.md index 193b4279..13fc3eb1 100644 --- a/doc/en/main-page.md +++ b/doc/en/main-page.md @@ -1,16 +1,20 @@ # Documentation +Documentation for the in-development engine version 0.23. + +[Documentation for the last stable version (0.22.x)](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.22/doc/en/main-page.md) + ## Sections -- [Engine usage recommendations](engine-use-recommendations.md) -- [Content-packs](content-packs.md) -- [Block properties](block-properties.md) -- [Item properties](item-properties.md) -- [XML UI building](xml-ui-layouts.md) - [Assets preloading](assets-preload.md) - [Audio](audio.md) -- [Scripting](scripting.md) -- [Console](console.md) - [Block models](block-models.md) -- [Rigging](rigging.md) +- [Block properties](block-properties.md) +- [Console](console.md) +- [Content-packs](content-packs.md) +- [Engine usage recommendations](engine-use-recommendations.md) +- [Item properties](item-properties.md) - [Resources (resources.json)](resources.md) +- [Rigging](rigging.md) +- [Scripting](scripting.md) +- [XML UI building](xml-ui-layouts.md) diff --git a/doc/ru/main-page.md b/doc/ru/main-page.md index c0f52e61..72a4980a 100644 --- a/doc/ru/main-page.md +++ b/doc/ru/main-page.md @@ -1,16 +1,21 @@ # Документация +Документация версии движка 0.23, находящейся в разработке. + +[Документация стабильной версии (0.22.x)](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.22/doc/ru/main-page.md) + ## Разделы -- [Рекомендации по использованию движка](engine-use-recommendations.md) +- [XML разметка интерфейса](xml-ui-layouts.md) +- [Аудио](audio.md) +- [Движок генерации мира](world-generator.md) +- [Консоль](console.md) - [Контент‐паки](content-packs.md) +- [Модели блоков](block-models.md) +- [Предзагрузка ассетов](assets-preload.md) +- [Рекомендации по использованию движка](engine-use-recommendations.md) +- [Ресурсы (resources.json)](resources.md) +- [Риггинг](rigging.md) - [Свойства блоков](block-properties.md) - [Свойства предметов](item-properties.md) -- [XML разметка интерфейса](xml-ui-layouts.md) -- [Предзагрузка ассетов](assets-preload.md) -- [Аудио](audio.md) - [Скриптинг](scripting.md) -- [Консоль](console.md) -- [Модели блоков](block-models.md) -- [Риггинг](rigging.md) -- [Ресурсы (resources.json)](resources.md) From 0eb0743dfced54b6e5ac4b451dd66262272b6cb0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 07:11:57 +0300 Subject: [PATCH 10/16] add table-of-contents to world-generator.md --- doc/ru/world-generator.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index fd697f92..1af00163 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -1,5 +1,32 @@ # Генератор мира +## Содержание + +- [Основные понятия](#основные-понятия) +- [Файл конфигурации](#файл-конфигурации) +- [Фрагменты](#фрагменты) +- [Структуры](#структуры) +- [Биомы](#биомы) + * [Параметры биомов](#параметры-биомов) + * [Выбор биома](#выбор-биома) +- [Heightmap (карта высот)](#heightmap-карта-высот) + * [Конструктор](#конструктор) + * [Унарные операции](#унарные-операции) + * [Бинарные операции](#бинарные-операции) + * [heightmap:dump(...)](#heightmapdump) + * [heightmap:noise(...)](#heightmapnoise) + * [heightmap:cellnoise(...)](#heightmapcellnoise) + * [heightmap:resize(...)](#heightmapresize) + * [heightmap:crop(...)](#heightmapcrop) +- [heightmap:at(x, y)](#heightmapatx-y) +- [VoxelFragment (фрагмент)](#voxelfragment-) +- [Генерация карты высот](#генерация-карты-высот) +- [Ручная расстановка структур](#ручная-расстановка-структур) + * [Размещения структур/тоннелей](#размещения-структуртоннелей) + * [Расстановка малых структур](#расстановка-малых-структур) + * [Расстановка 'широких' структур](#расстановка-широких-структур) +- [Структурный воздух](#структурный-воздух) + ## Основные понятия Понятия используемые далее по тексту. @@ -430,3 +457,5 @@ function place_structures_wide( ## Структурный воздух `core:struct_air` - блок, которые следует использовать в фрагментах для обозначения пустого пространства, которое не должно заполняться блоками при генерации в мире. + + From 326e52b304cb8a4e37dcf9a98f991f2cb492709f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 07:15:22 +0300 Subject: [PATCH 11/16] fix md reference --- doc/ru/world-generator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index 1af00163..eb8d6d60 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -19,7 +19,7 @@ * [heightmap:resize(...)](#heightmapresize) * [heightmap:crop(...)](#heightmapcrop) - [heightmap:at(x, y)](#heightmapatx-y) -- [VoxelFragment (фрагмент)](#voxelfragment-) +- [VoxelFragment (фрагмент)](#voxelfragment-фрагмент) - [Генерация карты высот](#генерация-карты-высот) - [Ручная расстановка структур](#ручная-расстановка-структур) * [Размещения структур/тоннелей](#размещения-структуртоннелей) From 0ad59fadd9faf4a23bcb24e116679d595560e4d6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 08:07:36 +0300 Subject: [PATCH 12/16] rename lua_type_voxelstructure.cpp to lua_type_voxelfragment.cpp --- .../{lua_type_voxelstructure.cpp => lua_type_voxelfragment.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/logic/scripting/lua/usertypes/{lua_type_voxelstructure.cpp => lua_type_voxelfragment.cpp} (100%) diff --git a/src/logic/scripting/lua/usertypes/lua_type_voxelstructure.cpp b/src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp similarity index 100% rename from src/logic/scripting/lua/usertypes/lua_type_voxelstructure.cpp rename to src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp From faca68e6c33b5cce4a3ea545d35adedd17fa078e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 08:46:32 +0300 Subject: [PATCH 13/16] replace argument 'seed' with global constant 'SEED' --- doc/ru/world-generator.md | 27 ++++--- .../base/generators/demo.files/script.lua | 24 +++--- .../scripting/scripting_world_generation.cpp | 80 ++++++++++--------- src/world/generator/GeneratorDef.hpp | 20 +++-- src/world/generator/WorldGenerator.cpp | 8 +- 5 files changed, 85 insertions(+), 74 deletions(-) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index eb8d6d60..aa9228c3 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -3,6 +3,7 @@ ## Содержание - [Основные понятия](#основные-понятия) +- [Глобальные переменные](#глобальные-переменные) - [Файл конфигурации](#файл-конфигурации) - [Фрагменты](#фрагменты) - [Структуры](#структуры) @@ -52,6 +53,14 @@ - **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 4. - **wide-structs-chunks-radius** - масимальный радиус размещения 'широких' структур, измеряемый в чанках. +## Глобальные переменные + +В скрипте генератора доступны следующие переменные: + +- `SEED` - зерно генерации мира +- `__DIR__` - директория генератора (`пак:generators/имя_генератора.files/`) +- `__FILE__` - файл скрипта (`пак:generators/имя_генератора.files/script.lua`) + ## Фрагменты Фрагмент является сохраненной для дальнейшего использования, областью мира, как и чанк, ограниченную некоторой шириной, высотой и длиной. Фрагмент может содержать данные не только о блоках, попадающих в область, но и о инвентарях блоков области, а так же сущностях. В отличие от чанка, размер фрагмента произволен. @@ -75,6 +84,7 @@ ``` На данный момент, имя структуры должно совпадать с именем использованного фрагмента. + ## Биомы Биом определяет то, из каких блоков и какими слоями генерируется ландшафт, а так же набор растений, структур. @@ -139,22 +149,22 @@ structures = [ -- x, y - позиция начала карты (в точках) -- w, h - ширина и высота карты (в точках) -- bpd - (blocks per dot) число блоков на точку (масштаб) -function generate_biome_parameters(x, y, w, h, seed, bpd) +function generate_biome_parameters(x, y, w, h, bpd) -- создание карт высот (Heightmap) для каждого параметра биомов -- ... return карты_через_запятую end -- пример -function generate_biome_parameters(x, y, w, h, seed, s) +function generate_biome_parameters(x, y, w, h, s) -- карта температур local tempmap = Heightmap(w, h) - tempmap.noiseSeed = seed + 5324 + 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.noiseSeed = SEED + 953 hummap:noise({x, y}, 0.04*s, 6) hummap:pow(3) @@ -356,7 +366,6 @@ generation.save_fragment( function generate_heightmap( x, y, -- смещение карты высот w, h, -- размер карты высот, ожидаемый движком - seed, -- зерно мира bpd, -- число блоков на точку карты (blocks per dot) - масштаб [опционально] inputs -- массив входных карт параметров биомов -- (см. свойство heightmap-inputs генератора) @@ -367,11 +376,11 @@ function generate_heightmap( к нужному диапазону: ```lua -function generate_heightmap(x, y, w, h, seed, bpd) +function generate_heightmap(x, y, w, h, bpd) -- создаем карту высот с заданным размером local map = Heightmap(w, h) -- настраиваем зерно шума - map.noiseSeed = seed + map.noiseSeed = SEED -- шум с масштабом 1/10 на 4 октавы с амплитудой 0.5 map:noise({x, y}, 0.1*bpd, 4, 0.5) -- сдвигаем высоты к положительному диапазону @@ -415,7 +424,6 @@ end function place_structures( x, z, -- позиция начала области в блоках w, d, -- размер области в блоках - seed, -- зерно мира heights, -- карта высот чанка chunk_height, -- высота чанка ) --> массив размещений структур @@ -426,7 +434,7 @@ function place_structures( Пример: ```lua -function place_structures(x, z, w, d, seed, hmap, chunk_height) +function place_structures(x, z, w, d, hmap, chunk_height) local placements = {} local height = hmap:at(w/2, h/2) * chunk_height @@ -449,7 +457,6 @@ end function place_structures_wide( x, z, -- позиция начала области в блоках w, d, -- размер области в блоках - seed, -- зерно мира chunk_height, -- высота чанка ) --> массив размещений структур / тоннелей ``` diff --git a/res/content/base/generators/demo.files/script.lua b/res/content/base/generators/demo.files/script.lua index ffec458d..756da50e 100644 --- a/res/content/base/generators/demo.files/script.lua +++ b/res/content/base/generators/demo.files/script.lua @@ -2,13 +2,13 @@ local _, dir = parse_path(__DIR__) local ores = require "base:generation/ores" ores.load(dir) -function place_structures(x, z, w, d, seed, hmap, chunk_height) +function place_structures(x, z, w, d, hmap, chunk_height) local placements = {} - ores.place(placements, x, z, w, d, seed, hmap, chunk_height) + ores.place(placements, x, z, w, d, SEED, hmap, chunk_height) return placements end -function place_structures_wide(x, z, w, d, seed, chunk_height) +function place_structures_wide(x, z, w, d, chunk_height) local placements = {} if math.random() < 0.05 then -- generate caves local sx = x + math.random() * 10 - 5 @@ -43,22 +43,22 @@ function place_structures_wide(x, z, w, d, seed, chunk_height) return placements end -function generate_heightmap(x, y, w, h, seed, s, inputs) +function generate_heightmap(x, y, w, h, s, inputs) local umap = Heightmap(w, h) local vmap = Heightmap(w, h) - umap.noiseSeed = seed - vmap.noiseSeed = seed + umap.noiseSeed = SEED + vmap.noiseSeed = SEED vmap:noise({x+521, y+70}, 0.1*s, 3, 25.8) vmap:noise({x+95, y+246}, 0.15*s, 3, 25.8) local map = Heightmap(w, h) - map.noiseSeed = seed + map.noiseSeed = SEED map:noise({x, y}, 0.8*s, 4, 0.02) map:cellnoise({x, y}, 0.1*s, 3, 0.3, umap, vmap) map:add(0.7) local rivermap = Heightmap(w, h) - rivermap.noiseSeed = seed + rivermap.noiseSeed = SEED rivermap:noise({x+21, y+12}, 0.1*s, 4) rivermap:abs() rivermap:mul(2.0) @@ -67,21 +67,21 @@ function generate_heightmap(x, y, w, h, seed, s, inputs) map:mul(rivermap) local desertmap = Heightmap(w, h) - desertmap.noiseSeed = seed + desertmap.noiseSeed = SEED desertmap:cellnoise({x+52, y+326}, 0.3*s, 2, 0.2) desertmap:add(0.4) map:mixin(desertmap, inputs[1]) return map end -function generate_biome_parameters(x, y, w, h, seed, s) +function generate_biome_parameters(x, y, w, h, s) local tempmap = Heightmap(w, h) - tempmap.noiseSeed = seed + 5324 + tempmap.noiseSeed = SEED + 5324 tempmap:noise({x, y}, 0.04*s, 6) tempmap:mul(0.5) tempmap:add(0.5) local hummap = Heightmap(w, h) - hummap.noiseSeed = seed + 953 + hummap.noiseSeed = SEED + 953 hummap:noise({x, y}, 0.04*s, 6) tempmap:pow(3) hummap:pow(3) diff --git a/src/logic/scripting/scripting_world_generation.cpp b/src/logic/scripting/scripting_world_generation.cpp index caa08d6c..32479888 100644 --- a/src/logic/scripting/scripting_world_generation.cpp +++ b/src/logic/scripting/scripting_world_generation.cpp @@ -24,10 +24,13 @@ static debug::Logger logger("generator-scripting"); class LuaGeneratorScript : public GeneratorScript { State* L; const GeneratorDef& def; - scriptenv env; + scriptenv env = nullptr; + + fs::path file; + std::string dirPath; public: - LuaGeneratorScript(State* L, const GeneratorDef& def, scriptenv env) - : L(L), def(def), env(std::move(env)) { + LuaGeneratorScript(State* L, const GeneratorDef& def, const fs::path& file, const std::string& dirPath) + : L(L), def(def), file(file), dirPath(dirPath) { } virtual ~LuaGeneratorScript() { @@ -37,10 +40,33 @@ public: } } + void initialize(uint64_t seed) override { + env = create_environment(L); + stackguard _(L); + + pushenv(L, *env); + pushstring(L, dirPath); + setfield(L, "__DIR__"); + pushstring(L, dirPath + "/script.lua"); + setfield(L, "__FILE__"); + pushinteger(L, seed); + setfield(L, "SEED"); + + pop(L); + + if (fs::exists(file)) { + std::string src = files::read_string(file); + logger.info() << "script (generator) " << file.u8string(); + pop(L, execute(L, *env, src, file.u8string())); + } else { + // Use default (empty) script + pop(L, execute(L, *env, "", "")); + } + } + std::shared_ptr generateHeightmap( const glm::ivec2& offset, const glm::ivec2& size, - uint64_t seed, uint bpd, const std::vector>& inputs ) override { @@ -48,7 +74,6 @@ public: if (getfield(L, "generate_heightmap")) { pushivec_stack(L, offset); pushivec_stack(L, size); - pushinteger(L, seed); pushinteger(L, bpd); if (!inputs.empty()) { size_t inputsNum = def.heightmapInputs.size(); @@ -58,7 +83,7 @@ public: rawseti(L, i+1); } } - if (call_nothrow(L, 6 + (!inputs.empty()))) { + if (call_nothrow(L, 5 + (!inputs.empty()))) { auto map = touserdata(L, -1)->getHeightmap(); pop(L, 2); return map; @@ -69,7 +94,7 @@ public: } std::vector> generateParameterMaps( - const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, uint bpd + const glm::ivec2& offset, const glm::ivec2& size, uint bpd ) override { std::vector> maps; @@ -78,9 +103,8 @@ public: if (getfield(L, "generate_biome_parameters")) { pushivec_stack(L, offset); pushivec_stack(L, size); - pushinteger(L, seed); pushinteger(L, bpd); - if (call_nothrow(L, 6, biomeParameters)) { + if (call_nothrow(L, 5, biomeParameters)) { for (int i = biomeParameters-1; i >= 0; i--) { maps.push_back( touserdata(L, -1-i)->getHeightmap()); @@ -166,7 +190,6 @@ public: std::vector placeStructuresWide( const glm::ivec2& offset, const glm::ivec2& size, - uint64_t seed, uint chunkHeight ) override { std::vector placements {}; @@ -176,9 +199,8 @@ public: if (getfield(L, "place_structures_wide")) { pushivec_stack(L, offset); pushivec_stack(L, size); - pushinteger(L, seed); pushinteger(L, chunkHeight); - if (call_nothrow(L, 6, 1)) { + if (call_nothrow(L, 5, 1)) { int len = objlen(L, -1); for (int i = 1; i <= len; i++) { rawgeti(L, i); @@ -194,8 +216,10 @@ public: } std::vector placeStructures( - const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, - const std::shared_ptr& heightmap, uint chunkHeight + const glm::ivec2& offset, + const glm::ivec2& size, + const std::shared_ptr& heightmap, + uint chunkHeight ) override { std::vector placements {}; @@ -204,10 +228,9 @@ public: if (getfield(L, "place_structures")) { pushivec_stack(L, offset); pushivec_stack(L, size); - pushinteger(L, seed); newuserdata(L, heightmap); pushinteger(L, chunkHeight); - if (call_nothrow(L, 7, 1)) { + if (call_nothrow(L, 6, 1)) { int len = objlen(L, -1); for (int i = 1; i <= len; i++) { rawgeti(L, i); @@ -224,28 +247,11 @@ public: }; std::unique_ptr scripting::load_generator( - const GeneratorDef& def, const fs::path& file, const std::string& dirPath + const GeneratorDef& def, + const fs::path& file, + const std::string& dirPath ) { auto L = create_state(*engine->getPaths(), StateType::GENERATOR); - auto env = create_environment(L); - stackguard _(L); - pushenv(L, *env); - pushstring(L, dirPath); - setfield(L, "__DIR__"); - pushstring(L, dirPath + "/script.lua"); - setfield(L, "__FILE__"); - - pop(L); - - if (fs::exists(file)) { - std::string src = files::read_string(file); - logger.info() << "script (generator) " << file.u8string(); - pop(L, execute(L, *env, src, file.u8string())); - } else { - // Use default (empty) script - pop(L, execute(L, *env, "", "")); - } - - return std::make_unique(L, def, std::move(env)); + return std::make_unique(L, def, file, dirPath); } diff --git a/src/world/generator/GeneratorDef.hpp b/src/world/generator/GeneratorDef.hpp index 3a1e110b..b48d69de 100644 --- a/src/world/generator/GeneratorDef.hpp +++ b/src/world/generator/GeneratorDef.hpp @@ -123,17 +123,17 @@ class GeneratorScript { public: virtual ~GeneratorScript() = default; + virtual void initialize(uint64_t seed) = 0; + /// @brief Generate a heightmap with values in range 0..1 /// @param offset position of the heightmap in the world /// @param size size of the heightmap - /// @param seed world seed /// @param bpd blocks per dot /// @param inputs biome parameter maps passed to generate_heightmap /// @return generated heightmap (can't be nullptr) virtual std::shared_ptr generateHeightmap( const glm::ivec2& offset, const glm::ivec2& size, - uint64_t seed, uint bpd, const std::vector>& inputs ) = 0; @@ -141,13 +141,11 @@ public: /// @brief Generate a biomes parameters maps /// @param offset position of maps in the world /// @param size maps size - /// @param seed world seed /// @param bpd blocks per dot /// @return generated maps (can't be nullptr) virtual std::vector> generateParameterMaps( const glm::ivec2& offset, const glm::ivec2& size, - uint64_t seed, uint bpd ) = 0; @@ -156,12 +154,10 @@ public: /// wide-structs-chunks-radius /// @param offset position of the area /// @param size size of the area (blocks) - /// @param seed world seed /// @param chunkHeight chunk height to use as heights multiplier virtual std::vector placeStructuresWide( - const glm::ivec2& offset, - const glm::ivec2& size, - uint64_t seed, + const glm::ivec2& offset, + const glm::ivec2& size, uint chunkHeight ) = 0; @@ -169,13 +165,15 @@ public: /// placed to nearest chunks also (position of out area). /// @param offset position of the area /// @param size size of the area (blocks) - /// @param seed world seed /// @param heightmap area heightmap /// @param chunkHeight chunk height to use as heights multiplier /// @return structure & line placements virtual std::vector placeStructures( - const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed, - const std::shared_ptr& heightmap, uint chunkHeight) = 0; + const glm::ivec2& offset, + const glm::ivec2& size, + const std::shared_ptr& heightmap, + uint chunkHeight + ) = 0; }; /// @brief Structure voxel fragments and metadata diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index 7fb699f6..08b0b7f2 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -31,6 +31,8 @@ WorldGenerator::WorldGenerator( seed(seed), surroundMap(0, BASIC_PROTOTYPE_LAYERS + def.wideStructsChunksRadius * 2) { + def.script->initialize(seed); + uint levels = BASIC_PROTOTYPE_LAYERS + def.wideStructsChunksRadius * 2; surroundMap = SurroundMap(0, levels); @@ -228,7 +230,7 @@ void WorldGenerator::generateStructuresWide( return; } auto placements = def.script->placeStructuresWide( - {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed, CHUNK_H + {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, CHUNK_H ); placeStructures(placements, prototype, chunkX, chunkZ); @@ -245,7 +247,7 @@ void WorldGenerator::generateStructures( const auto& heightmap = prototype.heightmap; auto placements = def.script->placeStructures( - {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed, + {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, heightmap, CHUNK_H ); placeStructures(placements, prototype, chunkX, chunkZ); @@ -297,7 +299,6 @@ void WorldGenerator::generateBiomes( auto biomeParams = def.script->generateParameterMaps( {floordiv(chunkX * CHUNK_W, bpd), floordiv(chunkZ * CHUNK_D, bpd)}, {floordiv(CHUNK_W, bpd)+1, floordiv(CHUNK_D, bpd)+1}, - seed, bpd ); for (auto index : def.heightmapInputs) { @@ -339,7 +340,6 @@ void WorldGenerator::generateHeightmap( prototype.heightmap = def.script->generateHeightmap( {floordiv(chunkX * CHUNK_W, bpd), floordiv(chunkZ * CHUNK_D, bpd)}, {floordiv(CHUNK_W, bpd)+1, floordiv(CHUNK_D, bpd)+1}, - seed, bpd, prototype.heightmapInputs ); From 44d7fdf1c7354dc282562a6955a4b94bd6f0d538 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 09:10:14 +0300 Subject: [PATCH 14/16] fix world-generator.md --- doc/ru/world-generator.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index aa9228c3..ac4a42fa 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -19,7 +19,7 @@ * [heightmap:cellnoise(...)](#heightmapcellnoise) * [heightmap:resize(...)](#heightmapresize) * [heightmap:crop(...)](#heightmapcrop) -- [heightmap:at(x, y)](#heightmapatx-y) + * [heightmap:at(x, y)](#heightmapatx-y) - [VoxelFragment (фрагмент)](#voxelfragment-фрагмент) - [Генерация карты высот](#генерация-карты-высот) - [Ручная расстановка структур](#ручная-расстановка-структур) @@ -313,7 +313,7 @@ map:crop(x, y, ширина, высота) Обрезает карту высот до заданной области. -## heightmap:at(x, y) +### heightmap:at(x, y) ```lua map:at(x, y) --> number From 32f6c9a200813d73ca3df4d8264873a583f6dac6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 09:47:37 +0300 Subject: [PATCH 15/16] add world-generator.md english version --- doc/en/world-generator.md | 464 ++++++++++++++++++++++++++++++++++++++ doc/ru/world-generator.md | 3 +- 2 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 doc/en/world-generator.md diff --git a/doc/en/world-generator.md b/doc/en/world-generator.md new file mode 100644 index 00000000..d243ff62 --- /dev/null +++ b/doc/en/world-generator.md @@ -0,0 +1,464 @@ +# World Generator + +## Table of Contents + +- [Basic concepts](#basic-concepts) +- [Global variables](#global-variables) +- [Configuration file](#configuration-file) +- [Fragments](#fragments) +- [Structures](#structures) +- [Biomes](#biomes) + * [Biome parameters](#biome-parameters) + * [Biome selection](#biome-selection) +- [Heightmap](#heightmap) + * [Constructor](#constructor) + * [Unary operations](#unary-operations) + * [binary operations](#binary-operations) + * [heightmap:dump(...)](#heightmapdump) + * [heightmap:noise(...)](#heightmapnoise) + * [heightmap:cellnoise(...)](#heightmapcellnoise) + * [heightmap:resize(...)](#heightmapresize) + * [heightmap:crop(...)](#heightmapcrop) + * [heightmap:at(x, y)](#heightmapatx-y) +- [VoxelFragment (fragment in Lua)](#voxelfragment-fragment-in-lua) +- [Generating a height map](#generating-a-height-map) +- [Manual structures placement](#manual-structures-placement) + * [Structure/tunnel placements](#structuretunnel-placements) + * [Small structures placement](#small-structures-placement) + * [Wide structures placement](#wide-structures-placement) +- [Structural air](#structural-air) + +## Basic concepts + +Concepts used in the text below. + +- **Combined array/object** - TOML or JSON file that is combined from several versions in different packs, which allows adding data to it from outside. The fields of the combined object are overwritten in order from first to last, just like other resources in the packs. In the case of a combined array, a check for duplicates is **not** performed. +- **Biome** - information that determines what blocks and what layers the terrain is generated from, as well as a set of plants, structures. +- **Plant** - a block randomly placed on the surface. +- **Small structure** - a structure whose size does not exceed the size of a chunk. Example: trees. + +## Configuration file + +The world generator is recognized if the file `generators/generator_name.toml` is present. Other files related to the generator are located in the directory `generators/generator_name.files/`: +- biomes.toml - biome definitions +- structures.toml - structure definitions +- script.lua - generator script +- fragments - directory where fragment files are located + +The main properties described in the configuration file: +- **caption** - the generator display name. By default, it is generated from the id. +- **biome-parameters** - the number of biome selection parameters (from 0 to 4). Default: 0. +- **sea-level** - sea level (below this level, sea-layers will be generated instead of air). Default: 0. +- **biomes-bpd** - number of blocks per point of the biome selection parameter map. Default: 8. +- **heights-bpd** - number of blocks per point of the height map. Default: 8. +- **wide-structs-chunks-radius** - maximum radius for placing 'wide' structures, measured in chunks. + +## Global variables + +The following variables are available in the generator script: + +- `SEED` - world generation seed +- `__DIR__` - generator directory (`pack:generators/generator_name.files/`) +- `__FILE__` - script file (`pack:generators/generator_name.files/script.lua`) + +## Fragments + +A fragment is a region of the world, like a chunk, saved for later use, limited by a certain width, height and length. A fragment can contain data not only blocks, but also the block inventories and entities. Unlike a chunk, the size of a fragment is arbitrary. + +Fragment can be created using the `fragment.save` command, or the `generation.create_fragment` function. + +Fragments used by the generator must present in the directory: +`generators/generator_name.files/fragments/` + +## Structures + +A structure is a set of rules for inserting a fragment into the world by the generator. It currently has no properties, being created as empty objects in the `generators/generator_name.files/structures.json` file. Example: +```lua +{ + "tree0": {}, + "tree1": {}, + "tree2": {}, + "tower": {}, + "coal_ore0": {} +} +``` + +Currently, the name of the structure must match the name of the fragment used. + +## Biomes + +A biome defines what blocks and layers the terrain is generated from, as well as a set of plants and structures. + +Biomes are defined in a combined object: +`generators/generator_name.files/biomes.toml` + +Let's look at the biome structure using the forest example from the base:demo generator: + +```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} +] +``` + +- key 'forest' - biome name +- parameters - weights and central values ​​of the parameters for the biome. See the [biome selection](#biome-selection) section. The number of entries must match the number of biome selection parameters. +- layers - block layers from top to bottom. + - height - layer height in blocks. -1 is used to mark the filler layer, of which there can only be one. Its height is calculated automatically. + - block - full block name + - below-sea-level - whether the layer can be generated below sea level (example: turf). If false, when generated below sea level, the layer will be replaced by the next one. +- sea-layers - ocean layers. The position of the top layer coincides with the sea level height. +- plant-chance - probability of generating a plant on a surface block. +- plants - plants randomly placed on the surface. + - weight - weight directly affecting the chance of selecting a specific plant. + - block - plant block +- structure-chance - probability of generating a small structure on a surface block. +- structures - structures randomly placed on the surface. + - name - name of the structure declared in `structures.json`. + - weight - weight directly affecting the chance of choosing a specific structure. + +### Biome Parameters + +The generator parameter `biome-parameters` defines the number of biome selection parameters (examples: temperature, humidity). + +Biome parameter value maps are generated in the same way as height maps. + +It is required to implement the function: +```lua +-- x, y - map start position (in dots) +-- w, h - map width and height (in dots) +-- bpd - (blocks per dot) number of blocks per dot (scale) +function generate_biome_parameters(x, y, w, h, bpd) + -- creating heightmaps for each biome parameter + -- ... + return comma-separated_maps +end + +-- example +function generate_biome_parameters(x, y, w, h, s) + -- temperature map + local tempmap = Heightmap(w, h) + tempmap.noiseSeed = SEED + 5324 + tempmap:noise({x, y}, 0.04*s, 6) + tempmap:pow(3) + -- humidity map + local hummap = Heightmap(w, h) + hummap.noiseSeed = SEED + 953 + hummap:noise({x, y}, 0.04*s, 6) + hummap:pow(3) + return tempmap, hummap +end +``` + +### Biome selection + +After generating the parameter maps for each biome, scores are calculated for all parameters: + +$score = \frac{|V - V_b|}{W_b}$ + +Where $V$ is the parameter value, $V_b$ is the central parameter value for the biome, $W_b$ is the biome weight for the parameter. + +The generator selects the biome with the **least** sum of parameter scores. + +>[!WARNING] +> If the parameter values ​​and weights are not set up correctly, biomes may have an effect similar to the depth conflict in 3D graphics when two surfaces overlap. +> + In the case of biomes, the pattern looks random due to the distortion of these 'surfaces' by the noise used to generate the parameter maps. + > + To get rid of the effect, you can either adjust the weights or parameter values ​​of the biomes, or increase the difference in the generation of the parameter maps. + +## Heightmap + +Heightmap is a class for working with heightmaps (arbitrarily sized matrices of floating point numbers). + +### Constructor + +The heightmap constructor requires integer width and height. + +```lua +local map = Heightmap(width, height) +``` + +### Unary Operations + +Operations apply to all height values. + +```lua +map:abs() +``` + +Casts height values ​​to absolute. + +### Binary Operations + +Operations using a second map or a scalar. + +Arithmetic operations: + +```lua +-- Addition +map:add(value: Heightmap|number) + +-- Subtraction +map:sub(value: Heightmap|number) + +-- Multiplication +map:mul(value: Heightmap|number) + +-- Exponentiation +map:pow(value: Heightmap|number) +``` + +Other operations: + +```lua +-- Minimum +map:min(value: Heightmap|number) + +-- Maximum +map:max(value: Heightmap|number) + +-- Mixing +map:mixin(value: Heightmap|number, t: Heightmap|number) +-- t - mixing factor from 0.0 to 1.0 +-- mixing is performed according to the formula: +-- map_value * (1.0 - t) + value * t +``` + +### heightmap:dump(...) + +A method used for debugging, creates an image based on a heightmap by converting values ​​from the range `[-1.0, 1.0]` to brightness values ​​`[0, 255]`, saving it to the specified file. + +```lua +map:dump('export:test.png') +``` + +### heightmap:noise(...) + +A method that generates simplex noise, adding it to the existing values. + +The noise seed can be specified in the `map.noiseSeed` field. + +```lua +map:noise( +-- coordinate offset +offset: {number, number}, +-- coordinate scaling factor +scale: number, +-- number of noise octaves (default: 1) +[optional] octaves: integer, +-- noise amplitude multiplier (default: 1.0) +[optional] multiplier: number, +-- X coordinate offset map for noise generation +[optional] shiftMapX: Heightmap, +-- Y coordinate offset map for noise generation +[optional] shiftMapY: Heightmap, +) -> nil +``` + +Noise visualization with octaves 1, 2, 3, 4, and 5. + +![image](../images/simplex-noise.gif) + +### heightmap:cellnoise(...) + +Analog of heightmap:noise that generates cellular noise. + +The noise seed can be specified in the `map.noiseSeed` field. + +![image](../images/cell-noise.gif) + +### heightmap:resize(...) + +```lua +map:resize(width, height, interpolation) +``` + +Changes the heightmap size. + +Available interpolation modes: +- 'nearest' - no interpolation +- 'linear' - bilinear interpolation + +### heightmap:crop(...) + +```lua +map:crop(x, y, width, height) +``` + +Crops the heightmap to the specified area. + +### heightmap:at(x, y) + +```lua +map:at(x, y) --> number +``` + +Returns the height value at the specified position. + +## VoxelFragment (fragment in Lua) + +A fragment is created by calling the function: +```lua +generation.create_fragment( + -- point A + a: vec3, + -- point B + b: vec3, + -- automatically crop the fragment if possible + crop: bool +) -> VoxelFragment +``` + +A fragment can be loaded from a file: +```lua +generation.load_fragment( + -- fragment file + filename: str +) -> VoxelFragment +``` + +A fragment can be saved to a file: +```lua +generation.save_fragment( + -- fragment to save + fragment: VoxelFragment, + -- file + filename: str +) -> nil +``` + +The fragment size is available as the `size` property. + +A fragment can be cropped to fit its contents (air is ignored) by calling the `fragment:crop()` method. + +## Generating a height map + +By default, the engine generates a height map consisting of zeros. + +To generate custom heightmaps, you need to implement the function: + +```lua +function generate_heightmap( + x, y, -- offset of the heightmap + w, h, -- size of the heightmap expected by the engine + bpd, -- number of blocks per dot - scale + [optional] inputs -- array of input maps of biome parameters + -- (see the heightmap-inputs property of the generator) +) --> Heightmap +``` + +An example of generating a heightmap from simplex noise with reduction +to the desired range: + +```lua +function generate_heightmap(x, y, w, h, bpd) + -- create a heightmap with a given size + local map = Heightmap(w, h) + -- set the noise seed + map.noiseSeed = SEED + -- noise with a scale of 1/10 by 4 octaves with an amplitude of 0.5 + map:noise({x, y}, 0.1*bpd, 4, 0.5) + -- shift heights to positive range + map:add(0.5) + return map +end +``` + +## Manual structures placement + +### Structure/tunnel placements + +Placement of a structure/line is an array of a given +set of parameters. + +Structure: +```lua +{structure_name, structure_position, rotation, [optional] priority} +``` + +Where: +- structure_name - a string containing the name of the structure, registered in structures.toml. +- structure_position - a vec3 (an array of three numbers) relative to the position of the chunk. +- rotation - a number from 0 to 3 indicating the rotation of the structure along the Y axis. +- priority - a number determining the order in which structures are placed. Structures with lower priority are overlapped by structures with higher priority. + +Tunnel: +```lua +{":line", filler_block, point_a, point_b, radius} +``` + +Where: +- filler_block - the numeric id of the block that the structure will consist of. +- point_a, point_b - vec3, vec3 positions of the start and end of the tunnel. +- radius - radius of the tunnel in blocks + +### Small structures placement + +```lua +function place_structures( + x, z, -- start position of the region in blocks + w, d, -- size of the region in blocks + heights, -- height map of the chunk + chunk_height, -- height of the chunk +) --> array of structure placements +``` + +Structures can be placed outside the chunk, but not more than one chunk away. + +Example: + +```lua +function place_structures(x, z, w, d, hmap, chunk_height) + local placements = {} + local height = hmap:at(w/2, h/2) * chunk_height + + -- places the tower in the center of the chunk + table.insert(placements, { + 'tower', {w/2, height, d/2}, math.random() * 4, 2 + }) + return placements +end +``` + +### Wide structures placement + +Structures and tunnels can be placed outside a chunk, but no further than the number of chunks specified in the `wide-structs-chunks-radius` property of the generator. + +Unlike the previous function, no heightmap is passed here, since the call occurs early in the chunk generation. + +```lua +function place_structures_wide( + x, z, -- start position of the region in blocks + w, d, -- size of the region in blocks + chunk_height, -- height of the chunk +) --> array of structure / tunnel placements +``` + +## Structural Air + +`core:struct_air` - a block that should be used in chunks to mark empty space that should not be filled with blocks when generated in the world. + + diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index ac4a42fa..4d6d9fec 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -50,7 +50,7 @@ - **biome-parameters** - количество параметров выбора биомов (от 0 до 4). По-умолчанию: 0. - **sea-level** - уровень моря (ниже этого уровня вместо воздуха будут генерироваться слои моря (sea-layers)). По-умолчанию: 0. - **biomes-bpd** - количество блоков на точку карты параметра выбора биомов. По-умолчанию: 8. -- **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 4. +- **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 8. - **wide-structs-chunks-radius** - масимальный радиус размещения 'широких' структур, измеряемый в чанках. ## Глобальные переменные @@ -93,6 +93,7 @@ `generators/имя_генератора.files/biomes.toml` Разберем структуру биома на примере леса из генератора base:demo: + ```toml [forest] parameters = [ From 68f47800af6bf70b82f9b73a114016c326e9114f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 16 Oct 2024 09:49:20 +0300 Subject: [PATCH 16/16] update doc/en/main-page.md --- doc/en/main-page.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/en/main-page.md b/doc/en/main-page.md index 13fc3eb1..0de00ad5 100644 --- a/doc/en/main-page.md +++ b/doc/en/main-page.md @@ -17,4 +17,5 @@ Documentation for the in-development engine version 0.23. - [Resources (resources.json)](resources.md) - [Rigging](rigging.md) - [Scripting](scripting.md) +- [World generator engine](world-generator.md) - [XML UI building](xml-ui-layouts.md)