Compare commits

..

No commits in common. "master" and "5.10.0-rc1" have entirely different histories.

746 changed files with 63013 additions and 75015 deletions

View file

@ -1,4 +1,4 @@
Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*,-performance-avoid-endl,performance-inefficient-string-concatenation'
Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*'
WarningsAsErrors: '-*,modernize-use-emplace,performance-type-promotion-in-math-fn,performance-faster-string-find,performance-implicit-cast-in-loop'
CheckOptions:
- key: performance-unnecessary-value-param.AllowedTypes

1
.gitattributes vendored
View file

@ -5,4 +5,3 @@
*.h diff=cpp
*.gltf binary
*.x binary

View file

@ -14,7 +14,7 @@ Contributions are welcome! Here's how you can help:
[clone](https://help.github.com/articles/cloning-a-repository/) your fork.
2. Before you start coding, consider opening an
[issue on Github](https://github.com/luanti-org/luanti/issues) to discuss the
[issue at Github](https://github.com/minetest/minetest/issues) to discuss the
suitability and implementation of your intended contribution with the core
developers.
@ -25,16 +25,16 @@ Contributions are welcome! Here's how you can help:
the work, to avoid disappointment.
You may also benefit from discussing on our IRC development channel
[#luanti-dev](http://www.luanti.org/irc/). Note that a proper IRC client
[#minetest-dev](http://www.minetest.net/irc/). Note that a proper IRC client
is required to speak on this channel.
3. Start coding!
- Refer to the
[Lua API](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md),
[Developer Wiki](https://dev.luanti.org/) and other
[documentation](https://github.com/luanti-org/luanti/tree/master/doc).
- Follow the [C/C++](https://dev.luanti.org/Code_style_guidelines) and
[Lua](https://dev.luanti.org/Lua_code_style_guidelines) code style guidelines.
[Lua API](https://github.com/minetest/minetest/blob/master/doc/lua_api.md),
[Developer Wiki](http://dev.minetest.net/Main_Page) and other
[documentation](https://github.com/minetest/minetest/tree/master/doc).
- Follow the [C/C++](http://dev.minetest.net/Code_style_guidelines) and
[Lua](http://dev.minetest.net/Lua_code_style_guidelines) code style guidelines.
- Check your code works as expected and document any changes to the Lua API.
- To avoid conflicting changes between contributions, do not do the following manually. They will be done before each release.
- Run `updatepo.sh` or update `luanti.po{,t}` even if your code adds new translatable strings.
@ -53,7 +53,7 @@ Contributions are welcome! Here's how you can help:
- The following lines should describe the commit, starting a new line for each point.
5. Once you are happy with your changes, submit a pull request.
- Open the [pull-request form](https://github.com/luanti-org/luanti/pull/new/master).
- Open the [pull-request form](https://github.com/minetest/minetest/pull/new/master).
- Add a description explaining what you've done (or if it's a
work-in-progress - what you need to do).
- Make sure to fill out the pull request template.
@ -64,8 +64,8 @@ Contributions are welcome! Here's how you can help:
picture of the project.
2. It works.
3. It follows the code style for
[C/C++](https://dev.luanti.org/Code_style_guidelines) or
[Lua](https://dev.luanti.org/Lua_code_style_guidelines).
[C/C++](http://dev.minetest.net/Code_style_guidelines) or
[Lua](http://dev.minetest.net/Lua_code_style_guidelines).
4. The code's interfaces are well designed, regardless of other aspects that
might need more work in the future.
5. It uses protocols and formats which include the required compatibility.
@ -76,9 +76,9 @@ If you experience an issue, we would like to know the details - especially when
a stable release is on the way.
1. Do a quick search on GitHub to check if the issue has already been reported.
2. Is it an issue with the Luanti *engine*? If not, report it
[elsewhere](http://www.luanti.org/development/#reporting-issues).
3. [Open an issue](https://github.com/luanti-org/luanti/issues/new) and describe
2. Is it an issue with the Minetest *engine*? If not, report it
[elsewhere](http://www.minetest.net/development/#reporting-issues).
3. [Open an issue](https://github.com/minetest/minetest/issues/new) and describe
the issue you are having - you could include:
- Error logs (check the bottom of the `debug.txt` file).
- Screenshots.
@ -106,21 +106,21 @@ the project page with a list of current languages
Builtin (the component which contains things like server messages, chat command
descriptions, privilege descriptions) is translated separately; it needs to be
translated by editing a `.tr` text file. See
[Translation](https://dev.luanti.org/Translation) for more information.
[Translation](https://dev.minetest.net/Translation) for more information.
## Donations
If you'd like to monetarily support Luanti development, you can find donation
methods on [our website](http://www.luanti.org/development/#donate).
methods on [our website](http://www.minetest.net/development/#donate).
# Maintaining
* This is a concise version of the
[Rules & Guidelines](https://dev.luanti.org/engine-dev-process/) on the developer wiki.*
[Rules & Guidelines](http://dev.minetest.net/Category:Rules_and_Guidelines) on the developer wiki.*
These notes are for those who have push access Luanti (core developers / maintainers).
- See the [project organisation](https://dev.luanti.org/Organisation) for the people involved.
- See the [project organisation](http://dev.minetest.net/Organisation) for the people involved.
## Concept approvals and roadmaps
@ -159,14 +159,14 @@ Submit a :+1: (+1) or "Looks good" comment to show you believe the pull-request
- The title should follow the commit guidelines (title starts with a capital letter, present tense, descriptive).
- Don't modify history older than 10 minutes.
- Use rebase, not merge to get linear history:
- `curl -Ls https://github.com/luanti-org/luanti/pull/1.patch | git am`
- `curl https://github.com/minetest/minetest/pull/1.patch | git am`
## Reviewing issues and feature requests
- If an issue does not get a response from its author within 1 month (when requiring more details), it can be closed.
- When an issue is a duplicate, refer to the first ones and close the later ones.
- Tag issues with the appropriate [labels](https://github.com/luanti-org/luanti/labels) for devices, platforms etc.
- Tag issues with the appropriate [labels](https://github.com/minetest/minetest/labels) for devices, platforms etc.
## Releasing a new version
*Refer to [dev.luanti.org/Releasing_Luanti](https://dev.luanti.org/Releasing_Luanti)*
*Refer to [dev.minetest.net/Releasing_Luanti](https://dev.minetest.net/Releasing_Luanti)*

View file

@ -6,10 +6,9 @@ body:
attributes:
value: |
Please note the following:
1. **Please update Luanti to the latest stable or dev version** before submitting bug reports. Make sure the bug is still reproducible on the latest version.
2. This page is for reporting the bugs of **the engine itself**. For bugs in a particular game, please [search for the game in the ContentDB](https://content.luanti.org/packages/?type=game) and submit a bug report in their issue trackers.
* For example, you can submit issues about the Minetest Game [in its own repository](https://github.com/luanti-org/minetest_game/issues).
2. This page is for reporting the bugs of **the engine itself**. For bugs in a particular game, please [search for the game in the ContentDB](https://content.minetest.net/packages/?type=game) and submit a bug report in their issue trackers.
* For example, you can submit issues about the Minetest Game [in its own repository](https://github.com/minetest/minetest_game/issues).
3. Please provide as many details as possible for us to spot the problem quicker.
- type: textarea
attributes:
@ -34,6 +33,13 @@ body:
render: "true"
validations:
required: true
- type: input
attributes:
label: Irrlicht device
description:
placeholder: "Example: X11"
validations:
required: false
- type: input
attributes:
label: Operating system and version
@ -62,7 +68,7 @@ body:
attributes:
label: Active renderer
description: You can find this in the "About" tab in the main menu.
placeholder: "Example: ES 3.2 / ogles2 / X11"
placeholder: "Example: OpenGL 4.6.0"
validations:
required: false
- type: textarea

View file

@ -1,8 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Submit issues about Minetest Game
url: https://github.com/luanti-org/minetest_game/issues/new
url: https://github.com/minetest/minetest_game/issues/new/choose
about: Only submit issues of the engine in this repository's issue tracker. Submit those of Minetest Game in its own issue tracker.
- name: Search for issue trackers of third-party games
url: https://content.luanti.org/packages/?type=game
url: https://content.minetest.net/packages/?type=game
about: For issues of third-party games, search for the game in the ContentDB and then submit an issue in their issue tracker.

View file

@ -7,7 +7,7 @@ body:
value: |
Please note the following:
1. Only submit a feature request if the feature does not exist on the latest dev version.
2. This page is for suggesting changes to **the engine itself**. To suggest changes to games, please [search for the game in the ContentDB](https://content.luanti.org/packages/?type=game) and submit a feature request in their issue trackers.
2. This page is for suggesting changes to **the engine itself**. To suggest changes to games, please [search for the game in the ContentDB](https://content.minetest.net/packages/?type=game) and submit a feature request in their issue trackers.
- type: textarea
attributes:
label: Problem

View file

@ -3,7 +3,7 @@ Add compact, short information about your PR for easier understanding:
- Goal of the PR
- How does the PR work?
- Does it resolve any reported issue?
- Does this relate to a goal in [the roadmap](https://github.com/luanti-org/luanti/blob/master/doc/direction.md)?
- Does this relate to a goal in [the roadmap](https://github.com/minetest/minetest/blob/master/doc/direction.md)?
- If not a bug fix, why is this PR needed? What usecases does it solve?
## To do

4
.github/SECURITY.md vendored
View file

@ -3,7 +3,7 @@
## Supported Versions
We only support the latest stable version for security issues.
See the [releases page](https://github.com/luanti-org/luanti/releases).
See the [releases page](https://github.com/minetest/minetest/releases).
## Reporting a Vulnerability
@ -11,7 +11,7 @@ We ask that you report vulnerabilities privately, by contacting a core developer
to give us time to fix them. You can do that by emailing one of the following addresses:
* celeron55@gmail.com
* rw@rubenwardy.com
* rubenwardy@minetest.net
Depending on severity, we will either create a private issue for the vulnerability
and release a patch version of Luanti, or give you permission to file the issue publicly.

View file

@ -12,7 +12,6 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'android/**'
- '.github/workflows/android.yml'
pull_request:
@ -25,7 +24,6 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'android/**'
- '.github/workflows/android.yml'

View file

@ -12,8 +12,9 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'util/ci/**'
- 'Dockerfile'
- '.dockerignore'
- '.github/workflows/linux.yml'
pull_request:
paths:
@ -25,8 +26,9 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'util/ci/**'
- 'Dockerfile'
- '.dockerignore'
- '.github/workflows/linux.yml'
env:
@ -49,8 +51,6 @@ jobs:
env:
CC: gcc-7
CXX: g++-7
# Test fallback SHA implementations
CMAKE_FLAGS: '-DENABLE_OPENSSL=0'
- name: Test
run: |

View file

@ -16,7 +16,7 @@ on:
jobs:
build:
if: github.repository == 'luanti-org/luanti'
if: github.repository == 'minetest/minetest'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

View file

@ -13,7 +13,6 @@ on:
- 'irr/**.mm' # Objective-C(++)
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- '.github/workflows/macos.yml'
pull_request:
paths:
@ -26,11 +25,10 @@ on:
- 'irr/**.mm' # Objective-C(++)
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- '.github/workflows/macos.yml'
jobs:
build-intel-macos:
build:
# use lowest possible macOS running on x86_64 supported by brew to support more users
runs-on: macos-13
steps:
@ -70,44 +68,3 @@ jobs:
with:
name: luanti-macos
path: ./build/macos/*.zip
build-arm-macos-xcode:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
source ./util/ci/common.sh
install_macos_deps
# brew jsoncpp do not include libjsoncpp.a, and if installed header conflict caused build failure
brew uninstall jsoncpp
- name: Build with Cmake
run: |
mkdir build
cd build
cmake .. \
-DCMAKE_OSX_DEPLOYMENT_TARGET=14 \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DCMAKE_INSTALL_PREFIX=../build/macos/ \
-DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE \
-DENABLE_SYSTEM_JSONCPP=OFF
cmake --build . -j$(sysctl -n hw.logicalcpu)
make install
- name: Build and Archive with Xcode
run: |
mkdir build_xcode
cd build_xcode
../util/ci/build_xcode.sh
- name: Tests
run: |
mkdir -p "${HOME}/Library/Application Support/minetest/games/"
ln -s "${PWD}/games/devtest" "${HOME}/Library/Application Support/minetest/games/"
./build/macos/luanti.app/Contents/MacOS/luanti --run-unittests
./build_xcode/luanti.xcarchive/Products/Applications/luanti.app/Contents/MacOS/luanti --run-unittests
- name: Diff Resources
run: |
diff -rd ./build/macos/luanti.app/Contents/Resources ./build_xcode/build/Release/luanti.app/Contents/Resources || exit 1
diff -rd ./build/macos/luanti.app/Contents/Resources ./build_xcode/luanti.xcarchive/Products/Applications/luanti.app/Contents/Resources || exit 1

View file

@ -1,26 +0,0 @@
name: png_file_checks
# Check whether all png files are in a valid format
on:
push:
paths:
- '**.png'
- '.github/workflows/**.yml'
pull_request:
paths:
- '**.png'
- '.github/workflows/**.yml'
jobs:
png_optimized:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt install -y optipng
- name: Check whether all png files are optimized
run: |
./util/ci/check_png_optimized.sh

View file

@ -14,7 +14,6 @@ on:
- '**.sh'
- '**.cmake'
- '**.glsl'
- '**.lua'
pull_request:
paths:
- '**.txt'
@ -25,7 +24,6 @@ on:
- '**.sh'
- '**.cmake'
- '**.glsl'
- '**.lua'
jobs:
trailing_whitespaces:
@ -34,72 +32,7 @@ jobs:
- uses: actions/checkout@v4
# Line endings are already ensured by .gitattributes
- name: Check trailing whitespaces
run: |
if git ls-files |\
grep -E '\.txt$|\.md$|\.[ch]$|\.cpp$|\.hpp$|\.sh$|\.cmake$|\.glsl$' |\
xargs grep -n '\s$';\
then\
echo -e "\033[0;31mFound trailing whitespace";\
(exit 1);\
else\
(exit 0);\
fi
indent_spaces:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Line endings are already ensured by .gitattributes
# Multiple multline comments in one line is not supported by this check
# and there is no reason to use them
# So lines like: "/* */ /*" or "*/ a = 5; /*" will result in error
- name: Check for unsupported multiline comments
run: |
if git ls-files |\
grep -E '^src/.*\.cpp$|^src/.*\.[ch]$' |\
xargs grep -n '\*/.*/\*';\
then
echo -e "\033[0;31mUnsupported combination of multiline comments. New multiline comment should begin on new line.";\
(exit 1);\
else\
(exit 0);\
fi
if git ls-files |\
grep -E '\.lua$' |\
xargs grep -n -e '\]\].*--\[\[';\
then
echo -e "\033[0;31mUnsupported combination of multiline comments. New multiline comment should begin on new line.";\
(exit 1);\
else\
(exit 0);\
fi
# This prepare files for final check
# See python script ./util/ci/indent_tab_preprocess.py for details.
- name: Preprocess files
run: |
git ls-files |\
grep -E '^src/.*\.cpp$|^src/.*\.[ch]$' |\
xargs -L 1 -P $(($(nproc) + 1)) \
python3 ./util/ci/indent_tab_preprocess.py "/*" "*/"
git ls-files |\
grep -E '\.lua$' |\
xargs -L 1 -P $(($(nproc) + 1)) \
python3 ./util/ci/indent_tab_preprocess.py "--[[" "]]"
# Check for bad indent.
# This runs over preprocessed files.
# If there is any remaining space on line beginning or after tab,
# error is generated
- name: Check indent spaces
run: |
if git ls-files |\
grep -E '^src/.*\.cpp$|^src/.*\.[ch]$|\.lua' |\
xargs grep -n -P '^\t*[ ]';\
then\
echo -e "\033[0;31mFound incorrect indent whitespaces";\
(exit 1);\
else\
(exit 0);\
fi
run: if git ls-files | grep -E '\.txt$|\.md$|\.[ch]$|\.cpp$|\.hpp$|\.sh$|\.cmake$|\.glsl$' | xargs grep -n '\s$'; then echo -e "\033[0;31mFound trailing whitespace"; (exit 1); else (exit 0); fi
tabs_lua_api_files:
runs-on: ubuntu-latest
@ -107,12 +40,6 @@ jobs:
- uses: actions/checkout@v4
# Some files should not contain tabs
- name: Check tabs in Lua API files
run: |
if grep -n $'\t' doc/lua_api.md doc/client_lua_api.md;\
then\
echo -e "\033[0;31mFound tab in markdown file";\
(exit 1);\
else\
(exit 0);\
fi
run: if grep -n $'\t' doc/lua_api.md doc/client_lua_api.md; then echo -e "\033[0;31mFound tab in markdown file"; (exit 1); else (exit 0); fi

View file

@ -12,7 +12,6 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'util/buildbot/**'
- 'misc/*.manifest'
- '.github/workflows/windows.yml'
@ -26,7 +25,6 @@ on:
- 'irr/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'po/**.po'
- 'util/buildbot/**'
- 'misc/*.manifest'
- '.github/workflows/windows.yml'
@ -73,7 +71,7 @@ jobs:
env:
VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94
# 2024.05.24
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp sdl2
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry
strategy:
fail-fast: false
matrix:

6
.gitignore vendored
View file

@ -49,13 +49,13 @@ AppDir
# Nix
/result
## Files related to Luanti development cycle
## Files related to Minetest development cycle
/*.patch
*.diff
# GNU Patch reject file
*.rej
## Non-static Luanti directories or symlinks to these
## Non-static Minetest directories or symlinks to these
/bin/
/games/*
!/games/devtest/
@ -80,7 +80,7 @@ minetest.conf
debug.txt
debug.txt.1
## Other files generated by Luanti
## Other files generated by Minetest
screenshot_*.png
testbm.txt

View file

@ -10,13 +10,11 @@ ignore = {
read_globals = {
"ItemStack",
"INIT",
"PLATFORM",
"DIR_DELIM",
"dump", "dump2",
"fgettext", "fgettext_ne",
"vector",
"VoxelArea",
"VoxelManip",
"profiler",
"Settings",
"PerlinNoise", "PerlinNoiseMap",
@ -76,6 +74,10 @@ files["builtin/mainmenu"] = {
globals = {
"gamedata",
},
read_globals = {
"PLATFORM",
},
}
files["builtin/common/tests"] = {

View file

@ -11,7 +11,7 @@ set(CLANG_MINIMUM_VERSION "7.0.1")
# You should not need to edit these manually, use util/bump_version.sh
set(VERSION_MAJOR 5)
set(VERSION_MINOR 12)
set(VERSION_MINOR 10)
set(VERSION_PATCH 0)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
@ -48,7 +48,7 @@ endif()
# - win32/gcc: fails to link
# - win32/clang: works
# - macOS on x86: seems to be fine
# - macOS on ARM: crashes, see <https://github.com/luanti-org/luanti/issues/14397>
# - macOS on ARM: crashes, see <https://github.com/minetest/minetest/issues/14397>
# Note: since CMake has no easy architecture detection disabling for Mac entirely
#### ####
if((WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR APPLE)
@ -272,16 +272,12 @@ endif()
if(APPLE)
install(FILES "misc/luanti-icon.icns" DESTINATION "${SHAREDIR}")
install(FILES "${CMAKE_BINARY_DIR}/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents")
endif()
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(client_RESOURCES "${CMAKE_SOURCE_DIR}/misc/luanti-icon.icns")
install(FILES "misc/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents")
endif()
# Library pack
find_package(GMP REQUIRED)
find_package(Json 1.0.0 REQUIRED)
find_package(Json REQUIRED)
find_package(Lua REQUIRED)
if(NOT USE_LUAJIT)
add_subdirectory(lib/bitop)

2
CNAME
View file

@ -1 +1 @@
api.luanti.org
api.minetest.net

View file

@ -14,9 +14,6 @@ https://www.apache.org/licenses/LICENSE-2.0.html
Textures by Zughy are under CC BY-SA 4.0
https://creativecommons.org/licenses/by-sa/4.0/
Textures by cx384 are under CC BY-SA 4.0
https://creativecommons.org/licenses/by-sa/4.0/
Media files by DS are under CC BY-SA 4.0
https://creativecommons.org/licenses/by-sa/4.0/
@ -66,14 +63,6 @@ Zughy:
textures/base/pack/settings_btn.png
textures/base/pack/settings_info.png
textures/base/pack/settings_reset.png
textures/base/pack/server_url.png
textures/base/pack/server_url_unavailable.png
textures/base/pack/server_view_clients.png
textures/base/pack/server_view_clients_unavailable.png
cx384:
textures/base/pack/server_view_mods.png
textures/base/pack/server_view_mods_unavailable.png
appgurueu:
textures/base/pack/server_incompatible.png

View file

@ -1,15 +1,13 @@
<div align="center">
<img src="textures/base/pack/logo.png" width="32%">
<h1>Luanti (formerly Minetest)</h1>
<img src="https://github.com/luanti-org/luanti/workflows/build/badge.svg" alt="Build Status">
<a href="https://hosted.weblate.org/engage/minetest/?utm_source=widget"><img src="https://hosted.weblate.org/widgets/minetest/-/svg-badge.svg" alt="Translation status"></a>
<a href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html"><img src="https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg" alt="License"></a>
</div>
<br><br>
Luanti (formerly Minetest)
==========================
![Build Status](https://github.com/minetest/minetest/workflows/build/badge.svg)
[![Translation status](https://hosted.weblate.org/widgets/minetest/-/svg-badge.svg)](https://hosted.weblate.org/engage/minetest/?utm_source=widget)
[![License](https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg)](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
Luanti is a free open-source voxel game engine with easy modding and game creation.
Copyright (C) 2010-2025 Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2024 Perttu Ahola <celeron55@gmail.com>
and contributors (see source file comments and the version control log)
Table of Contents
@ -27,10 +25,10 @@ Table of Contents
Further documentation
----------------------
- Website: https://www.luanti.org/
- Wiki: https://wiki.luanti.org/
- Forum: https://forum.luanti.org/
- GitHub: https://github.com/luanti-org/luanti/
- Website: https://www.minetest.net/
- Wiki: https://wiki.minetest.net/
- Forum: https://forum.minetest.net/
- GitHub: https://github.com/minetest/minetest/
- [Developer documentation](doc/developing/)
- [doc/](doc/) directory of source distribution

View file

@ -1,4 +1,5 @@
diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
index fd5a056e3..83e3cf657 100644
--- a/android/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -1345,7 +1345,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
@ -8,7 +9,7 @@ diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android
- if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
+ if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
+ /*
+ * CUSTOM ADDITION FOR LUANTI
+ * CUSTOM ADDITION FOR MINETEST
+ * should be upstreamed
+ */
+ (source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {

View file

@ -60,8 +60,8 @@ import java.util.Locale;
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 0;
private static final int SDL_MINOR_VERSION = 30;
private static final int SDL_MICRO_VERSION = 8;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@ -790,9 +790,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
SDLActivity.mFullscreenModeActive = false;
}
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
}
} else {
Log.e(TAG, "error handling message, getContext() returned no Activity");
@ -1350,7 +1347,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
/*
* CUSTOM ADDITION FOR LUANTI
* CUSTOM ADDITION FOR MINETEST
* should be upstreamed
*/
(source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="unzip_notification_description">Menos de 1 minuto…</string>
<string name="ime_dialog_done">Hecho</string>
<string name="no_web_browser">No se encontró ningún navegador web</string>
<string name="loading">Cargando…</string>
<string name="notification_channel_name">Notificación General</string>
<string name="label">Luanti</string>
<string name="notification_channel_description">Notificaciones de Luanti</string>
<string name="unzip_notification_title">Cargando Luanti</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="no_web_browser">No se encontró ningún navegador web</string>
<string name="loading">Cargando…</string>
<string name="notification_channel_description">Notificaciones de Luanti</string>
<string name="unzip_notification_description">Menos de 1 minuto…</string>
<string name="ime_dialog_done">Hecho</string>
<string name="label">Luanti</string>
<string name="unzip_notification_title">Cargando Luanti</string>
<string name="notification_channel_name">Notificación General</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="unzip_notification_description">کمتر از 1 دقیقه…</string>
<string name="loading">در حال بارگذاری…</string>
<string name="ime_dialog_done">انجام شد</string>
<string name="label">لوآنتی</string>
<string name="unzip_notification_title">در حال بارگذاری لوآنتی</string>
<string name="notification_channel_name">نوتیفیکیشن عمومی</string>
<string name="notification_channel_description">نوتیفیکیشن از لوآنتی</string>
<string name="no_web_browser">هیچ مرورگری یافت نشد</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Luanti</string>
<string name="loading">Chargement…</string>
<string name="notification_channel_name">Notification générale</string>
<string name="notification_channel_description">Notifications de Luanti</string>
<string name="unzip_notification_title">Chargement de Luanti</string>
<string name="unzip_notification_description">Moins d\'une minute…</string>
<string name="ime_dialog_done">Terminé</string>
<string name="no_web_browser">Aucun navigateur web trouvé</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Luanti</string>
<string name="loading">Cargando…</string>
<string name="notification_channel_name">Notificación xeral</string>
<string name="notification_channel_description">Notificacións de Luanti</string>
<string name="unzip_notification_title">Cargando Luanti</string>
<string name="unzip_notification_description">Menos de 1 minuto…</string>
<string name="ime_dialog_done">Feito</string>
<string name="no_web_browser">Non se atopou ningún navegador web</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="unzip_notification_title">Загрузка Luanti</string>
<string name="unzip_notification_description">Меньше чам за 1 минуту…</string>
<string name="ime_dialog_done">Готово</string>
<string name="label">Luаnti</string>
<string name="notification_channel_description">Уведомления от Luanti</string>
<string name="notification_channel_name">Основные уведомления</string>
<string name="loading">Загрузка…</string>
<string name="no_web_browser">Не найдено веб-браузера</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Luanti</string>
<string name="loading">Laddar…</string>
<string name="unzip_notification_description">Mindre än 1 minut…</string>
<string name="ime_dialog_done">Färdig</string>
<string name="no_web_browser">Ingen webbläsare kunde hittas</string>
<string name="notification_channel_name">Generell notis</string>
<string name="notification_channel_description">Notiser från Luanti</string>
<string name="unzip_notification_title">Laddar Luanti</string>
</resources>

View file

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Luanti</string>
<string name="no_web_browser">Браузерів не знайдено</string>
<string name="loading">Завантаження…</string>
<string name="notification_channel_name">Загальні сповіщення</string>
<string name="unzip_notification_title">Luanti завантажується</string>
<string name="unzip_notification_description">Менше за 1 хвилину…</string>
<string name="ime_dialog_done">Готово</string>
<string name="notification_channel_description">Сповіщення від Luanti</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Luanti</string>
<string name="loading">加载中…</string>
<string name="notification_channel_name">一般通知</string>
<string name="notification_channel_description">Luanti 的通知</string>
<string name="unzip_notification_title">加载 Luanti 中</string>
<string name="unzip_notification_description">不到1分钟…</string>
<string name="ime_dialog_done">完成</string>
<string name="no_web_browser">未找到网页浏览器</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="loading">載入中…</string>
<string name="notification_channel_name">一般通知</string>
<string name="notification_channel_description">Luanti 的通知</string>
<string name="unzip_notification_description">不到1分鐘…</string>
<string name="ime_dialog_done">完畢</string>
<string name="no_web_browser">未找到任何網頁瀏覽器</string>
<string name="label">Luanti</string>
<string name="unzip_notification_title">載入Luanti中</string>
</resources>

View file

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext.set("versionMajor", 5) // Version Major
project.ext.set("versionMinor", 12) // Version Minor
project.ext.set("versionMinor", 10) // Version Minor
project.ext.set("versionPatch", 0) // Version Patch
// ^ keep in sync with cmake

View file

@ -52,7 +52,7 @@ if (new File(depsDir, 'armeabi-v7a').exists()) {
task downloadDeps(type: Download) {
def depsZip = new File(buildDir, 'deps.zip')
src 'https://github.com/luanti-org/luanti_android_deps/releases/download/latest/deps-lite.zip'
src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps-lite.zip'
dest depsZip
overwrite false

View file

@ -2,10 +2,7 @@ local scriptpath = core.get_builtin_path()
local clientpath = scriptpath.."client"..DIR_DELIM
local commonpath = scriptpath.."common"..DIR_DELIM
local builtin_shared = {}
assert(loadfile(commonpath .. "register.lua"))(builtin_shared)
assert(loadfile(clientpath .. "register.lua"))(builtin_shared)
dofile(clientpath .. "register.lua")
dofile(commonpath .. "after.lua")
dofile(commonpath .. "mod_storage.lua")
dofile(commonpath .. "chatcommands.lua")

View file

@ -1,6 +1,68 @@
local builtin_shared = ...
core.callback_origins = {}
local make_registration = builtin_shared.make_registration
local getinfo = debug.getinfo
debug.getinfo = nil
--- Runs given callbacks.
--
-- Note: this function is also called from C++
-- @tparam table callbacks a table with registered callbacks, like `core.registered_on_*`
-- @tparam number mode a RunCallbacksMode, as defined in src/script/common/c_internal.h
-- @param ... arguments for the callback
-- @return depends on mode
function core.run_callbacks(callbacks, mode, ...)
assert(type(callbacks) == "table")
local cb_len = #callbacks
if cb_len == 0 then
if mode == 2 or mode == 3 then
return true
elseif mode == 4 or mode == 5 then
return false
end
end
local ret
for i = 1, cb_len do
local cb_ret = callbacks[i](...)
if mode == 0 and i == 1 or mode == 1 and i == cb_len then
ret = cb_ret
elseif mode == 2 then
if not cb_ret or i == 1 then
ret = cb_ret
end
elseif mode == 3 then
if cb_ret then
return cb_ret
end
ret = cb_ret
elseif mode == 4 then
if (cb_ret and not ret) or i == 1 then
ret = cb_ret
end
elseif mode == 5 and cb_ret then
return cb_ret
end
end
return ret
end
--
-- Callback registration
--
local function make_registration()
local t = {}
local registerfunc = function(func)
t[#t + 1] = func
core.callback_origins[func] = {
mod = core.get_current_modname() or "??",
name = getinfo(1, "n").name or "??"
}
--local origin = core.callback_origins[func]
--print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
end
return t, registerfunc
end
core.registered_globalsteps, core.register_globalstep = make_registration()
core.registered_on_mods_loaded, core.register_on_mods_loaded = make_registration()

View file

@ -90,7 +90,7 @@ local facedir_to_dir_map = {
1, 4, 3, 2,
}
function core.facedir_to_dir(facedir)
return vector.copy(facedir_to_dir[facedir_to_dir_map[facedir % 32]])
return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
end
function core.dir_to_fourdir(dir)
@ -110,7 +110,7 @@ function core.dir_to_fourdir(dir)
end
function core.fourdir_to_dir(fourdir)
return vector.copy(facedir_to_dir[facedir_to_dir_map[fourdir % 4]])
return facedir_to_dir[facedir_to_dir_map[fourdir % 4]]
end
function core.dir_to_wallmounted(dir)
@ -147,7 +147,7 @@ local wallmounted_to_dir = {
vector.new( 0, -1, 0),
}
function core.wallmounted_to_dir(wallmounted)
return vector.copy(wallmounted_to_dir[wallmounted % 8])
return wallmounted_to_dir[wallmounted % 8]
end
function core.dir_to_yaw(dir)

View file

@ -54,8 +54,7 @@ function builtin_shared.make_registration()
local registerfunc = function(func)
t[#t + 1] = func
core.callback_origins[func] = {
-- may be nil or return nil
mod = core.get_current_modname and core.get_current_modname() or "??",
mod = core.get_current_modname() or "??",
name = debug.getinfo(1, "n").name or "??"
}
end
@ -67,8 +66,7 @@ function builtin_shared.make_registration_reverse()
local registerfunc = function(func)
table.insert(t, 1, func)
core.callback_origins[func] = {
-- may be nil or return nil
mod = core.get_current_modname and core.get_current_modname() or "??",
mod = core.get_current_modname() or "??",
name = debug.getinfo(1, "n").name or "??"
}
end

View file

@ -389,7 +389,7 @@ function vector.random_direction()
local x, y, z, l2
repeat -- expected less than two attempts on average (volume sphere vs. cube)
x, y, z = math.random() * 2 - 1, math.random() * 2 - 1, math.random() * 2 - 1
l2 = x*x + y*y + z*z
l2 = x*x + y*y + z*z
until l2 <= 1 and l2 >= 1e-6
-- normalize
local l = math.sqrt(l2)

View file

@ -38,7 +38,7 @@ local function buttonbar_formspec(self)
-- `BASE_SPACING` is used as the minimum spacing, like `gap` in CSS Flexbox.
-- The number of buttons per page is always calculated as if the scroll
-- buttons were visible.
-- buttons were visible.
local avail_space = self.size.x - 2*BASE_SPACING - 2*get_scroll_btn_width()
local btns_per_page = math.floor((avail_space - BASE_SPACING) / (btn_size + BASE_SPACING))

View file

@ -1,4 +1,5 @@
local builtin_shared = ...
local SCALE = 0.667
local facedir_to_euler = {
{y = 0, x = 0, z = 0},
@ -35,7 +36,9 @@ local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
core.register_entity(":__builtin:falling_node", {
initial_properties = {
visual = "node",
visual = "item",
visual_size = vector.new(SCALE, SCALE, SCALE),
textures = {},
physical = true,
is_visible = false,
collide_with_objects = true,
@ -75,17 +78,43 @@ core.register_entity(":__builtin:falling_node", {
self.floats = core.get_item_group(node.name, "float") ~= 0
-- Save liquidtype for falling water
self.liquidtype = def.liquidtype
self.liquidtype = def.liquidtype
-- Set up entity visuals
-- For compatibility with older clients we continue to use "item" visual
-- for simple situations.
local drawtypes = {normal=true, glasslike=true, allfaces=true, nodebox=true}
local p2types = {none=true, facedir=true, ["4dir"]=true}
if drawtypes[def.drawtype] and p2types[def.paramtype2] and def.use_texture_alpha ~= "blend" then
-- Set entity visuals
if def.drawtype == "torchlike" or def.drawtype == "signlike" then
local textures
if def.tiles and def.tiles[1] then
local tile = def.tiles[1]
if type(tile) == "table" then
tile = tile.name
end
if def.drawtype == "torchlike" then
textures = { "("..tile..")^[transformFX", tile }
else
textures = { tile, "("..tile..")^[transformFX" }
end
end
local vsize
if def.visual_scale then
local s = def.visual_scale
vsize = vector.new(s, s, s)
end
self.object:set_properties({
is_visible = true,
visual = "upright_sprite",
visual_size = vsize,
textures = textures,
glow = def.light_source,
})
elseif def.drawtype ~= "airlike" then
local itemstring = node.name
if core.is_colored_paramtype(def.paramtype2) then
itemstring = core.itemstring_with_palette(itemstring, node.param2)
end
-- FIXME: solution needed for paramtype2 == "leveled"
-- Calculate size of falling node
local s = vector.zero()
s.x = (def.visual_scale or 1) * 0.667
local s = {}
s.x = (def.visual_scale or 1) * SCALE
s.y = s.x
s.z = s.x
-- Compensate for wield_scale
@ -96,31 +125,10 @@ core.register_entity(":__builtin:falling_node", {
end
self.object:set_properties({
is_visible = true,
visual = "item",
wield_item = node.name,
wield_item = itemstring,
visual_size = s,
glow = def.light_source,
})
-- Rotate as needed
if def.paramtype2 == "facedir" then
local fdir = node.param2 % 32 % 24
local euler = facedir_to_euler[fdir + 1]
if euler then
self.object:set_rotation(euler)
end
elseif def.paramtype2 == "4dir" then
local fdir = node.param2 % 4
local euler = facedir_to_euler[fdir + 1]
if euler then
self.object:set_rotation(euler)
end
end
elseif def.drawtype ~= "airlike" then
self.object:set_properties({
is_visible = true,
node = node,
glow = def.light_source,
})
end
-- Set collision box (certain nodeboxes only for now)
@ -140,6 +148,111 @@ core.register_entity(":__builtin:falling_node", {
})
end
end
-- Rotate entity
if def.drawtype == "torchlike" then
if (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted")
and node.param2 % 8 == 7 then
self.object:set_yaw(-math.pi*0.25)
else
self.object:set_yaw(math.pi*0.25)
end
elseif ((node.param2 ~= 0 or def.drawtype == "nodebox" or def.drawtype == "mesh")
and (def.wield_image == "" or def.wield_image == nil))
or def.drawtype == "signlike"
or def.drawtype == "mesh"
or def.drawtype == "normal"
or def.drawtype == "nodebox" then
if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then
local fdir = node.param2 % 32 % 24
-- Get rotation from a precalculated lookup table
local euler = facedir_to_euler[fdir + 1]
if euler then
self.object:set_rotation(euler)
end
elseif (def.paramtype2 == "4dir" or def.paramtype2 == "color4dir") then
local fdir = node.param2 % 4
-- Get rotation from a precalculated lookup table
local euler = facedir_to_euler[fdir + 1]
if euler then
self.object:set_rotation(euler)
end
elseif (def.drawtype ~= "plantlike" and def.drawtype ~= "plantlike_rooted" and
(def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike")) then
local rot = node.param2 % 8
if (def.drawtype == "signlike" and def.paramtype2 ~= "wallmounted" and def.paramtype2 ~= "colorwallmounted") then
-- Change rotation to "floor" by default for non-wallmounted paramtype2
rot = 1
end
local pitch, yaw, roll = 0, 0, 0
if def.drawtype == "nodebox" or def.drawtype == "mesh" then
if rot == 0 then
pitch, yaw = math.pi/2, 0
elseif rot == 1 then
pitch, yaw = -math.pi/2, math.pi
elseif rot == 2 then
pitch, yaw = 0, math.pi/2
elseif rot == 3 then
pitch, yaw = 0, -math.pi/2
elseif rot == 4 then
pitch, yaw = 0, math.pi
elseif rot == 6 then
pitch, yaw = math.pi/2, 0
elseif rot == 7 then
pitch, yaw = -math.pi/2, math.pi
end
else
if rot == 1 then
pitch, yaw = math.pi, math.pi
elseif rot == 2 then
pitch, yaw = math.pi/2, math.pi/2
elseif rot == 3 then
pitch, yaw = math.pi/2, -math.pi/2
elseif rot == 4 then
pitch, yaw = math.pi/2, math.pi
elseif rot == 5 then
pitch, yaw = math.pi/2, 0
elseif rot == 6 then
pitch, yaw = math.pi, -math.pi/2
elseif rot == 7 then
pitch, yaw = 0, -math.pi/2
end
end
if def.drawtype == "signlike" then
pitch = pitch - math.pi/2
if rot == 0 then
yaw = yaw + math.pi/2
elseif rot == 1 then
yaw = yaw - math.pi/2
elseif rot == 6 then
yaw = yaw - math.pi/2
pitch = pitch + math.pi
elseif rot == 7 then
yaw = yaw + math.pi/2
pitch = pitch + math.pi
end
elseif def.drawtype == "mesh" or def.drawtype == "normal" or def.drawtype == "nodebox" then
if rot == 0 or rot == 1 then
roll = roll + math.pi
elseif rot == 6 or rot == 7 then
if def.drawtype ~= "normal" then
roll = roll - math.pi/2
end
else
yaw = yaw + math.pi
end
end
self.object:set_rotation({x=pitch, y=yaw, z=roll})
elseif (def.drawtype == "mesh" and def.paramtype2 == "degrotate") then
local p2 = (node.param2 - (def.place_param2 or 0)) % 240
local yaw = (p2 / 240) * (math.pi * 2)
self.object:set_yaw(yaw)
elseif (def.drawtype == "mesh" and def.paramtype2 == "colordegrotate") then
local p2 = (node.param2 % 32 - (def.place_param2 or 0) % 32) % 24
local yaw = (p2 / 24) * (math.pi * 2)
self.object:set_yaw(yaw)
end
end
end,
get_staticdata = function(self)
@ -195,26 +308,23 @@ core.register_entity(":__builtin:falling_node", {
core.remove_node(bcp)
else
-- We are placing on top so check what's there
np.y = np.y + 1
end
local n2 = core.get_node(np)
local nd = core.registered_nodes[n2.name]
if not nd or nd.buildable_to then
core.remove_node(np)
else
-- 'walkable' is used to mean "falling nodes can't replace this"
-- here. Normally we would collide with the walkable node itself
-- and place our node on top (so `n2.name == "air"`), but we
-- re-check this in case we ended up inside a node.
if not nd.diggable or nd.walkable then
return false
end
-- Check what's here
local n2 = core.get_node(np)
local nd = core.registered_nodes[n2.name]
-- If it's not air or liquid, remove node and replace it with
-- it's drops
if n2.name ~= "air" and (not nd or nd.liquidtype ~= "source") then
if nd and nd.buildable_to == false then
nd.on_dig(np, n2, nil)
-- If it's still there, it might be protected
if core.get_node(np).name == n2.name then
return false
end
else
core.remove_node(np)
end
end

View file

@ -43,9 +43,6 @@ core.features = {
hotbar_hud_element = true,
bulk_lbms = true,
abm_without_neighbors = true,
biome_weights = true,
particle_blend_clip = true,
remove_item_match_meta = true,
}
function core.has_feature(arg)

View file

@ -36,7 +36,11 @@ end
function core.setting_get_pos(name)
return core.settings:get_pos(name)
local value = core.settings:get(name)
if not value then
return nil
end
return core.string_to_pos(value)
end
@ -112,25 +116,3 @@ if core.set_push_moveresult1 then
end)
core.set_push_moveresult1 = nil
end
-- Protocol version table
-- see also src/network/networkprotocol.cpp
core.protocol_versions = {
["5.0.0"] = 37,
["5.1.0"] = 38,
["5.2.0"] = 39,
["5.3.0"] = 39,
["5.4.0"] = 39,
["5.5.0"] = 40,
["5.6.0"] = 41,
["5.7.0"] = 42,
["5.8.0"] = 43,
["5.9.0"] = 44,
["5.9.1"] = 45,
["5.10.0"] = 46,
["5.11.0"] = 47,
}
setmetatable(core.protocol_versions, {__newindex = function()
error("core.protocol_versions is read-only")
end})

View file

@ -1,7 +1,7 @@
local static_spawnpoint_string = core.settings:get("static_spawnpoint")
if static_spawnpoint_string and
static_spawnpoint_string ~= "" and
not core.settings:get_pos("static_spawnpoint") then
not core.setting_get_pos("static_spawnpoint") then
error('The static_spawnpoint setting is invalid: "' ..
static_spawnpoint_string .. '"')
end

View file

@ -78,8 +78,6 @@ elseif INIT == "client" then
dofile(scriptdir .. "client" .. DIR_DELIM .. "init.lua")
elseif INIT == "emerge" then
dofile(scriptdir .. "emerge" .. DIR_DELIM .. "init.lua")
elseif INIT == "pause_menu" then
dofile(scriptdir .. "pause_menu" .. DIR_DELIM .. "init.lua")
else
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
end

View file

@ -11,6 +11,11 @@ end
core.async_event_handler = handle_job
function core.handle_async(func, parameter, callback)
-- Serialize function
local serialized_func = string.dump(func)
assert(serialized_func ~= nil)
-- Serialize parameters
local serialized_param = core.serialize(parameter)
@ -18,7 +23,7 @@ function core.handle_async(func, parameter, callback)
return false
end
local jobid = core.do_async_callback(func, serialized_param)
local jobid = core.do_async_callback(serialized_func, serialized_param)
core.async_jobs[jobid] = callback

View file

@ -392,7 +392,7 @@ function contentdb.resolve_dependencies(package, game, callback)
end
local function fetch_pkgs()
local function fetch_pkgs(params)
local version = core.get_version()
local base_url = core.settings:get("contentdb_url")
local url = base_url ..
@ -429,43 +429,41 @@ local function fetch_pkgs()
if not packages or #packages == 0 then
return
end
return packages
end
function contentdb.set_packages_from_api(packages)
contentdb.package_by_id = {}
contentdb.aliases = {}
local aliases = {}
for _, package in pairs(packages) do
package.id = contentdb.calculate_package_id(package.type, package.author, package.name)
package.id = params.calculate_package_id(package.type, package.author, package.name)
package.url_part = core.urlencode(package.author) .. "/" .. core.urlencode(package.name)
contentdb.package_by_id[package.id] = package
if package.aliases then
for _, alias in ipairs(package.aliases) do
-- We currently don't support name changing
local suffix = "/" .. package.name
if alias:sub(-#suffix) == suffix then
contentdb.aliases[alias:lower()] = package.id
aliases[alias:lower()] = package.id
end
end
end
end
contentdb.load_ok = true
contentdb.load_error = false
contentdb.packages = packages
contentdb.packages_full = packages
contentdb.packages_full_unordered = packages
return { packages = packages, aliases = aliases }
end
function contentdb.fetch_pkgs(callback)
contentdb.loading = true
core.handle_async(fetch_pkgs, nil, function(result)
core.handle_async(fetch_pkgs, { calculate_package_id = contentdb.calculate_package_id }, function(result)
if result then
contentdb.set_packages_from_api(result)
contentdb.load_ok = true
contentdb.load_error = false
contentdb.packages = result.packages
contentdb.packages_full = result.packages
contentdb.packages_full_unordered = result.packages
contentdb.aliases = result.aliases
for _, package in ipairs(result.packages) do
contentdb.package_by_id[package.id] = package
end
else
contentdb.load_error = true
end
@ -565,32 +563,30 @@ function contentdb.filter_packages(query, by_type)
end
local keywords = {}
for word in query:gmatch("%S+") do
table.insert(keywords, word:lower())
end
local function contains_all_keywords(str)
str = str:lower()
for _, keyword in ipairs(keywords) do
if not str:find(keyword, 1, true) then
return false
end
end
return true
for word in query:lower():gmatch("%S+") do
table.insert(keywords, word)
end
local function matches_keywords(package)
return contains_all_keywords(package.name) or
contains_all_keywords(package.title) or
contains_all_keywords(package.author) or
contains_all_keywords(package.short_description)
for k = 1, #keywords do
local keyword = keywords[k]
if string.find(package.name:lower(), keyword, 1, true) or
string.find(package.title:lower(), keyword, 1, true) or
string.find(package.author:lower(), keyword, 1, true) or
string.find(package.short_description:lower(), keyword, 1, true) then
return true
end
end
return false
end
contentdb.packages = {}
for _, package in pairs(contentdb.packages_full) do
if (query == "" or matches_keywords(package)) and
(by_type == nil or package.type == by_type) then
table.insert(contentdb.packages, package)
contentdb.packages[#contentdb.packages + 1] = package
end
end
end

View file

@ -51,6 +51,10 @@ local function get_formspec(data)
return
end
if info.forums then
info.forums = "https://forum.minetest.net/viewtopic.php?t=" .. info.forums
end
assert(data.package.name == info.name)
data.info = info
ui.update()
@ -190,7 +194,7 @@ local function get_formspec(data)
add_link_button(fgettext("Source"), "repo")
add_link_button(fgettext("Issue Tracker"), "issue_tracker")
add_link_button(fgettext("Translate"), "translation_url")
add_link_button(fgettext("Forum Topic"), "forum_url")
add_link_button(fgettext("Forum Topic"), "forums")
hypertext = hypertext .. "\n\n" .. info.long_description.body

View file

@ -1,5 +1,5 @@
{
"#": "https://github.com/orgs/luanti-org/teams/engine/members",
"#": "https://github.com/orgs/minetest/teams/engine/members",
"core_developers": [
"Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]",
"sfan5 <sfan5@live.de>",
@ -13,10 +13,7 @@
"Desour/DS",
"srifqi",
"Gregor Parzefall (grorp)",
"Lars Müller (luatic)",
"cx384",
"sfence",
"y5nw"
"Lars Müller (luatic)"
],
"previous_core_developers": [
"BlockMen",
@ -39,7 +36,7 @@
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>"
],
"#": "Currently only https://github.com/orgs/luanti-org/teams/triagers/members",
"#": "Currently only https://github.com/orgs/minetest/teams/triagers/members",
"core_team": [
"Zughy [Issue triager]",
"wsor [Issue triager]",
@ -47,22 +44,30 @@
],
"#": "For updating active/previous contributors, see the script in ./util/gather_git_credits.py",
"contributors": [
"JosiahWI",
"Erich Schubert",
"wrrrzr",
"1F616EMO",
"red-001 <red-001@outlook.ie>",
"veprogames",
"paradust7",
"cx384",
"numzero",
"AFCMS",
"siliconsniffer",
"sfence",
"Wuzzy",
"Zemtzov7"
"ROllerozxa",
"JosiahWI",
"OgelGames",
"David Heidelberg",
"1F616EMO",
"HybridDog",
"Bradley Pierce (Thresher)",
"savilli",
"Stvk imension",
"y5nw",
"chmodsayshello",
"jordan4ibanez",
"superfloh247"
],
"previous_contributors": [
"Ælla Chiana Moskopp (erle) <erle@dieweltistgarnichtso.net> [Logo]",
"numzero",
"red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta",
"HybridDog",
"ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
@ -70,7 +75,6 @@
"MoNTE48",
"Constantin Wenger (SpeedProg)",
"Ciaran Gultnieks (CiaranG)",
"ROllerozxa",
"Paul Ouellette (pauloue)",
"stujones11",
"Rogier <rogier777@gmail.com>",

View file

@ -1,49 +0,0 @@
-- Luanti
-- Copyright (C) 2024 siliconsniffer
-- SPDX-License-Identifier: LGPL-2.1-or-later
local function clients_list_formspec(dialogdata)
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local clients_list = dialogdata.server.clients_list
local servername = dialogdata.server.name
local function fmt_formspec_list(clients_list)
local escaped = {}
for i, str in ipairs(clients_list) do
escaped[i] = core.formspec_escape(str)
end
return table.concat(escaped, ",")
end
local formspec = {
"formspec_version[8]",
"size[6,9.5]",
TOUCH_GUI and "padding[0.01,0.01]" or "",
"hypertext[0,0;6,1.5;;<global margin=5 halign=center valign=middle>",
fgettext("Players connected to\n$1",
"<b>" .. core.hypertext_escape(servername) .. "</b>") .. "]",
"textlist[0.5,1.5;5,6.8;;" .. fmt_formspec_list(clients_list) .. "]",
"button[1.5,8.5;3,0.8;quit;OK]"
}
return table.concat(formspec, "")
end
local function clients_list_buttonhandler(this, fields)
if fields.quit then
this:delete()
return true
end
return false
end
function create_clientslist_dialog(server)
local retval = dialog_create("dlg_clients_list",
clients_list_formspec,
clients_list_buttonhandler,
nil)
retval.data.server = server
return retval
end

View file

@ -299,7 +299,7 @@ local function handle_buttons(this, fields)
worldfile:set("load_mod_" .. mod.name, mod.virtual_path)
was_set[mod.name] = true
elseif not was_set[mod.name] then
worldfile:remove("load_mod_" .. mod.name)
worldfile:set("load_mod_" .. mod.name, "false")
end
elseif mod.enabled then
gamedata.errormessage = fgettext_ne("Failed to enable mo" ..

View file

@ -19,7 +19,7 @@
-- This whole file can be removed after a while.
-- It was only directly useful for upgrades from 5.7.0 to 5.8.0, but
-- maybe some odd fellow directly upgrades from 5.6.1 to 5.9.0 in the future...
-- see <https://github.com/luanti-org/luanti/pull/13850> in case it's not obvious
-- see <https://github.com/minetest/minetest/pull/13850> in case it's not obvious
---- ----
local SETTING_NAME = "no_mtg_notification"

View file

@ -1,105 +0,0 @@
-- Luanti
-- Copyright (C) 2024 cx384
-- SPDX-License-Identifier: LGPL-2.1-or-later
local function get_formspec(dialogdata)
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local server = dialogdata.server
local group_by_prefix = dialogdata.group_by_prefix
local expand_all = dialogdata.expand_all
-- A wrongly behaving server may send ill formed mod names
table.sort(server.mods)
local cells = {}
if group_by_prefix then
local function get_prefix(mod)
return mod:match("[^_]*")
end
local count = {}
for _, mod in ipairs(server.mods) do
local prefix = get_prefix(mod)
count[prefix] = (count[prefix] or 0) + 1
end
local last_prefix
local function add_row(depth, mod)
table.insert(cells, ("%d"):format(depth))
table.insert(cells, mod)
end
for i, mod in ipairs(server.mods) do
local prefix = get_prefix(mod)
if last_prefix == prefix then
add_row(1, mod)
elseif count[prefix] > 1 then
add_row(0, prefix)
add_row(1, mod)
else
add_row(0, mod)
end
last_prefix = prefix
end
else
cells = table.copy(server.mods)
end
for i, cell in ipairs(cells) do
cells[i] = core.formspec_escape(cell)
end
cells = table.concat(cells, ",")
local heading
if server.gameid then
heading = fgettext("The $1 server uses a game called $2 and the following mods:",
"<b>" .. core.hypertext_escape(server.name) .. "</b>",
"<style font=mono>" .. core.hypertext_escape(server.gameid) .. "</style>")
else
heading = fgettext("The $1 server uses the following mods:",
"<b>" .. core.hypertext_escape(server.name) .. "</b>")
end
local formspec = {
"formspec_version[8]",
"size[8,9.5]",
TOUCH_GUI and "padding[0.01,0.01]" or "",
"hypertext[0,0;8,1.5;;<global margin=5 halign=center valign=middle>", heading, "]",
"tablecolumns[", group_by_prefix and
(expand_all and "indent;text" or "tree;text") or "text", "]",
"table[0.5,1.5;7,6.8;mods;", cells, "]",
"checkbox[0.5,8.7;group_by_prefix;", fgettext("Group by prefix"), ";",
group_by_prefix and "true" or "false", "]",
group_by_prefix and ("checkbox[0.5,9.15;expand_all;" .. fgettext("Expand all") .. ";" ..
(expand_all and "true" or "false") .. "]") or "",
"button[5.5,8.5;2,0.8;quit;OK]"
}
return table.concat(formspec, "")
end
local function buttonhandler(this, fields)
if fields.quit then
this:delete()
return true
end
if fields.group_by_prefix then
this.data.group_by_prefix = core.is_yes(fields.group_by_prefix)
return true
end
if fields.expand_all then
this.data.expand_all = core.is_yes(fields.expand_all)
return true
end
return false
end
function create_server_list_mods_dialog(server)
local retval = dialog_create("dlg_server_list_mods",
get_formspec,
buttonhandler,
nil)
retval.data.group_by_prefix = false
retval.data.expand_all = false
retval.data.server = server
return retval
end

View file

@ -47,7 +47,7 @@ dofile(menupath .. DIR_DELIM .. "game_theme.lua")
dofile(menupath .. DIR_DELIM .. "content" .. DIR_DELIM .. "init.lua")
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
dofile(basepath .. "common" .. DIR_DELIM .. "settings" .. DIR_DELIM .. "init.lua")
dofile(menupath .. DIR_DELIM .. "settings" .. DIR_DELIM .. "init.lua")
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
@ -55,8 +55,6 @@ dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua")
dofile(menupath .. DIR_DELIM .. "dlg_reinstall_mtg.lua")
dofile(menupath .. DIR_DELIM .. "dlg_clients_list.lua")
dofile(menupath .. DIR_DELIM .. "dlg_server_list_mods.lua")
local tabs = {
content = dofile(menupath .. DIR_DELIM .. "tab_content.lua"),
@ -135,5 +133,4 @@ local function init_globals()
check_new_version()
end
assert(os.execute == nil)
init_globals()

View file

@ -98,7 +98,6 @@ local function make_field(converter, validator, stringifier)
local fs = ("field[0,0.3;%f,0.8;%s;%s;%s]"):format(
avail_w - 1.5, setting.name, get_label(setting), core.formspec_escape(value))
fs = fs .. ("field_enter_after_edit[%s;true]"):format(setting.name)
fs = fs .. ("field_close_on_enter[%s;false]"):format(setting.name) -- for pause menu env
fs = fs .. ("button[%f,0.3;1.5,0.8;%s;%s]"):format(avail_w - 1.5, "set_" .. setting.name, fgettext("Set"))
return fs, 1.1
@ -218,8 +217,6 @@ local function make_path(setting)
local fs = ("field[0,0.3;%f,0.8;%s;%s;%s]"):format(
avail_w - 3, setting.name, get_label(setting), core.formspec_escape(value))
fs = fs .. ("field_enter_after_edit[%s;true]"):format(setting.name)
fs = fs .. ("field_close_on_enter[%s;false]"):format(setting.name) -- for pause menu env
fs = fs .. ("button[%f,0.3;1.5,0.8;%s;%s]"):format(avail_w - 3, "pick_" .. setting.name, fgettext("Browse"))
fs = fs .. ("button[%f,0.3;1.5,0.8;%s;%s]"):format(avail_w - 1.5, "set_" .. setting.name, fgettext("Set"))
@ -252,11 +249,8 @@ local function make_path(setting)
}
end
if PLATFORM == "Android" or INIT == "pause_menu" then
if PLATFORM == "Android" then
-- The Irrlicht file picker doesn't work on Android.
-- Access to the Irrlicht file picker isn't implemented in the pause menu.
-- We want to delete the Irrlicht file picker anyway, so any time spent on
-- that would be wasted.
make.path = make.string
make.filepath = make.string
else
@ -288,14 +282,6 @@ function make.v3f(setting)
fs = fs .. ("field[%f,0.6;%f,0.8;%s;%s;%s]"):format(
2 * (field_width + 0.25), field_width, setting.name .. "_z", "Z", value.z)
fs = fs .. ("field_enter_after_edit[%s;true]"):format(setting.name .. "_x")
fs = fs .. ("field_enter_after_edit[%s;true]"):format(setting.name .. "_y")
fs = fs .. ("field_enter_after_edit[%s;true]"):format(setting.name .. "_z")
-- for pause menu env
fs = fs .. ("field_close_on_enter[%s;false]"):format(setting.name .. "_x")
fs = fs .. ("field_close_on_enter[%s;false]"):format(setting.name .. "_y")
fs = fs .. ("field_close_on_enter[%s;false]"):format(setting.name .. "_z")
fs = fs .. ("button[%f,0.6;1,0.8;%s;%s]"):format(avail_w, "set_" .. setting.name, fgettext("Set"))
return fs, 1.4
@ -442,22 +428,8 @@ local function make_noise_params(setting)
}
end
if INIT == "pause_menu" then
-- Making the noise parameter dialog work in the pause menu settings would
-- require porting "FSTK" (at least the dialog API) from the mainmenu formspec
-- API to the in-game formspec API.
-- There's no reason you'd want to adjust mapgen noise parameter settings
-- in-game (they only apply to new worlds), so there's no reason to implement
-- this.
local empty = function()
return { get_formspec = function() return "", 0 end }
end
make.noise_params_2d = empty
make.noise_params_3d = empty
else
make.noise_params_2d = make_noise_params
make.noise_params_3d = make_noise_params
end
make.noise_params_2d = make_noise_params
make.noise_params_3d = make_noise_params
return make

View file

@ -16,10 +16,13 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local path = core.get_builtin_path() .. "common" .. DIR_DELIM .. "settings" .. DIR_DELIM
local component_funcs = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "components.lua")
local component_funcs = dofile(path .. "components.lua")
local shadows_component = dofile(path .. "shadows_component.lua")
local shader_warning_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "shader_warning_component.lua")
local shadows_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "shadows_component.lua")
local loaded = false
local full_settings
@ -109,7 +112,7 @@ local function load()
local change_keys = {
query_text = "Controls",
requires = {
keyboard_mouse = true,
touch_controls = false,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 3)
@ -122,22 +125,6 @@ local function load()
end,
}
local touchscreen_layout = {
query_text = "Touchscreen layout",
requires = {
touchscreen = true,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 6)
return ("button[0,0;%f,0.8;btn_touch_layout;%s]"):format(btn_w, fgettext("Touchscreen layout")), 0.8
end,
on_submit = function(self, fields)
if fields.btn_touch_layout then
core.show_touchscreen_layout()
end
end,
}
add_page({
id = "accessibility",
title = fgettext_ne("Accessibility"),
@ -159,16 +146,20 @@ local function load()
{ heading = fgettext_ne("Movement") },
"arm_inertia",
"view_bobbing_amount",
"fall_bobbing_amount",
},
})
load_settingtypes()
table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys)
-- insert after "touch_controls"
table.insert(page_by_id.controls_touchscreen.content, 2, touchscreen_layout)
do
local content = page_by_id.graphics_and_audio_effects.content
local content = page_by_id.graphics_and_audio_graphics.content
table.insert(content, 1, shader_warning_component)
content = page_by_id.graphics_and_audio_effects.content
table.insert(content, 1, shader_warning_component)
local idx = table.indexof(content, "enable_dynamic_shadows")
table.insert(content, idx, shadows_component)
@ -357,6 +348,7 @@ local function check_requirements(name, requires)
end
local video_driver = core.get_active_driver()
local shaders_support = video_driver == "opengl" or video_driver == "opengl3" or video_driver == "ogles2"
local touch_support = core.irrlicht_device_supports_touch()
local touch_controls = core.settings:get("touch_controls")
local special = {
@ -367,7 +359,9 @@ local function check_requirements(name, requires)
-- be used, so we show settings for both.
touchscreen = touch_support and (touch_controls == "auto" or core.is_yes(touch_controls)),
keyboard_mouse = not touch_support or (touch_controls == "auto" or not core.is_yes(touch_controls)),
opengl = (video_driver == "opengl" or video_driver == "opengl3"),
shaders_support = shaders_support,
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
opengl = video_driver == "opengl",
gles = video_driver:sub(1, 5) == "ogles",
}
@ -375,10 +369,7 @@ local function check_requirements(name, requires)
if special[req_key] == nil then
local required_setting = get_setting_info(req_key)
if required_setting == nil then
core.log("warning", "Unknown setting " .. req_key .. " required by " .. (name or "???"))
elseif required_setting.type ~= "bool" then
core.log("warning", "Setting " .. req_key .. " of type " .. required_setting.type ..
" used as requirement by " .. (name or "???") .. ", only bool is allowed")
core.log("warning", "Unknown setting " .. req_key .. " required by " .. name)
end
local actual_value = core.settings:get_bool(req_key,
required_setting and core.is_yes(required_setting.default))
@ -515,8 +506,7 @@ local function get_formspec(dialogdata)
"box[0,0;", tostring(tabsize.width), ",", tostring(tabsize.height), ";#0000008C]",
("button[0,%f;%f,0.8;back;%s]"):format(
tabsize.height + 0.2, back_w,
INIT == "pause_menu" and fgettext("Exit") or fgettext("Back")),
tabsize.height + 0.2, back_w, fgettext("Back")),
("box[%f,%f;%f,0.8;#0000008C]"):format(
back_w + 0.2, tabsize.height + 0.2, checkbox_w),
@ -533,7 +523,6 @@ local function get_formspec(dialogdata)
"field[0.25,0.25;", tostring(search_width), ",0.75;search_query;;",
core.formspec_escape(dialogdata.query or ""), "]",
"field_enter_after_edit[search_query;true]",
"field_close_on_enter[search_query;false]", -- for pause menu env
"container[", tostring(search_width + 0.25), ", 0.25]",
"image_button[0,0;0.75,0.75;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]",
"image_button[0.75,0;0.75,0.75;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";search_clear;]",
@ -674,8 +663,7 @@ local function buttonhandler(this, fields)
dialogdata.rightscroll = core.explode_scrollbar_event(fields.rightscroll).value or dialogdata.rightscroll
dialogdata.query = fields.search_query
-- "fields.quit" is for the pause menu env
if fields.back or fields.quit then
if fields.back then
this:delete()
return true
end
@ -769,44 +757,11 @@ local function eventhandler(event)
end
if INIT == "mainmenu" then
function create_settings_dlg()
load()
local dlg = dialog_create("dlg_settings", get_formspec, buttonhandler, eventhandler)
function create_settings_dlg()
load()
local dlg = dialog_create("dlg_settings", get_formspec, buttonhandler, eventhandler)
dlg.data.page_id = update_filtered_pages("")
dlg.data.page_id = update_filtered_pages("")
return dlg
end
else
assert(INIT == "pause_menu")
local dialog
core.register_on_formspec_input(function(formname, fields)
if dialog and formname == "__builtin:settings" then
-- buttonhandler returning true means we should update the formspec.
-- dialog is re-checked since the buttonhandler may have closed it.
if buttonhandler(dialog, fields) and dialog then
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
end
return true
end
end)
core.open_settings = function()
load()
dialog = {}
dialog.data = {}
dialog.data.page_id = update_filtered_pages("")
dialog.delete = function()
dialog = nil
-- only needed for the "fields.back" case, in the "fields.quit"
-- case it's a no-op
core.show_formspec("__builtin:settings", "")
end
core.show_formspec("__builtin:settings", get_formspec(dialog.data))
end
return dlg
end

View file

@ -16,7 +16,7 @@ local minetest_example_header = [[
# to the program, eg. "luanti.exe --config ../minetest.conf.example".
# Further documentation:
# https://wiki.luanti.org/
# https://wiki.minetest.net/
]]
@ -61,7 +61,7 @@ local function create_minetest_conf_example(settings)
end
end
if entry.type == "key" then
local line = "See https://github.com/luanti-org/luanti/blob/master/irr/include/Keycodes.h"
local line = "See https://github.com/minetest/irrlicht/blob/master/include/Keycodes.h"
insert(result, "# " .. line .. "\n")
end
insert(result, "# type: " .. entry.type)

View file

@ -15,11 +15,11 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local path = core.get_builtin_path() .. "common" .. DIR_DELIM .. "settings" .. DIR_DELIM
local path = core.get_mainmenu_path() .. DIR_DELIM .. "settings"
dofile(path .. "settingtypes.lua")
dofile(path .. "dlg_change_mapgen_flags.lua")
dofile(path .. "dlg_settings.lua")
dofile(path .. DIR_DELIM .. "settingtypes.lua")
dofile(path .. DIR_DELIM .. "dlg_change_mapgen_flags.lua")
dofile(path .. DIR_DELIM .. "dlg_settings.lua")
-- Uncomment to generate 'minetest.conf.example' and 'settings_translation_file.cpp'.
-- For RUN_IN_PLACE the generated files may appear in the 'bin' folder.

View file

@ -408,16 +408,7 @@ function settingtypes.parse_config_file(read_all, parse_mods)
file:close()
end
-- TODO: Support game/mod settings in the pause menu too
-- Note that this will need to work different from how it's done in the
-- mainmenu:
-- * Only if in singleplayer / on local server, not on remote servers
-- * Only show settings for the active game and mods
-- (add API function to get them, can return nil if on a remote server)
-- (names are probably not enough, will need paths for uniqueness)
-- This means just making "pkgmgr.lua" work won't get you very far.
if INIT == "mainmenu" and parse_mods then
if parse_mods then
-- Parse games
local games_category_initialized = false
for _, game in ipairs(pkgmgr.games) do

View file

@ -0,0 +1,26 @@
-- Luanti
-- SPDX-License-Identifier: LGPL-2.1-or-later
return {
query_text = "Shaders",
requires = {
shaders_support = true,
shaders = false,
},
full_width = true,
get_formspec = function(self, avail_w)
local fs = {
"box[0,0;", avail_w, ",1.2;", mt_color_orange, "]",
"label[0.2,0.4;", fgettext("Shaders are disabled."), "]",
"label[0.2,0.8;", fgettext("This is not a recommended configuration."), "]",
"button[", avail_w - 2.2, ",0.2;2,0.8;fix_shader_warning;", fgettext("Enable"), "]",
}
return table.concat(fs, ""), 1.2
end,
on_submit = function(self, fields)
if fields.fix_shader_warning then
core.settings:remove("enable_shaders") -- default value is true
return true
end
end,
}

View file

@ -82,6 +82,7 @@ end
return {
query_text = "Shadows",
requires = {
shaders = true,
opengl = true,
},
get_formspec = function(self, avail_w)

View file

@ -32,27 +32,6 @@ local function get_credits()
return json
end
local function get_renderer_info()
local ret = {}
-- OpenGL version, stripped to just the important part
local s1 = core.get_active_renderer()
if s1:sub(1, 7) == "OpenGL " then
s1 = s1:sub(8)
end
local m = s1:match("^[%d.]+")
if not m then
m = s1:match("^ES [%d.]+")
end
ret[#ret+1] = m or s1
-- video driver
ret[#ret+1] = core.get_active_driver():lower()
-- irrlicht device
ret[#ret+1] = core.get_active_irrlicht_device():upper()
return table.concat(ret, " / ")
end
return {
name = "about",
caption = fgettext("About"),
@ -102,12 +81,20 @@ return {
"button_url[1.5,4.1;2.5,0.8;homepage;luanti.org;https://www.luanti.org/]" ..
"hypertext[5.5,0.25;9.75,6.6;credits;" .. core.formspec_escape(hypertext) .. "]"
local active_renderer_info = fgettext("Active renderer:") .. "\n" ..
core.formspec_escape(get_renderer_info())
-- Render information
local active_renderer_info = fgettext("Active renderer:") .. " " ..
core.formspec_escape(core.get_active_renderer())
fs = fs .. "style[label_button2;border=false]" ..
"button[0.1,6;5.3,1;label_button2;" .. active_renderer_info .. "]"..
"button[0.1,6;5.3,0.5;label_button2;" .. active_renderer_info .. "]"..
"tooltip[label_button2;" .. active_renderer_info .. "]"
-- Irrlicht device information
local irrlicht_device_info = fgettext("Irrlicht device:") .. " " ..
core.formspec_escape(core.get_active_irrlicht_device())
fs = fs .. "style[label_button3;border=false]" ..
"button[0.1,6.5;5.3,0.5;label_button3;" .. irrlicht_device_info .. "]"..
"tooltip[label_button3;" .. irrlicht_device_info .. "]"
if PLATFORM == "Android" then
fs = fs .. "button[0.5,5.1;4.5,0.8;share_debug;" .. fgettext("Share debug log") .. "]"
else

View file

@ -55,51 +55,6 @@ local function get_sorted_servers()
return servers
end
local function is_selected_fav(server)
local address = core.settings:get("address")
local port = tonumber(core.settings:get("remote_port"))
for _, fav in ipairs(serverlistmgr.get_favorites()) do
if address == fav.address and port == fav.port then
return true
end
end
return false
end
-- Persists the selected server in the "address" and "remote_port" settings
local function set_selected_server(server)
if server == nil then -- reset selection
core.settings:remove("address")
core.settings:remove("remote_port")
return
end
local address = server.address
local port = server.port
gamedata.serverdescription = server.description
if address and port then
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
end
local function find_selected_server()
local address = core.settings:get("address")
local port = tonumber(core.settings:get("remote_port"))
for _, server in ipairs(serverlistmgr.servers) do
if server.address == address and server.port == port then
return server
end
end
for _, server in ipairs(serverlistmgr.get_favorites()) do
if server.address == address and server.port == port then
return server
end
end
end
local function get_formspec(tabview, name, tabdata)
-- Update the cached supported proto info,
-- it may have changed after a change by the settings menu.
@ -112,7 +67,6 @@ local function get_formspec(tabview, name, tabdata)
local retval =
-- Search
"field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
"tooltip[te_search;" .. fgettext("Possible filters\ngame:<name>\nmod:<name>\nplayer:<name>") .. "]" ..
"field_enter_after_edit[te_search;true]" ..
"container[7.25,0.25]" ..
"image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" ..
@ -153,79 +107,17 @@ local function get_formspec(tabview, name, tabdata)
retval = retval .. "button[0.25,6;2.5,0.75;btn_mp_register;" .. fgettext("Register") .. "]"
end
local selected_server = find_selected_server()
if selected_server then
if tabdata.selected then
if gamedata.fav then
retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]"
retval = retval .. "style[btn_delete_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
"server_favorite_delete.png") .. ";btn_delete_favorite;]"
end
if gamedata.serverdescription then
retval = retval .. "textarea[0.25,1.85;5.25,2.7;;;" ..
core.formspec_escape(gamedata.serverdescription) .. "]"
end
-- Mods button
local mods = selected_server.mods
if mods and #mods > 0 then
local tooltip = ""
if selected_server.gameid then
tooltip = fgettext("Game: $1", selected_server.gameid) .. "\n"
end
tooltip = tooltip .. fgettext("Number of mods: $1", #mods)
retval = retval ..
"tooltip[btn_view_mods;" .. tooltip .. "]" ..
"style[btn_view_mods;padding=6]" ..
"image_button[4,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
"server_view_mods.png") .. ";btn_view_mods;]"
else
retval = retval .. "image[4.1,1.4;0.3,0.3;" .. core.formspec_escape(defaulttexturedir ..
"server_view_mods_unavailable.png") .. "]"
end
-- Clients list button
local clients_list = selected_server.clients_list
local can_view_clients_list = clients_list and #clients_list > 0
if can_view_clients_list then
table.sort(clients_list, function(a, b)
return a:lower() < b:lower()
end)
local max_clients = 5
if #clients_list > max_clients then
retval = retval .. "tooltip[btn_view_clients;" ..
fgettext("Players:\n$1", table.concat(clients_list, "\n", 1, max_clients)) .. "\n..." .. "]"
else
retval = retval .. "tooltip[btn_view_clients;" ..
fgettext("Players:\n$1", table.concat(clients_list, "\n")) .. "]"
end
retval = retval .. "style[btn_view_clients;padding=6]"
retval = retval .. "image_button[4.5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
"server_view_clients.png") .. ";btn_view_clients;]"
else
retval = retval .. "image[4.6,1.4;0.3,0.3;" .. core.formspec_escape(defaulttexturedir ..
"server_view_clients_unavailable.png") .. "]"
end
-- URL button
if selected_server.url then
retval = retval .. "tooltip[btn_server_url;" .. fgettext("Open server website") .. "]"
retval = retval .. "style[btn_server_url;padding=6]"
retval = retval .. "image_button[3.5,1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_url.png") .. ";btn_server_url;]"
else
retval = retval .. "image[3.6,1.4;0.3,0.3;" .. core.formspec_escape(defaulttexturedir ..
"server_url_unavailable.png") .. "]"
end
-- Favorites toggle button
if is_selected_fav() then
retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]"
retval = retval .. "style[btn_delete_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_favorite_delete.png") .. ";btn_delete_favorite;]"
else
retval = retval .. "tooltip[btn_add_favorite;" .. fgettext("Add favorite") .. "]"
retval = retval .. "style[btn_add_favorite;padding=6]"
retval = retval .. "image_button[5,1.3;0.5,0.5;" ..
core.formspec_escape(defaulttexturedir .. "server_favorite.png") .. ";btn_add_favorite;]"
end
end
retval = retval .. "container_end[]"
@ -283,126 +175,31 @@ local function get_formspec(tabview, name, tabdata)
retval = retval .. table.concat(rows, ",")
local selected_row_idx = 0
if selected_server then
for i, server in pairs(tabdata.lookup) do
if selected_server.address == server.address and
selected_server.port == server.port then
selected_row_idx = i
break
end
end
if tabdata.selected then
retval = retval .. ";" .. tabdata.selected .. "]"
else
retval = retval .. ";0]"
end
retval = retval .. ";" .. selected_row_idx .. "]"
return retval
end
--------------------------------------------------------------------------------
local function parse_search_input(input)
if not input:find("%S") then
return -- Return nil if nothing to search for
end
-- Search is not case sensitive
input = input:lower()
local query = {keywords = {}, mods = {}, players = {}}
-- Process quotation enclosed parts
input = input:gsub('(%S?)"([^"]*)"(%S?)', function(before, match, after)
if before == "" and after == "" then -- Also have be separated by spaces
table.insert(query.keywords, match)
return " "
end
return before..'"'..match..'"'..after
end)
-- Separate by space characters and handle special prefixes
-- (words with special prefixes need an exact match and none of them can contain spaces)
for word in input:gmatch("%S+") do
local mod = word:match("^mod:(.*)")
table.insert(query.mods, mod)
local player = word:match("^player:(.*)")
table.insert(query.players, player)
local game = word:match("^game:(.*)")
query.game = query.game or game
if not (mod or player or game) then
table.insert(query.keywords, word)
end
end
return query
end
-- Prepares the server to be used for searching
local function uncapitalize_server(server)
local function table_lower(t)
local r = {}
for i, s in ipairs(t or {}) do
r[i] = s:lower()
end
return r
end
return {
name = (server.name or ""):lower(),
description = (server.description or ""):lower(),
gameid = (server.gameid or ""):lower(),
mods = table_lower(server.mods),
clients_list = table_lower(server.clients_list),
}
end
-- Returns false if the query does not match
-- otherwise returns a number to adjust the sorting priority
local function matches_query(server, query)
-- Search is not case sensitive
server = uncapitalize_server(server)
-- Check if mods found
for _, mod in ipairs(query.mods) do
if table.indexof(server.mods, mod) < 0 then
return false
end
end
-- Check if players found
for _, player in ipairs(query.players) do
if table.indexof(server.clients_list, player) < 0 then
return false
end
end
-- Check if game matches
if query.game and query.game ~= server.gameid then
return false
end
-- Check if keyword found
local name_matches = true
local description_matches = true
for _, keyword in ipairs(query.keywords) do
name_matches = name_matches and server.name:find(keyword, 1, true)
description_matches = description_matches and server.description:find(keyword, 1, true)
end
return name_matches and 50 or description_matches and 0
end
local function search_server_list(input, tabdata)
local function search_server_list(input)
menudata.search_result = nil
if #serverlistmgr.servers < 2 then
return
end
-- setup the keyword list
local keywords = {}
for word in input:gmatch("%S+") do
word = word:gsub("(%W)", "%%%1")
table.insert(keywords, word)
end
tabdata.pre_search_selection = tabdata.pre_search_selection or find_selected_server()
-- setup the search query
local query = parse_search_input(input)
if not query then
if #keywords == 0 then
return
end
@ -410,10 +207,26 @@ local function search_server_list(input, tabdata)
-- Search the serverlist
local search_result = {}
for i, server in ipairs(serverlistmgr.servers) do
local match = matches_query(server, query)
if match then
server.points = #serverlistmgr.servers - i + match
for i = 1, #serverlistmgr.servers do
local server = serverlistmgr.servers[i]
local found = 0
for k = 1, #keywords do
local keyword = keywords[k]
if server.name then
local sername = server.name:lower()
local _, count = sername:gsub(keyword, keyword)
found = found + count * 4
end
if server.description then
local desc = server.description:lower()
local _, count = desc:gsub(keyword, keyword)
found = found + count * 2
end
end
if found > 0 then
local points = (#serverlistmgr.servers - i) / 5 + found
server.points = points
table.insert(search_result, server)
end
end
@ -422,32 +235,39 @@ local function search_server_list(input, tabdata)
return
end
local current_server = find_selected_server()
table.sort(search_result, function(a, b)
return a.points > b.points
end)
menudata.search_result = search_result
end
-- Keep current selection if it's in search results
if current_server then
for _, server in ipairs(search_result) do
if server.address == current_server.address and
server.port == current_server.port then
return
end
local function set_selected_server(tabdata, idx, server)
-- reset selection
if idx == nil or server == nil then
tabdata.selected = nil
core.settings:set("address", "")
core.settings:set("remote_port", "30000")
return
end
local address = server.address
local port = server.port
gamedata.serverdescription = server.description
gamedata.fav = false
for _, fav in ipairs(serverlistmgr.get_favorites()) do
if address == fav.address and port == fav.port then
gamedata.fav = true
break
end
end
-- Find first compatible server (favorite or public)
for _, server in ipairs(search_result) do
if is_server_protocol_compat(server.proto_min, server.proto_max) then
set_selected_server(server)
return
end
if address and port then
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
-- If no compatible server found, clear selection
set_selected_server(nil)
tabdata.selected = idx
end
local function main_button_handler(tabview, fields, name, tabdata)
@ -480,67 +300,45 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.serverdescription = server.description
if gamedata.address and gamedata.port then
set_selected_server(server)
core.settings:set("address", gamedata.address)
core.settings:set("remote_port", gamedata.port)
core.start()
end
return true
end
if event.type == "CHG" then
set_selected_server(server)
tabdata.pre_search_selection = nil
set_selected_server(tabdata, event.row, server)
return true
end
end
end
if fields.btn_add_favorite then
serverlistmgr.add_favorite(find_selected_server())
return true
end
if fields.btn_delete_favorite then
local idx = core.get_table_index("servers")
if not idx then return end
local server = tabdata.lookup[idx]
if not server then return end
serverlistmgr.delete_favorite(tabdata.lookup[idx])
set_selected_server(tabdata.lookup[idx+1])
return true
end
if fields.btn_server_url then
core.open_url_dialog(find_selected_server().url)
return true
end
if fields.btn_view_clients then
local dlg = create_clientslist_dialog(find_selected_server())
dlg:set_parent(tabview)
tabview:hide()
dlg:show()
return true
end
if fields.btn_view_mods then
local dlg = create_server_list_mods_dialog(find_selected_server())
dlg:set_parent(tabview)
tabview:hide()
dlg:show()
serverlistmgr.delete_favorite(server)
-- the server at [idx+1] will be at idx once list is refreshed
set_selected_server(tabdata, idx, tabdata.lookup[idx+1])
return true
end
if fields.btn_mp_clear then
tabdata.search_for = ""
menudata.search_result = nil
if tabdata.pre_search_selection then
set_selected_server(tabdata.pre_search_selection)
tabdata.pre_search_selection = nil
end
return true
end
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
tabdata.search_for = fields.te_search
search_server_list(fields.te_search, tabdata)
search_server_list(fields.te_search:lower())
if menudata.search_result then
-- first server in row 2 due to header
set_selected_server(tabdata, 2, menudata.search_result[1])
end
return true
end
@ -565,6 +363,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
local idx = core.get_table_index("servers")
local server = idx and tabdata.lookup[idx]
set_selected_server(tabdata)
if server and server.address == gamedata.address and
server.port == gamedata.port then

View file

@ -1,12 +0,0 @@
local scriptpath = core.get_builtin_path()
local pausepath = scriptpath.."pause_menu"..DIR_DELIM
local commonpath = scriptpath.."common"..DIR_DELIM
-- we're in-game, so no absolute paths are needed
defaulttexturedir = ""
local builtin_shared = {}
assert(loadfile(commonpath .. "register.lua"))(builtin_shared)
assert(loadfile(pausepath .. "register.lua"))(builtin_shared)
dofile(commonpath .. "settings" .. DIR_DELIM .. "init.lua")

View file

@ -1,5 +0,0 @@
local builtin_shared = ...
local make_registration = builtin_shared.make_registration
core.registered_on_formspec_input, core.register_on_formspec_input = make_registration()

View file

@ -61,7 +61,7 @@
#
# # This is a comment
# #
# # Requires: enable_dynamic_shadows, !enable_waving_leaves
# # Requires: shaders, enable_dynamic_shadows, !enable_waving_leaves
# name (Readable name) type type_args
#
# A requirement can be the name of a boolean setting or an engine-defined value.
@ -69,6 +69,8 @@
#
# * The value of a boolean setting, such as enable_dynamic_shadows
# * An engine-defined value:
# * shaders_support (a video driver that supports shaders, may not be enabled)
# * shaders (both enable_shaders and shaders_support)
# * desktop / android
# * touchscreen / keyboard_mouse
# * opengl / gles
@ -77,11 +79,8 @@
# Sections are marked by a single line in the format: [Section Name]
# Sub-section are marked by adding * in front of the section name: [*Sub-section]
# Sub-sub-sections have two * etc.
# There shouldn't be too many settings per category.
#
# The top-level categories "Advanced", "Client and Server" and "Mapgen" are
# handled specially and its contents only shown when a checkbox is checked.
# They contain settings not intended for the "average user".
# There shouldn't be too much settings per category; settings that shouldn't be
# modified by the "average user" should be in (sub-)categories called "Advanced".
[Controls]
@ -256,8 +255,8 @@ fps_max (Maximum FPS) int 60 1 4294967295
# Vertical screen synchronization. Your system may still force VSync on even if this is disabled.
vsync (VSync) bool false
# Maximum FPS when the window is not focused.
fps_max_unfocused (FPS when unfocused) int 10 1 4294967295
# Maximum FPS when the window is not focused, or when the game is paused.
fps_max_unfocused (FPS when unfocused or paused) int 20 1 4294967295
# View distance in nodes.
viewing_range (Viewing range) int 190 20 4000
@ -266,8 +265,6 @@ viewing_range (Viewing range) int 190 20 4000
# to the game world only, keeping the GUI intact.
# It should give a significant performance boost at the cost of less detailed image.
# Higher values result in a less detailed image.
# Note: Undersampling is currently not supported if the "3d_mode" setting is set
# to a non-default value.
undersampling (Undersampling) int 1 1 8
[**3D]
@ -280,6 +277,7 @@ undersampling (Undersampling) int 1 1 8
# - topbottom: split screen top/bottom.
# - sidebyside: split screen side by side.
# - crossview: Cross-eyed 3d
# Note that the interlaced mode requires shaders to be enabled.
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,crossview
# Strength of 3D mode parallax.
@ -295,6 +293,10 @@ arm_inertia (Arm inertia) bool true
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
view_bobbing_amount (View bobbing factor) float 1.0 0.0 7.9
# Multiplier for fall bobbing.
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
fall_bobbing_amount (Fall bobbing factor) float 0.03 0.0 100.0
[**Camera]
# Field of view in degrees.
@ -373,12 +375,17 @@ fog_start (Fog start) float 0.4 0.0 0.99
[**Clouds]
# Allow clouds to look 3D instead of flat.
# Clouds are a client-side effect.
enable_clouds (Clouds) bool true
# Use 3D cloud look instead of flat.
#
# Requires: enable_clouds
enable_3d_clouds (3D clouds) bool true
# Use smooth cloud shading.
#
# Requires: enable_3d_clouds
# Requires: enable_3d_clouds, enable_clouds
soft_clouds (Soft clouds) bool false
[**Filtering and Antialiasing]
@ -397,7 +404,6 @@ bilinear_filter (Bilinear filtering) bool false
trilinear_filter (Trilinear filtering) bool false
# Use anisotropic filtering when looking at textures from an angle.
# This provides a significant improvement when used together with mipmapping.
anisotropic_filter (Anisotropic filtering) bool false
# Select the antialiasing method to apply.
@ -405,18 +411,16 @@ anisotropic_filter (Anisotropic filtering) bool false
# * None - No antialiasing (default)
#
# * FSAA - Hardware-provided full-screen antialiasing
# (incompatible with Post Processing and Undersampling)
# A.K.A multi-sample antialiasing (MSAA)
# Smoothens out block edges but does not affect the insides of textures.
# A restart is required to change this option.
#
# If Post Processing is disabled, changing FSAA requires a restart.
# Also, if Post Processing is disabled, FSAA will not work together with
# undersampling or a non-default "3d_mode" setting.
#
# * FXAA - Fast approximate antialiasing
# * FXAA - Fast approximate antialiasing (requires shaders)
# Applies a post-processing filter to detect and smoothen high-contrast edges.
# Provides balance between speed and image quality.
#
# * SSAA - Super-sampling antialiasing
# * SSAA - Super-sampling antialiasing (requires shaders)
# Renders higher-resolution image of the scene, then scales down to reduce
# the aliasing effects. This is the slowest and the most accurate method.
antialiasing (Antialiasing method) enum none none,fsaa,fxaa,ssaa
@ -463,16 +467,24 @@ smooth_lighting (Smooth lighting) bool true
# at the expense of minor visual glitches that do not impact game playability.
performance_tradeoffs (Tradeoffs for performance) bool false
# Adds particles when digging a node.
enable_particles (Digging particles) bool true
[**Waving Nodes]
# Set to true to enable waving leaves.
#
# Requires: shaders
enable_waving_leaves (Waving leaves) bool false
# Set to true to enable waving plants.
#
# Requires: shaders
enable_waving_plants (Waving plants) bool false
# Set to true to enable waving liquids (like water).
#
# Requires: shaders
enable_waving_water (Waving liquids) bool false
# The maximum height of the surface of waving liquids.
@ -480,83 +492,99 @@ enable_waving_water (Waving liquids) bool false
# 0.0 = Wave doesn't move at all.
# Default is 1.0 (1/2 node).
#
# Requires: enable_waving_water
# Requires: shaders, enable_waving_water
water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0
# Length of liquid waves.
#
# Requires: enable_waving_water
# Requires: shaders, enable_waving_water
water_wave_length (Waving liquids wavelength) float 20.0 0.1
# How fast liquid waves will move. Higher = faster.
# If negative, liquid waves will move backwards.
#
# Requires: enable_waving_water
# Requires: shaders, enable_waving_water
water_wave_speed (Waving liquids wave speed) float 5.0
[**Dynamic shadows]
# Set to true to enable Shadow Mapping.
#
# Requires: opengl
# Requires: shaders, opengl
enable_dynamic_shadows (Dynamic shadows) bool false
# Set the shadow strength gamma.
# Adjusts the intensity of in-game dynamic shadows.
# Lower value means lighter shadows, higher value means darker shadows.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0
# Maximum distance to render shadows.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 140.0 10.0 1000.0
# Texture size to render the shadow map on.
# This must be a power of two.
# Bigger numbers create better shadows but it is also more expensive.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_map_texture_size (Shadow map texture size) int 2048 128 8192
# Sets shadow texture quality to 32 bits.
# On false, 16 bits texture will be used.
# This can cause much more artifacts in the shadow.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_map_texture_32bit (Shadow map texture in 32 bits) bool true
# Enable Poisson disk filtering.
# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
#
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_poisson_filter (Poisson filtering) bool true
# Define shadow filtering quality.
# This simulates the soft shadows effect by applying a PCF or Poisson disk
# but also uses more resources.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_filters (Shadow filter quality) enum 1 0,1,2
# Enable colored shadows for transculent nodes.
# This is expensive.
# Enable colored shadows.
# On true translucent nodes cast colored shadows. This is expensive.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_map_color (Colored shadows) bool false
# Spread a complete update of shadow map over given number of frames.
# Higher values might make shadows laggy, lower values
# will consume more resources.
# Minimum value: 1; maximum value: 16
#
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_update_frames (Map shadows update frames) int 8 1 16
# Set the soft shadow radius size.
# Lower values mean sharper shadows, bigger values mean softer shadows.
# Minimum value: 1.0; maximum value: 15.0
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_soft_radius (Soft shadow radius) float 5.0 1.0 15.0
# Set the default tilt of Sun/Moon orbit in degrees.
# Games may change orbit tilt via API.
# Value of 0 means no tilt / vertical orbit.
#
# Requires: enable_dynamic_shadows, opengl
# Requires: shaders, enable_dynamic_shadows, opengl
shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 -60.0 60.0
[**Post Processing]
# Enables the post processing pipeline.
#
# Requires: shaders
enable_post_processing (Enable Post Processing) bool true
# Enables Hable's 'Uncharted 2' filmic tone mapping.
@ -564,7 +592,7 @@ enable_post_processing (Enable Post Processing) bool true
# appearance of high dynamic range images. Mid-range contrast is slightly
# enhanced, highlights and shadows are gradually compressed.
#
# Requires: enable_post_processing
# Requires: shaders, enable_post_processing
tone_mapping (Filmic tone mapping) bool false
# Enable automatic exposure correction
@ -572,14 +600,14 @@ tone_mapping (Filmic tone mapping) bool false
# automatically adjust to the brightness of the scene,
# simulating the behavior of human eye.
#
# Requires: enable_post_processing
# Requires: shaders, enable_post_processing
enable_auto_exposure (Enable Automatic Exposure) bool false
# Set the exposure compensation in EV units.
# Value of 0.0 (default) means no exposure compensation.
# Range: from -1 to 1.0
#
# Requires: enable_post_processing, enable_auto_exposure
# Requires: shaders, enable_post_processing, enable_auto_exposure
exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0
# Apply dithering to reduce color banding artifacts.
@ -590,35 +618,35 @@ exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0
# With OpenGL ES, dithering only works if the shader supports high
# floating-point precision and it may have a higher performance impact.
#
# Requires: enable_post_processing
# Requires: shaders, enable_post_processing
debanding (Enable Debanding) bool true
# Set to true to enable bloom effect.
# Bright colors will bleed over the neighboring objects.
#
# Requires: enable_post_processing
# Requires: shaders, enable_post_processing
enable_bloom (Enable Bloom) bool false
# Set to true to enable volumetric lighting effect (a.k.a. "Godrays").
#
# Requires: enable_post_processing, enable_bloom
# Requires: shaders, enable_post_processing, enable_bloom
enable_volumetric_lighting (Volumetric lighting) bool false
[**Other Effects]
# Simulate translucency when looking at foliage in the sunlight.
#
# Requires: enable_dynamic_shadows
# Requires: shaders, enable_dynamic_shadows
enable_translucent_foliage (Translucent foliage) bool false
# Apply specular shading to nodes.
#
# Requires: enable_dynamic_shadows
# Requires: shaders, enable_dynamic_shadows
enable_node_specular (Node specular) bool false
# When enabled, liquid reflections are simulated.
#
# Requires: enable_waving_water, enable_dynamic_shadows
# Requires: shaders, enable_waving_water, enable_dynamic_shadows
enable_water_reflections (Liquid reflections) bool false
[*Audio]
@ -630,7 +658,8 @@ sound_volume (Volume) float 0.8 0.0 1.0
# Volume multiplier when the window is unfocused.
sound_volume_unfocused (Volume when unfocused) float 0.3 0.0 1.0
# Whether to mute sounds. You can unmute sounds at any time.
# Whether to mute sounds. You can unmute sounds at any time, unless the
# sound system is disabled (enable_sound=false).
# In-game, you can toggle the mute state with the mute key or by using the
# pause menu.
mute_sound (Mute sound) bool false
@ -671,6 +700,12 @@ formspec_fullscreen_bg_color (Formspec Full-Screen Background Color) string (0,0
# to hardware (e.g. render-to-texture for nodes in inventory).
gui_scaling_filter (GUI scaling filter) bool false
# When gui_scaling_filter_txr2img is true, copy those images
# from hardware to software for scaling. When false, fall back
# to the old scaling method, for video drivers that don't
# properly support downloading textures back from hardware.
gui_scaling_filter_txr2img (GUI scaling filter txr2img) bool true
# Delay showing tooltips, stated in milliseconds.
tooltip_show_delay (Tooltip delay) int 400 0 18446744073709551615
@ -713,6 +748,9 @@ console_color (Console color) string (0,0,0)
# In-game chat console background alpha (opaqueness, between 0 and 255).
console_alpha (Console alpha) int 200 0 255
# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
clickable_chat_weblinks (Chat weblinks) bool true
# Optional override for chat weblink color.
chat_weblink_color (Weblink color) string #8888FF
@ -724,7 +762,7 @@ chat_font_size (Chat font size) int 0 0 72
[**Content Repository]
# The URL for the content repository
contentdb_url (ContentDB URL) string https://content.luanti.org
contentdb_url (ContentDB URL) string https://content.minetest.net
# If enabled and you have ContentDB packages installed, Luanti may contact ContentDB to
# check for package updates when opening the mainmenu.
@ -735,7 +773,7 @@ contentdb_enable_updates_indicator (Enable updates available indicator on conten
# as defined by the Free Software Foundation.
# You can also specify content ratings.
# These flags are independent from Luanti versions,
# so see a full list at https://content.luanti.org/help/content_flags/
# so see a full list at https://content.minetest.net/help/content_flags/
contentdb_flag_blacklist (ContentDB Flag Blacklist) string nonfree, desktop_default
# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued.
@ -751,20 +789,20 @@ contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3 1
enable_local_map_saving (Saving map received from server) bool false
# URL to the server list displayed in the Multiplayer Tab.
serverlist_url (Serverlist URL) string https://servers.luanti.org
serverlist_url (Serverlist URL) string servers.minetest.net
# If enabled, server account registration is separate from login in the UI.
# If disabled, connecting to a server will automatically register a new account.
# If enabled, account registration is separate from login in the UI.
# If disabled, new accounts will be registered automatically when logging in.
enable_split_login_register (Enable split login/register) bool true
# URL to JSON file which provides information about the newest Luanti release.
# If this is empty the engine will never check for updates.
update_information_url (Update information URL) string https://www.luanti.org/release_info.json
update_information_url (Update information URL) string https://www.minetest.net/release_info.json
[*Server]
# Name of the player.
# When running a server, a client connecting with this name is admin.
# When running a server, clients connecting with this name are admins.
# When starting from the main menu, this is overridden.
name (Admin name) string
@ -777,10 +815,10 @@ server_name (Server name) string Luanti server
server_description (Server description) string mine here
# Domain name of server, to be displayed in the serverlist.
server_address (Server address) string game.example.net
server_address (Server address) string game.minetest.net
# Homepage of server, to be displayed in the serverlist.
server_url (Server URL) string https://game.example.net
server_url (Server URL) string https://minetest.net
# Automatically report to the serverlist.
server_announce (Announce server) bool false
@ -789,7 +827,7 @@ server_announce (Announce server) bool false
server_announce_send_players (Send player names to the server list) bool true
# Announce to this serverlist.
serverlist_url (Serverlist URL) string https://servers.luanti.org
serverlist_url (Serverlist URL) string servers.minetest.net
# Message of the day displayed to players connecting.
motd (Message of the day) string
@ -828,12 +866,10 @@ protocol_version_min (Protocol version minimum) int 1 1 65535
# Files that are not present will be fetched the usual way.
remote_media (Remote media) string
# Enable IPv6 support for server.
# Note that clients will be able to connect with both IPv4 and IPv6.
# Enable/disable running an IPv6 server.
# Ignored if bind_address is set.
#
# Requires: enable_ipv6
ipv6_server (IPv6 server) bool true
# Needs enable_ipv6 to be enabled.
ipv6_server (IPv6 server) bool false
[*Server Security]
@ -1791,12 +1827,24 @@ profiler_print_interval (Engine profiling data print interval) int 0 0
[*Advanced]
# Enable IPv6 support (for both client and server).
# Required for IPv6 connections to work at all.
enable_ipv6 (IPv6) bool true
# If enabled, invalid world data won't cause the server to shut down.
# Only enable this if you know what you are doing.
ignore_world_load_errors (Ignore world errors) bool false
[**Graphics]
# Enables debug and error-checking in the OpenGL driver.
opengl_debug (OpenGL debug) bool false
# Shaders are a fundamental part of rendering and enable advanced visual effects.
#
# Requires: shaders_support
enable_shaders (Shaders) bool true
# Path to shader directory. If no path is defined, default location will be used.
#
# Requires: shaders
shader_path (Shader path) path
# The rendering back-end.
@ -1809,14 +1857,16 @@ video_driver (Video driver) enum ,opengl,opengl3,ogles2
# Set to 0 to disable it entirely.
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
# Draw transparency sorted triangles grouped by their mesh buffers.
# This breaks transparency sorting between mesh buffers, but avoids situations
# where transparency sorting would be very slow otherwise.
transparency_sorting_group_by_buffers (Transparency Sorting Group by Buffers) bool true
# Radius of cloud area stated in number of 64 node cloud squares.
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
cloud_radius (Cloud radius) int 12 8 62
cloud_radius (Cloud radius) int 12 1 62
# Whether node texture animations should be desynchronized per mapblock.
desynchronize_mapblock_texture_animation (Desynchronize block animation) bool false
# Enables caching of facedir rotated meshes.
# This is only effective with shaders disabled.
enable_mesh_cache (Mesh cache) bool false
# Delay between mesh updates on the client in ms. Increasing this will slow
# down the rate of mesh updates, thus reducing jitter on slower clients.
@ -1826,10 +1876,6 @@ mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50
# Value of 0 (default) will let Luanti autodetect the number of available threads.
mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8
# All mesh buffers with less than this number of vertices will be merged
# during map rendering. This improves rendering performance.
mesh_buffer_min_vertices (Minimum vertex count for mesh buffers) int 300 0 1000
# True = 256
# False = 128
# Usable to make minimap smoother on slower machines.
@ -1851,11 +1897,12 @@ world_aligned_mode (World-aligned textures mode) enum enable disable,enable,forc
# Warning: This option is EXPERIMENTAL!
autoscale_mode (Autoscaling mode) enum disable disable,enable,force
# When using bilinear/trilinear filtering, low-resolution textures
# can be blurred, so this option automatically upscales them to preserve
# crisp pixels. This defines the minimum texture size for the upscaled textures;
# higher values look sharper, but require more memory.
# This setting is ONLY applied if any of the mentioned filters are enabled.
# When using bilinear/trilinear/anisotropic filters, low-resolution textures
# can be blurred, so automatically upscale them with nearest-neighbor
# interpolation to preserve crisp pixels. This sets the minimum texture size
# for the upscaled textures; higher values look sharper, but require more
# memory. Powers of 2 are recommended. This setting is ONLY applied if
# bilinear/trilinear/anisotropic filtering is enabled.
# This is also used as the base node texture size for world-aligned
# texture autoscaling.
texture_min_size (Base texture size) int 64 1 32768
@ -1867,32 +1914,15 @@ texture_min_size (Base texture size) int 64 1 32768
# Systems with a low-end GPU (or no GPU) would benefit from smaller values.
client_mesh_chunk (Client Mesh Chunksize) int 1 1 16
# Decide the color depth of the texture used for the post-processing pipeline.
# Reducing this can improve performance, but some effects (e.g. debanding)
# require more than 8 bits to work.
#
# Requires: enable_post_processing
post_processing_texture_bits (Color depth for post-processing texture) enum 16 8,10,16
# Enable Poisson disk filtering.
# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
#
# Requires: enable_dynamic_shadows, opengl
shadow_poisson_filter (Poisson filtering) bool true
# Spread a complete update of the shadow map over a given number of frames.
# Higher values might make shadows laggy, lower values
# will consume more resources.
#
# Requires: enable_dynamic_shadows, opengl
shadow_update_frames (Map shadows update frames) int 16 1 32
# Enables debug and error-checking in the OpenGL driver.
opengl_debug (OpenGL debug) bool false
# Set to true to render debugging breakdown of the bloom effect.
# In debug mode, the screen is split into 4 quadrants:
# top-left - processed base image, top-right - final image
# bottom-left - raw base image, bottom-right - bloom texture.
#
# Requires: enable_post_processing, enable_bloom
# Requires: shaders, enable_post_processing, enable_bloom
enable_bloom_debug (Enable Bloom Debug) bool false
[**Sound]
@ -1976,10 +2006,6 @@ lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4
[**Networking]
# Enable IPv6 support (for both client and server).
# Required for IPv6 connections to work at all.
enable_ipv6 (IPv6) bool true
# Prometheus listener address.
# If Luanti is compiled with ENABLE_PROMETHEUS option enabled,
# enable metrics listener for Prometheus on that address.
@ -1994,9 +2020,7 @@ max_out_chat_queue_size (Maximum size of the outgoing chat queue) int 20 -1 3276
client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0
# Maximum number of mapblocks for client to be kept in memory.
# Note that there is an internal dynamic minimum number of blocks that
# won't be deleted, depending on the current view range.
# Set to -1 for no limit.
# Set to -1 for unlimited amount.
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
# Maximum number of blocks that are simultaneously sent per client.
@ -2075,6 +2099,9 @@ max_block_send_distance (Max block send distance) int 12 1 65535
# Set this to -1 to disable the limit.
max_forceloaded_blocks (Maximum forceloaded blocks) int 16 -1
# Interval of sending time of day to clients, stated in seconds.
time_send_interval (Time send interval) float 5.0 0.001
# Interval of saving important changes in the world, stated in seconds.
server_map_save_interval (Map save interval) float 5.3 0.001
@ -2083,7 +2110,7 @@ server_map_save_interval (Map save interval) float 5.3 0.001
server_unload_unused_data_timeout (Unload unused server data) int 29 0 4294967295
# Maximum number of statically stored objects in a block.
max_objects_per_block (Maximum objects per block) int 256 256 65535
max_objects_per_block (Maximum objects per block) int 256 1 65535
# Length of time between active block management cycles, stated in seconds.
active_block_mgmt_interval (Active block management interval) float 2.0 0.0
@ -2184,13 +2211,6 @@ curl_file_download_timeout (cURL file download timeout) int 300000 5000 21474836
[**Miscellaneous]
# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
clickable_chat_weblinks (Chat weblinks) bool true
# If enabled, invalid world data won't cause the server to shut down.
# Only enable this if you know what you are doing.
ignore_world_load_errors (Ignore world errors) bool false
# Adjust the detected display density, used for scaling UI elements.
display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0
@ -2309,6 +2329,12 @@ show_technical_names (Show technical names) bool false
# Controlled by a checkbox in the settings menu.
show_advanced (Show advanced settings) bool false
# Enables the sound system.
# If disabled, this completely disables all sounds everywhere and the in-game
# sound controls will be non-functional.
# Changing this setting requires a restart.
enable_sound (Sound) bool true
# Key for moving the player forward.
keymap_forward (Forward key) key KEY_KEY_W

View file

@ -9,7 +9,6 @@ attribute vec2 inTexCoord0;
/* Uniforms */
uniform float uThickness;
uniform mat4 uProjection;
/* Varyings */
@ -18,7 +17,7 @@ varying vec4 vVertexColor;
void main()
{
gl_Position = uProjection * inVertexPosition;
gl_Position = inVertexPosition;
gl_PointSize = uThickness;
vTextureCoord = inTexCoord0;
vVertexColor = inVertexColor.bgra;

View file

@ -0,0 +1,6 @@
varying lowp vec4 varColor;
void main(void)
{
gl_FragData[0] = varColor;
}

View file

@ -0,0 +1,7 @@
varying lowp vec4 varColor;
void main(void)
{
gl_Position = mWorldViewProj * inVertexPosition;
varColor = inVertexColor;
}

View file

@ -23,12 +23,7 @@ void main(void)
vec2 uv = varTexCoord.st;
vec3 color = texture2D(rendered, uv).rgb;
// translate to linear colorspace (approximate)
#ifdef GL_ES
// clamp color to [0,1] range in lieu of centroids
color = pow(clamp(color, 0.0, 1.0), vec3(2.2));
#else
color = pow(color, vec3(2.2));
#endif
color *= exposureParams.compensationFactor * bloomStrength;

View file

@ -1,3 +1,7 @@
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT)
#define MATERIAL_WAVING_LIQUID 1
#endif
uniform sampler2D baseTexture;
uniform vec3 dayLight;
@ -39,19 +43,17 @@ varying vec3 vPosition;
// cameraOffset + worldPosition (for large coordinates the limits of float
// precision must be considered).
varying vec3 worldPosition;
#ifdef GL_ES
varying lowp vec4 varColor;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
varying float nightRatio;
#else
centroid varying lowp vec4 varColor;
centroid varying vec2 varTexCoord;
centroid varying float nightRatio;
#endif
varying highp vec3 eyeVec;
varying float nightRatio;
#ifdef ENABLE_DYNAMIC_SHADOWS
#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WATER_REFLECTIONS && ENABLE_WAVING_WATER)
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
vec4 perm(vec4 x)
{
return mod(((x * 34.0) + 1.0) * x, 289.0);
@ -502,7 +504,7 @@ void main(void)
vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition);
// Water reflections
#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WATER_REFLECTIONS && ENABLE_WAVING_WATER)
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
vec3 wavePos = worldPosition * vec3(2.0, 0.0, 2.0);
float off = animationTimer * WATER_WAVE_SPEED * 10.0;
wavePos.x /= WATER_WAVE_LENGTH * 3.0;
@ -530,7 +532,7 @@ void main(void)
col.rgb += water_reflect_color * f_adj_shadow_strength * brightness_factor;
#endif
#if (defined(ENABLE_NODE_SPECULAR) && !MATERIAL_WATER_REFLECTIONS)
#if (defined(ENABLE_NODE_SPECULAR) && !defined(MATERIAL_WAVING_LIQUID))
// Apply specular to blocks.
if (dot(v_LightDirection, vNormal) < 0.0) {
float intensity = 2.0 * (1.0 - (base.r * varColor.r));

View file

@ -14,17 +14,14 @@ varying vec3 vPosition;
// cameraOffset + worldPosition (for large coordinates the limits of float
// precision must be considered).
varying vec3 worldPosition;
varying lowp vec4 varColor;
// The centroid keyword ensures that after interpolation the texture coordinates
// lie within the same bounds when MSAA is en- and disabled.
// This fixes the stripes problem with nearest-neighbor textures and MSAA.
#ifdef GL_ES
varying lowp vec4 varColor;
varying mediump vec2 varTexCoord;
varying float nightRatio;
#else
centroid varying lowp vec4 varColor;
centroid varying vec2 varTexCoord;
centroid varying float nightRatio;
#endif
#ifdef ENABLE_DYNAMIC_SHADOWS
// shadow uniforms
@ -47,6 +44,7 @@ centroid varying float nightRatio;
varying float area_enable_parallax;
varying highp vec3 eyeVec;
varying float nightRatio;
// Color of the light emitted by the light sources.
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
const float e = 2.718281828459;
@ -110,7 +108,8 @@ float smoothTriangleWave(float x)
return smoothCurve(triangleWave(x)) * 2.0 - 1.0;
}
#if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
// OpenGL < 4.3 does not support continued preprocessor lines
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
//
// Simple, fast noise function.
@ -167,7 +166,8 @@ void main(void)
#endif
vec4 pos = inVertexPosition;
#if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
// OpenGL < 4.3 does not support continued preprocessor lines
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
// Generate waves with Perlin-type noise.
// The constants are calibrated such that they roughly
// correspond to the old sine waves.

View file

@ -61,7 +61,7 @@ vec4 applyBloom(vec4 color, vec2 uv)
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
*/
// highp for GLES, see <https://github.com/luanti-org/luanti/pull/14688>
// see https://github.com/minetest/minetest/pull/14688
highp vec3 uncharted2Tonemap(highp vec3 x)
{
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;

View file

@ -1,7 +1,7 @@
# Project properties
PROJECT_NAME = @PROJECT_NAME_CAPITALIZED@
PROJECT_NUMBER = @VERSION_STRING@
PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/misc/luanti.svg
PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/misc/minetest.svg
# Parsing
JAVADOC_AUTOBRIEF = YES

View file

@ -3,6 +3,8 @@ All Luanti builds, including the Android variant, are based on the same code.
However, additional Java code is used for proper Android integration.
## Controls
Compared to Luanti binaries for PC, the Android port has limited functionality
due to limited capabilities of common devices. What can be done is described below:
While you're playing the game normally (that is, no menu or inventory is
shown), the following controls are available:
@ -42,7 +44,7 @@ configuration file can usually be found at:
* After 5.4.2:
* `/sdcard/Android/data/net.minetest.minetest/` or `/storage/emulated/0/Android/data/net.minetest.minetest/` if stored on the device
* `/storage/emulated/(varying folder name)/Android/data/net.minetest.minetest/` if stored on the SD card
* [Learn more about Android directory](https://wiki.luanti.org/Accessing_Android_Data_Directory)
* [Learn more about Android directory](https://wiki.minetest.net/Accessing_Android_Data_Directory)
## Useful settings
@ -56,25 +58,35 @@ Mobile device generally have less RAM than PC, this setting limit how many mapbl
this setting limit max FPS (Frame per second). Default value is 60, which lowest Android device screen refresh rate commonly found, but if you're using an device have lower refresh rate, change this
## Requirements
The recommended system requirements for Luanti are listed below.
The minimal and recommended system requirements for Luanti are listed below.
### CPU
Supported architectures:
1. ARMv7
2. AArch64
1. ARM v7
2. ARM v8
3. x86
4. x86_64
CPU architectures similar to ARM or x86 might run Luanti but are not tested.
### Minimum
1. Graphics API: OpenGL ES 1.0
* Shaders might not work correctly or work at all on OpenGL ES 1.0.
2. Android version: Android 4.1 (API Level 16)
3. Free RAM: 500 MB
4. Free storage: 100 MB
* More storage is highly recommended
### Recommended
1. Graphics API: OpenGL ES 2.0
2. Android version: Android 5 (API Level 21) or newer
3. Free RAM: 1 GB
4. Free storage: 500 MB
2. Android version: Android 4.4 (API Level 19) or newer
3. Empty RAM: 850 MB
4. Free storage: 480 MB
## Rendering
Unlike on PC, Android devices use OpenGL ES which less powerful than OpenGL, thus
some shader settings cannot be used on OpenGL ES.
Changing the graphic driver setting to OpenGL will not work.
Changing the graphic driver setting to OpenGL will result in undesirable behavior.
## Building Requirements
In order to build, your PC has to be set up to build Luanti in the usual

View file

@ -10,16 +10,14 @@ This list is largely advisory and items may be reevaluated once the time comes.
* `game.conf` name/id mess
* remove `depends.txt` / `description.txt` (would simplify ContentDB and Luanti code a little)
* rotate moon texture by 180°, making it coherent with the sun
* https://github.com/luanti-org/luanti/pull/11902
* https://github.com/minetest/minetest/pull/11902
* remove undocumented `set_physics_override(num, num, num)`
* remove special handling of `${key}` syntax in metadata values
* remove old_move
* change physics_override `sneak` to disable the speed change and not just the node clipping
* https://github.com/luanti-org/luanti/issues/13699
* https://github.com/minetest/minetest/issues/13699
* migrate from player names to UUIDs, this would enable renaming of accounts and unicode player names (if desired)
* harmonize use_texture_alpha between entities & nodes, change default to 'opaque' and remove bool compat code
* merge `sound` and `sounds` table in itemdef
* remove `DIR_DELIM` from Lua
* stop reading initial properties from bare entity def
* change particle default blend mode to `clip`
* remove built-in knockback and related functions entirely

View file

@ -1,12 +1,12 @@
Luanti Lua Client Modding API Reference 5.12.0
Luanti Lua Client Modding API Reference 5.10.0
==============================================
**WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`),
it's now called `core` due to the renaming of Luanti (formerly Minetest).
`minetest` will keep existing as an alias, so that old code won't break.
* More information at <http://www.luanti.org/>
* Developer Wiki: <https://dev.luanti.org/>
* More information at <http://www.minetest.net/>
* Developer Wiki: <http://dev.minetest.net/>
Introduction
------------
@ -23,7 +23,7 @@ Transferring client-sided mods from the server to the client is planned, but not
If you see a deficiency in the API, feel free to attempt to add the
functionality in the engine and API. You can send such improvements as
source code patches on GitHub.
source code patches on GitHub (https://github.com/minetest/minetest).
Programming in Lua
------------------

View file

@ -30,7 +30,6 @@ General options and their default values:
ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend
ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores
ENABLE_OPENSSL=ON - Build with OpenSSL; Speeds up SHA1 and SHA2 hashing
ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds
ENABLE_LTO=<varies> - Build with IPO/LTO optimizations (smaller and more efficient than regular build)
ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua)
@ -62,14 +61,7 @@ Library specific options:
GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains libintl.h
GETTEXT_LIBRARY - Optional/platform-dependent with gettext; path to libintl.so/libintl.dll.a
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
GMP_INCLUDE_DIR - Directory that contains gmp.h
GMP_LIBRARY - Path to libgmp.a/libgmp.so/libgmp.lib
ICONV_LIBRARY - Optional/platform-dependent; path to libiconv.so/libiconv.dylib
JPEG_DLL - Only on Windows; path to libjpeg.dll
JPEG_INCLUDE_DIR - Directory that contains jpeg.h
JPEG_LIBRARY - Path to libjpeg.a/libjpeg.so/libjpeg.lib
JSON_INCLUDE_DIR - Directory that contains json/allocator.h
JSON_LIBRARY - Path to libjson.a/libjson.so/libjson.lib
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
@ -87,12 +79,6 @@ Library specific options:
OPENAL_DLL - Only if building with sound on Windows; path to OpenAL32.dll
OPENAL_INCLUDE_DIR - Only if building with sound; directory where al.h is located
OPENAL_LIBRARY - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib
PNG_DLL - Only on Windows; path to libpng.dll
PNG_INCLUDE_DIR - Directory that contains png.h
PNG_LIBRARY - Path to libpng.a/libpng.so/libpng.lib
PROMETHEUS_PULL_LIBRARY - Only if building with prometheus; path to prometheus-cpp-pull
PROMETHEUS_CORE_LIBRARY - Only if building with prometheus; path to prometheus-cpp-core
PROMETHEUS_CPP_INCLUDE_DIR - Only if building with prometheus; directory where prometheus/counter.h is located
SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h
SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib
VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a

View file

@ -18,31 +18,30 @@
| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present |
| Curl | 7.56.0+ | Optional |
| gettext | - | Optional |
| OpenSSL | 3.0+ | Optional (only libcrypto used) |
For Debian/Ubuntu users:
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext libsdl2-dev
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext
For Fedora users:
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext SDL2-devel
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libXi-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext
For openSUSE users:
sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libvorbis-devel freetype2-devel SDL2-devel
sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libXi-devel libvorbis-devel freetype2-devel
For Arch users:
sudo pacman -S --needed base-devel libcurl-gnutls cmake libpng libjpeg-turbo sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sdl2
sudo pacman -S --needed base-devel libcurl-gnutls cmake libxi libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext
For Alpine users:
sudo apk add build-base cmake libpng-dev jpeg-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sdl2-dev
sudo apk add build-base cmake libpng-dev jpeg-dev libxi-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext
For Void users:
sudo xbps-install cmake libpng-devel jpeg-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext SDL2-devel
sudo xbps-install cmake libpng-devel jpeg-devel libXi-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext
## Download
@ -70,14 +69,14 @@ For Void users:
Download source (this is the URL to the latest of source repository, which might not work at all times) using Git:
git clone --depth 1 https://github.com/luanti-org/luanti
cd luanti
git clone --depth 1 https://github.com/minetest/minetest.git
cd minetest
Download source, without using Git:
wget https://github.com/luanti-org/luanti/archive/master.tar.gz
wget https://github.com/minetest/minetest/archive/master.tar.gz
tar xf master.tar.gz
cd luanti-master
cd minetest-master
## Build
@ -88,7 +87,7 @@ Build a version that runs directly from the source directory:
Run it:
./bin/luanti
./bin/minetest
- Use `cmake . -LH` to see all CMake options and their current state.
- If you want to install it system-wide (or are making a distribution package),

View file

@ -16,13 +16,11 @@ brew install cmake freetype gettext gmp hiredis jpeg-turbo jsoncpp leveldb libog
Download source (this is the URL to the latest of source repository, which might not work at all times) using Git:
```bash
git clone --depth 1 https://github.com/luanti-org/luanti luanti
cd luanti
git clone --depth 1 https://github.com/minetest/minetest.git
cd minetest
```
## Building for personal usage
### Build
## Build
```bash
mkdir build
@ -36,65 +34,12 @@ cmake .. \
make -j$(sysctl -n hw.logicalcpu)
make install
# Apple Silicon (M1/M2) Macs w/ MacOS >= BigSur signature for local run
codesign --force --deep -s - --entitlements ../misc/macos/entitlements/debug.entitlements macos/luanti.app
# M1 Macs w/ MacOS >= BigSur
codesign --force --deep -s - macos/minetest.app
```
If you are using LuaJIT with `MAP_JIT` support use `debug_map_jit.entitlements`.
### Run
## Run
```
open ./build/macos/luanti.app
open ./build/macos/minetest.app
```
## Building for distribution
### Generate Xcode project
```bash
mkdir build
cd build
cmake .. \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE \
-DFREETYPE_LIBRARY=/path/to/lib/dir/libfreetype.a \
-DGETTEXT_INCLUDE_DIR=/path/to/include/dir \
-DGETTEXT_LIBRARY=/path/to/lib/dir/libintl.a \
-DLUA_LIBRARY=/path/to/lib/dir/libluajit-5.1.a \
-DOGG_LIBRARY=/path/to/lib/dir/libogg.a \
-DVORBIS_LIBRARY=/path/to/lib/dir/libvorbis.a \
-DVORBISFILE_LIBRARY=/path/to/lib/dir/libvorbisfile.a \
-DZSTD_LIBRARY=/path/to/lib/dir/libzstd.a \
-DGMP_LIBRARY=/path/to/lib/dir/libgmp.a \
-DJSON_LIBRARY=/path/to/lib/dir/libjsoncpp.a \
-DENABLE_LEVELDB=OFF \
-DENABLE_POSTGRESQL=OFF \
-DENABLE_REDIS=OFF \
-DJPEG_LIBRARY=/path/to/lib/dir/libjpeg.a \
-DPNG_LIBRARY=/path/to/lib/dir/libpng.a \
-DCMAKE_EXE_LINKER_FLAGS=-lbz2\
-GXcode
```
If you are using LuaJIT with `MAP_JIT` support add `-DXCODE_CODE_SIGN_ENTITLEMENTS=../misc/macos/entitlements/release_map_jit.entitlements`.
*WARNING:* You have to regenerate Xcode project if you switch commit, branch or etc.
### Build and Run
* Open generated Xcode project
* Select scheme `luanti`
* Configure signing Team etc.
* Run Build command
* Open application from `build/build/Debug/` directory or run it from Xcode
### Archive and Run
* Open generated Xcode project
* Select scheme `luanti`
* Configure signing Team etc.
* Run Build command
* Open application archive in finder, go into it, copy application and test it.

View file

@ -13,8 +13,9 @@
It is highly recommended to use vcpkg as package manager.
After you successfully built vcpkg you can easily install the required libraries:
```powershell
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] sdl2 --triplet x64-windows
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] opengl-registry --triplet x64-windows
```
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
@ -33,8 +34,8 @@ Use `--triplet` to specify the target triplet, e.g. `x64-windows` or `x86-window
### a) Using the vcpkg toolchain and CMake GUI
1. Start up the CMake GUI
2. Select **Browse Source...** and select DIR/luanti
3. Select **Browse Build...** and select DIR/luanti-build
2. Select **Browse Source...** and select DIR/minetest
3. Select **Browse Build...** and select DIR/minetest-build
4. Select **Configure**
5. Choose the right visual Studio version and target platform. It has to match the version of the installed dependencies
6. Choose **Specify toolchain file for cross-compiling**

View file

@ -2,15 +2,15 @@
## Wiki
Some important development docs are found in the wiki: https://dev.luanti.org/
Some important development docs are found in the wiki: https://dev.minetest.net/
Notable pages:
- [Releasing Luanti](https://dev.luanti.org/Releasing_Luanti)
- [Engine translations](https://dev.luanti.org/Translation#Maintaining_engine_translations)
- [Changelog](https://dev.luanti.org/Changelog)
- [Organisation](https://dev.luanti.org/Organisation)
- [Code style guidelines](https://dev.luanti.org/Code_style_guidelines)
- [Releasing Luanti](https://dev.minetest.net/Releasing_Minetest)
- [Engine translations](https://dev.minetest.net/Translation#Maintaining_engine_translations)
- [Changelog](https://dev.minetest.net/Changelog)
- [Organisation](https://dev.minetest.net/Organisation)
- [Code style guidelines](https://dev.minetest.net/Code_style_guidelines)
## In this folder
@ -23,4 +23,4 @@ Notable pages:
Oftentimes knowledge hasn't been written down (yet) and your best bet is to ask someone experienced and/or the core developers.
Feel free to join the [#minetest-dev IRC](https://wiki.luanti.org/IRC) and ask questions related to **engine development**.
Feel free to join the [#minetest-dev IRC](https://wiki.minetest.net/IRC) and ask questions related to **engine development**.

View file

@ -2,7 +2,7 @@
## Sign the Android APK from CI
The [Github Actions Workflow](https://github.com/luanti-org/luanti/actions?query=workflow%3Aandroid+event%3Apush)
The [Github Actions Workflow](https://github.com/minetest/minetest/actions?query=workflow%3Aandroid+event%3Apush)
automatically produces an APK for each architecture.
Before installing them onto a device they however need to be signed.

View file

@ -9,7 +9,7 @@ To get usable results you need to build Luanti with debug symbols
Run the client (or server) like this and do whatever you wanted to test:
```bash
perf record -z --call-graph dwarf -- ./bin/luanti
perf record -z --call-graph dwarf -- ./bin/minetest
```
This will leave a file called "perf.data".

View file

@ -45,8 +45,13 @@ There's usually no reason to raise this unless the NDK drops older versions.
**Compilers**: gcc, clang and MSVC (exceptions exist)
We require **OpenGL** 2.0 or ES 2.0, so shaders can be relied on.
Graphics code should generally work on both. Newer features can be used as long as a fallback exists.
**OpenGL** is an entirely different beast, there is no formal consensus on changing the requirements
and neither do we have an exact set of requirements.
We still support OpenGL 1.4 without shaders (fixed-pipeline), which could be considered very unreasonable in 2024.
OpenGL ES 2.0 is supported for the sake of mobile platforms.
It has been [proposed](https://irc.minetest.net/minetest-dev/2022-08-18) moving to OpenGL 2.x or 3.0 with shaders required.
General **system requirements** are not bounded either.
Being able to play Luanti on a recent low-end phone is a reasonable target.

View file

@ -6,9 +6,9 @@ The long-term roadmaps, aims, and guiding philosophies are set out using the
following documents:
* [What is Minetest?](http://c55.me/blog/?p=1491)
* [celeron55's roadmap](https://forum.luanti.org/viewtopic.php?t=9177)
* [celeron55's comment in "A clear mission statement for Minetest is missing"](https://github.com/luanti-org/luanti/issues/3476#issuecomment-167399287)
* [Core developer to-do/wish lists](https://forum.luanti.org/viewforum.php?f=7)
* [celeron55's roadmap](https://forum.minetest.net/viewtopic.php?t=9177)
* [celeron55's comment in "A clear mission statement for Minetest is missing"](https://github.com/minetest/minetest/issues/3476#issuecomment-167399287)
* [Core developer to-do/wish lists](https://forum.minetest.net/viewforum.php?f=7)
## 2. Medium-term Roadmap
@ -16,7 +16,7 @@ These are the current medium-term goals for Luanti development, in no
particular order.
These goals were created from the top points in a
[roadmap brainstorm](https://github.com/luanti-org/luanti/issues/10461).
[roadmap brainstorm](https://github.com/minetest/minetest/issues/10461).
This should be reviewed approximately yearly, or when goals are achieved.
Pull requests that address one of these goals will be labeled as "Roadmap".
@ -32,9 +32,9 @@ Once that is done, fancier features can be worked on, such as water shaders,
shadows, and improved lighting.
Examples include
[transparency sorting](https://github.com/luanti-org/luanti/issues/95),
[particle performance](https://github.com/luanti-org/luanti/issues/1414),
[general view distance](https://github.com/luanti-org/luanti/issues/7222).
[transparency sorting](https://github.com/minetest/minetest/issues/95),
[particle performance](https://github.com/minetest/minetest/issues/1414),
[general view distance](https://github.com/minetest/minetest/issues/7222).
This includes work on maintaining
[our Irrlicht fork](https://github.com/minetest/irrlicht), and switching to
@ -43,16 +43,16 @@ alternative libraries to replace Irrlicht functionality as needed
### 2.2 Internal code refactoring
To ensure sustainable development, Luanti's code needs to be
[refactored and improved](https://github.com/luanti-org/luanti/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3A%22Code+quality%22).
[refactored and improved](https://github.com/minetest/minetest/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3A%22Code+quality%22+).
This will remove code rot and allow for more efficient development.
### 2.3 UI Improvements
A [formspec replacement](https://github.com/luanti-org/luanti/issues/6527) is
A [formspec replacement](https://github.com/minetest/minetest/issues/6527) is
needed to make GUIs better and easier to create. This replacement could also
be a replacement for HUDs, allowing for a unified API.
A [new mainmenu](https://github.com/luanti-org/luanti/issues/6733) is needed to
A [new mainmenu](https://github.com/minetest/minetest/issues/6733) is needed to
improve user experience. First impressions matter, and the current main menu
doesn't do a very good job at selling Luanti or explaining what it is.
A new main menu should promote games to users, allowing Minetest Game to no
@ -65,5 +65,5 @@ an issue for any large changes before spending lots of time.
There are still a significant number of issues with objects.
Collisions,
[performance](https://github.com/luanti-org/luanti/issues/6453),
[performance](https://github.com/minetest/minetest/issues/6453),
API convenience, and discrepancies between players and entities.

View file

@ -4,25 +4,22 @@ We provide Luanti server Docker images using the GitHub container registry.
Images are built on each commit and available using the following tag scheme:
* `ghcr.io/luanti-org/luanti:master` (latest build)
* `ghcr.io/luanti-org/luanti:<tag>` (specific Git tag)
* `ghcr.io/luanti-org/luanti:latest` (latest Git tag, which is the stable release)
* `ghcr.io/minetest/minetest:master` (latest build)
* `ghcr.io/minetest/minetest:<tag>` (specific Git tag)
* `ghcr.io/minetest/minetest:latest` (latest Git tag, which is the stable release)
See [here](https://github.com/luanti-org/luanti/pkgs/container/luanti) for all available tags.
Versions released before the project was renamed are available with the same tag scheme at `ghcr.io/minetest/minetest`.
See [here](https://github.com/orgs/minetest/packages/container/package/minetest) for all available tags.
See [here](https://github.com/minetest/minetest/pkgs/container/minetest) for all available tags.
For a quick test you can easily run:
```shell
docker run ghcr.io/luanti-org/luanti:master
docker run ghcr.io/minetest/minetest:master
```
To use it in a production environment, you should use volumes bound to the Docker host to persist data and modify the configuration:
```shell
docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ ghcr.io/luanti-org/luanti:master
docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ ghcr.io/minetest/minetest:master
```
You may also want to use [Docker Compose](https://docs.docker.com/compose):
@ -32,7 +29,7 @@ You may also want to use [Docker Compose](https://docs.docker.com/compose):
version: "2"
services:
minetest_server:
image: ghcr.io/luanti-org/luanti:master
image: ghcr.io/minetest/minetest:master
restart: always
networks:
- default

View file

@ -5,10 +5,10 @@ Luanti Lua Modding API Reference
it's now called `core` due to the renaming of Luanti (formerly Minetest).
`minetest` will keep existing as an alias, so that old code won't break.
* More information at <http://www.luanti.org/>
* Developer Wiki: <https://dev.luanti.org/>
* More information at <http://www.minetest.net/>
* Developer Wiki: <http://dev.minetest.net/>
* (Unofficial) Minetest Modding Book by rubenwardy: <https://rubenwardy.com/minetest_modding_book/>
* Modding tools: <https://github.com/luanti-org/modtools>
* Modding tools: <https://github.com/minetest/modtools>
Introduction
------------
@ -188,14 +188,14 @@ Mod directory structure
│   ├── models
│   ├── textures
│   │   ├── modname_stuff.png
│   │   ├── modname_stuff_normal.png
│   │   ├── modname_something_else.png
│   │   ├── subfolder_foo
│   │   │ ├── modname_more_stuff.png
│   │   │ └── another_subfolder
│   │   └── bar_subfolder
│   ├── sounds
│   ├── fonts
│ ├── media
│   ├── media
│   ├── locale
│   └── <custom data>
└── another
@ -266,7 +266,7 @@ The main Lua script. Running this script should register everything it
wants to register. Subsequent execution depends on Luanti calling the
registered callbacks.
### `textures`, `sounds`, `media`, `models`, `locale`, `fonts`
### `textures`, `sounds`, `media`, `models`, `locale`
Media files (textures, sounds, whatever) that will be transferred to the
client and will be available for use by the mod and translation files for
@ -276,10 +276,9 @@ the clients (see [Translations]). Accepted characters for names are:
Accepted formats are:
images: .png, .jpg, .tga
images: .png, .jpg, .tga, (deprecated:) .bmp
sounds: .ogg vorbis
models: .x, .b3d, .obj, (since version 5.10:) .gltf, .glb
fonts: .ttf, .woff (both since version 5.11, see notes below)
Other formats won't be sent to the client (e.g. you can store .blend files
in a folder for convenience, without the risk that such files are transferred)
@ -310,24 +309,19 @@ it unlocks no special rendering features.
Binary glTF (`.glb`) files are supported and recommended over `.gltf` files
due to their space savings.
Bone weights should be normalized, e.g. using ["normalize all" in Blender](https://docs.blender.org/manual/en/4.2/grease_pencil/modes/weight_paint/weights_menu.html#normalize-all).
You can use the [Khronos glTF validator](https://github.com/KhronosGroup/glTF-Validator)
to check whether a model is a valid glTF file.
Many glTF features are not supported *yet*, including:
This means that many glTF features are not supported *yet*, including:
* Animations
* Only a single animation is supported, use frame ranges within this animation.
* `CUBICSPLINE` interpolation is not supported.
* Only a single animation is supported,
use frame ranges within this animation.
* Only integer frames are supported.
* Cameras
* Materials
* Only base color textures are supported
* Backface culling is overridden
* Double-sided materials don't work
* Alternative means of supplying data
* Embedded images. You can use `gltfutil.py` from the
[modding tools](https://github.com/luanti-org/modtools) to strip or extract embedded images.
* Embedded images
* References to files via URIs
Textures are supplied solely via the same means as for the other model file formats:
@ -344,28 +338,6 @@ For example, if your model used an emissive material,
you should expect that a future version of Luanti may respect this,
and thus cause your model to render differently there.
#### Custom fonts
You can supply custom fonts in TrueType Font (`.ttf`) or Web Open Font Format (`.woff`) format.
The former is supported primarily for convenience. The latter is preferred due to its compression.
In the future, having multiple custom fonts and the ability to switch between them is planned,
but for now this feature is limited to the ability to override Luanti's default fonts via mods.
It is recommended that this only be used by game mods to set a look and feel.
The stems (file names without extension) are self-explanatory:
* Regular variants:
* `regular`
* `bold`
* `italic`
* `bold_italic`
* Monospaced variants:
* `mono`
* `mono_bold`
* `mono_italic`
* `mono_bold_italic`
Naming conventions
------------------
@ -516,7 +488,9 @@ stripping out the file extension:
* e.g. `foomod_foothing.png`
* e.g. `foomod_foothing`
Supported texture formats are PNG (`.png`), JPEG (`.jpg`) and Targa (`.tga`).
Supported texture formats are PNG (`.png`), JPEG (`.jpg`), Bitmap (`.bmp`)
and Targa (`.tga`).
Since better alternatives exist, the latter two may be removed in the future.
Texture modifiers
-----------------
@ -1484,6 +1458,8 @@ Node drawtypes
There are a bunch of different looking node types.
Look for examples in `games/devtest` or `games/minetest_game`.
* `normal`
* A node-sized cube.
* `airlike`
@ -1522,7 +1498,7 @@ There are a bunch of different looking node types.
* `allfaces`
* Often used for partially-transparent nodes.
* External sides of textures, and unlike other drawtypes, the external sides
of other nodes, are visible from the inside.
of other blocks, are visible from the inside.
* `allfaces_optional`
* Often used for leaves nodes.
* This switches between `normal`, `glasslike` and `allfaces` according to
@ -4211,14 +4187,14 @@ Two functions are provided to translate strings: `core.translate` and
* `core.get_translator(textdomain)` is a simple wrapper around
`core.translate` and `core.translate_n`.
After `local S, PS = core.get_translator(textdomain)`, we have
After `local S, NS = core.get_translator(textdomain)`, we have
`S(str, ...)` equivalent to `core.translate(textdomain, str, ...)`, and
`PS(str, str_plural, n, ...)` to `core.translate_n(textdomain, str, str_plural, n, ...)`.
`NS(str, str_plural, n, ...)` to `core.translate_n(textdomain, str, str_plural, n, ...)`.
It is intended to be used in the following way, so that it avoids verbose
repetitions of `core.translate`:
```lua
local S, PS = core.get_translator(textdomain)
local S, NS = core.get_translator(textdomain)
S(str, ...)
```
@ -4252,7 +4228,7 @@ command that shows the amount of time since the player joined. We can do the
following:
```lua
local S, PS = core.get_translator("hello")
local S, NS = core.get_translator("hello")
core.register_on_joinplayer(function(player)
local name = player:get_player_name()
core.chat_send_player(name, S("Hello @1, how are you today?", name))
@ -4261,7 +4237,7 @@ core.register_chatcommand("playtime", {
func = function(name)
local last_login = core.get_auth_handler().get_auth(name).last_login
local playtime = math.floor((last_login-os.time())/60)
return true, PS(
return true, NS(
"You have been playing for @1 minute.",
"You have been playing for @1 minutes.",
minutes, tostring(minutes))
@ -4308,7 +4284,7 @@ After creating the `locale` directory, a translation template for the above
example using the following command:
```sh
xgettext -L lua -kS -kPS:1,2 -kcore.translate:1c,2 -kcore.translate_n:1c,2,3 \
xgettext -L lua -kS -kNS:1,2 -kcore.translate:1c,2 -kcore.translate_n:1c,2,3 \
-d hello -o locale/hello.pot *.lua
```
@ -4368,7 +4344,7 @@ Hello @1, how are you today?=Hallo @1, wie geht es dir heute?
```
For old translation files, consider using the script `mod_translation_updater.py`
in the Luanti [modtools](https://github.com/luanti-org/modtools) repository to
in the Luanti [modtools](https://github.com/minetest/modtools) repository to
generate and update translation files automatically from the Lua sources.
Gettext translation file format
@ -5066,7 +5042,7 @@ inside the VoxelManip.
can use `core.emerge_area` to make sure that the area you want to
read/write is already generated.
* Other mods, or the engine itself, could possibly modify the area of the map
* Other mods, or the core itself, could possibly modify the area of the map
currently loaded into a VoxelManip object. With the exception of Mapgen
VoxelManips (see above section), the internal buffers are not updated. For
this reason, it is strongly encouraged to complete the usage of a particular
@ -5081,11 +5057,9 @@ inside the VoxelManip.
Methods
-------
* `read_from_map(p1, p2)`: Loads a chunk of map into the VoxelManip object
* `read_from_map(p1, p2)`: Loads a chunk of map into the VoxelManip object
containing the region formed by `p1` and `p2`.
* returns actual emerged `pmin`, actual emerged `pmax`
* Note that calling this multiple times will *add* to the area loaded in the
VoxelManip, and not reset it.
* `write_to_map([light])`: Writes the data loaded from the `VoxelManip` back to
the map.
* **important**: data must be set using `VoxelManip:set_data()` before
@ -5144,8 +5118,8 @@ Methods
generated mapchunk above are propagated down into the mapchunk, defaults
to `true` if left out.
* `update_liquids()`: Update liquid flow
* `was_modified()`: Returns `true` if the data in the VoxelManip has been modified
since it was last read from the map. This means you have to call `get_data()` again.
* `was_modified()`: Returns `true` if the data in the voxel manipulator has been modified
since it was last read from the map. This means you have to call `get_data` again.
This only applies to a `VoxelManip` object from `core.get_mapgen_object`,
where the engine will keep the map and the VM in sync automatically.
* Note: this doesn't do what you think it does and is subject to removal. Don't use it!
@ -5578,7 +5552,7 @@ Utilities
* It's possible that multiple Luanti instances are running at the same
time, which may lead to corruption if you are not careful.
* `core.is_singleplayer()`
* `core.features`: Table containing *server-side* API feature flags
* `core.features`: Table containing API feature flags
```lua
{
@ -5685,17 +5659,10 @@ Utilities
bulk_lbms = true,
-- ABM supports field without_neighbors (5.10.0)
abm_without_neighbors = true,
-- biomes have a weight parameter (5.11.0)
biome_weights = true,
-- Particles can specify a "clip" blend mode (5.11.0)
particle_blend_clip = true,
-- The `match_meta` optional parameter is available for `InvRef:remove_item()` (5.12.0)
remove_item_match_meta = true,
}
```
* `core.has_feature(arg)`: returns `boolean, missing_features`
* checks for *server-side* feature availability
* `arg`: string or table in format `{foo=true, bar=true}`
* `missing_features`: `{foo=true, bar=true}`
* `core.get_player_information(player_name)`: Table containing information
@ -5717,37 +5684,14 @@ Utilities
min_jitter = 0.01, -- minimum packet time jitter
max_jitter = 0.5, -- maximum packet time jitter
avg_jitter = 0.03, -- average packet time jitter
-- The version information is provided by the client and may be spoofed
-- or inconsistent in engine forks. You must not use this for checking
-- feature availability of clients. Instead, do use the fields
-- `protocol_version` and `formspec_version` where it matters.
-- Use `core.protocol_versions` to map Luanti versions to protocol versions.
-- This version string is only suitable for analysis purposes.
version_string = "0.4.9-git", -- full version string
-- the following information is available in a debug build only!!!
-- DO NOT USE IN MODS
--serialization_version = 26, -- serialization version used by client
--major = 0, -- major version number
--minor = 4, -- minor version number
--patch = 10, -- patch version number
--state = "Active" -- current client state
}
```
* `core.protocol_versions`:
* Table mapping Luanti versions to corresponding protocol versions for modder convenience.
* For example, to check whether a client has at least the feature set
of Luanti 5.8.0 or newer, you could do:
`core.get_player_information(player_name).protocol_version >= core.protocol_versions["5.8.0"]`
* (available since 5.11)
```lua
{
[version string] = protocol version at time of release
-- every major and minor version has an entry
-- patch versions only for the first release whose protocol version is not already present in the table
--ser_vers = 26, -- serialization version used by client
--major = 0, -- major version number
--minor = 4, -- minor version number
--patch = 10, -- patch version number
--vers_string = "0.4.9-git", -- full version string
--state = "Active" -- current client state
}
```
@ -6236,7 +6180,7 @@ Setting-related
* `core.settings`: Settings object containing all of the settings from the
main config file (`minetest.conf`). See [`Settings`].
* `core.setting_get_pos(name)`: Loads a setting from the main settings and
parses it as a position (in the format `(1,2,3)`). Returns a position or nil. **Deprecated: use `core.settings:get_pos()` instead**
parses it as a position (in the format `(1,2,3)`). Returns a position or nil.
Authentication
--------------
@ -6615,7 +6559,7 @@ Environment access
* `pointabilities`: Allows overriding the `pointable` property of
nodes and objects. Uses the same format as the `pointabilities` property
of item definitions. Default is `nil`.
* `core.find_path(pos1, pos2, searchdistance, max_jump, max_drop, algorithm)`
* `core.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
* returns table containing path that can be walked on
* returns a table of 3D points representing a path from `pos1` to `pos2` or
`nil` on failure.
@ -6635,11 +6579,8 @@ Environment access
Difference between `"A*"` and `"A*_noprefetch"` is that
`"A*"` will pre-calculate the cost-data, the other will calculate it
on-the-fly
* `core.spawn_tree(pos, treedef)`
* `core.spawn_tree (pos, {treedef})`
* spawns L-system tree at given `pos` with definition in `treedef` table
* `core.spawn_tree_on_vmanip(vmanip, pos, treedef)`
* analogous to `core.spawn_tree`, but spawns a L-system tree onto the specified
VoxelManip object `vmanip` instead of the map.
* `core.transforming_liquid_add(pos)`
* add node to liquid flow update queue
* `core.get_node_max_level(pos)`
@ -6758,9 +6699,6 @@ Formspec
* `core.hypertext_escape(string)`: returns a string
* escapes the characters "\", "<", and ">" to show text in a hypertext element.
* not safe for use with tag attributes.
* this function does not do formspec escaping, you will likely need to do
`core.formspec_escape(core.hypertext_escape(string))` if the hypertext is
not already being formspec escaped.
* `core.explode_table_event(string)`: returns a table
* returns e.g. `{type="CHG", row=1, column=2}`
* `type` is one of:
@ -7456,8 +7394,7 @@ Misc.
* This function can be overridden by mods to change the leave message.
* `core.hash_node_position(pos)`: returns a 48-bit integer
* `pos`: table {x=number, y=number, z=number},
* Gives a unique numeric encoding for a node position (16+16+16=48bit)
* Despite the name, this is not a hash function (so it doesn't mix or produce collisions).
* Gives a unique hash number for a node position (16+16+16=48bit)
* `core.get_position_from_hash(hash)`: returns a position
* Inverse transform of `core.hash_node_position`
* `core.get_item_group(name, group)`: returns a rating
@ -7875,15 +7812,13 @@ An `InvRef` is a reference to an inventory.
can be fully added to the list
* `contains_item(listname, stack, [match_meta])`: returns `true` if
the stack of items can be fully taken from the list.
* If `match_meta` is `true`, item metadata is also considered when comparing
items. Otherwise, only the items names are compared. Default: `false`
* The method ignores wear.
* `remove_item(listname, stack, [match_meta])`: take as many items as specified from the
list, returns the items that were actually removed (as an `ItemStack`).
* If `match_meta` is `true` (available since feature `remove_item_match_meta`),
item metadata is also considered when comparing items. Otherwise, only the
items names are compared. Default: `false`
* The method ignores wear.
If `match_meta` is false, only the items' names are compared
(default: `false`).
* `remove_item(listname, stack)`: take as many items as specified from the
list, returns the items that were actually removed (as an `ItemStack`)
-- note that any item metadata is ignored, so attempting to remove a specific
unique item this way will likely remove the wrong one -- to do that use
`set_stack` with an empty `ItemStack`.
* `get_location()`: returns a location compatible to
`core.get_inventory(location)`.
* returns `{type="undefined"}` in case location is not known
@ -8311,13 +8246,7 @@ child will follow movement and rotation of that bone.
object.
* `set_detach()`: Detaches object. No-op if object was not attached.
* `set_bone_position([bone, position, rotation])`
* Sets absolute bone overrides, e.g. it is equivalent to
```lua
obj:set_bone_override(bone, {
position = {vec = position, absolute = true},
rotation = {vec = rotation:apply(math.rad), absolute = true}
})
```
* Shorthand for `set_bone_override(bone, {position = position, rotation = rotation:apply(math.rad)})` using absolute values.
* **Note:** Rotation is in degrees, not radians.
* **Deprecated:** Use `set_bone_override` instead.
* `get_bone_position(bone)`: returns the previously set position and rotation of the bone
@ -8327,18 +8256,15 @@ child will follow movement and rotation of that bone.
* `set_bone_override(bone, override)`
* `bone`: string
* `override`: `{ position = property, rotation = property, scale = property }` or `nil`
* `override = nil` (including omission) is shorthand for `override = {}` which clears the override
* Each `property` is a table of the form
`{ vec = vector, interpolation = 0, absolute = false }` or `nil`
* `vec` is in the same coordinate system as the model, and in radians for rotation.
It defaults to `vector.zero()` for translation and rotation and `vector.new(1, 1, 1)` for scale.
* `interpolation`: The old and new overrides are interpolated over this timeframe (in seconds).
* `absolute`: If set to `false` (which is the default),
the override will be relative to the animated property:
* Translation in the case of `position`;
* `property`: `{ vec = vector, interpolation = 0, absolute = false}` or `nil`;
* `vec` is in the same coordinate system as the model, and in degrees for rotation
* `property = nil` is equivalent to no override on that property
* `absolute`: If set to `false`, the override will be relative to the animated property:
* Transposition in the case of `position`;
* Composition in the case of `rotation`;
* Per-axis multiplication in the case of `scale`
* `property = nil` is equivalent to no override on that property
* Multiplication in the case of `scale`
* `interpolation`: Old and new values are interpolated over this timeframe (in seconds)
* `override = nil` (including omission) is shorthand for `override = {}` which clears the override
* **Note:** Unlike `set_bone_position`, the rotation is in radians, not degrees.
* Compatibility note: Clients prior to 5.9.0 only support absolute position and rotation.
All values are treated as absolute and are set immediately (no interpolation).
@ -8832,14 +8758,6 @@ child will follow movement and rotation of that bone.
Same limits as for `thirdperson_back` apply.
Defaults to `thirdperson_back` if unspecified.
* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`.
* `set_camera(params)`: Sets camera parameters.
* `mode`: Defines the camera mode used
- `any`: free choice between all modes (default)
- `first`: first-person camera
- `third`: third-person camera
- `third_front`: third-person camera, looking opposite of movement direction
* Supported by client since 5.12.0.
* `get_camera()`: Returns the camera parameters as a table as above.
* `send_mapblock(blockpos)`:
* Sends an already loaded mapblock to the player.
* Returns `false` if nothing was sent (note that this can also mean that
@ -8965,7 +8883,7 @@ For `core.get_perlin_map()`, the actual seed used is the noiseparams seed
plus the world seed, to create world-specific noise.
Format of `size` is `{x=dimx, y=dimy, z=dimz}`. The `z` component is omitted
for 2D noise, and it must be larger than 1 for 3D noise (otherwise
for 2D noise, and it must be must be larger than 1 for 3D noise (otherwise
`nil` is returned).
For each of the functions with an optional `buffer` parameter: If `buffer` is
@ -9121,9 +9039,6 @@ means that no defaults will be returned for mod settings.
* Is currently limited to mapgen flags `mg_flags` and mapgen-specific
flags like `mgv5_spflags`.
* Returns `nil` if `key` is not found.
* `get_pos(key)`:
* Returns a `vector`
* Returns `nil` if no value is found or parsing failed.
* `set(key, value)`
* Setting names can't contain whitespace or any of `="{}#`.
* Setting values can't contain the sequence `\n"""`.
@ -9134,9 +9049,6 @@ means that no defaults will be returned for mod settings.
* `set_np_group(key, value)`
* `value` is a NoiseParams table.
* Also, see documentation for `set()` above.
* `set_pos(key, value)`
* `value` is a `vector`.
* Also, see documentation for `set()` above.
* `remove(key)`: returns a boolean (`true` for success)
* `get_names()`: returns `{key1,...}`
* `has(key)`:
@ -9234,7 +9146,7 @@ Player properties need to be saved manually.
-- Clients older than 5.9.0 interpret `pointable = "blocking"` as `pointable = true`.
-- Can be overridden by the `pointabilities` of the held item.
visual = "",
visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
-- "cube" is a node-sized cube.
-- "sprite" is a flat texture always facing the player.
-- "upright_sprite" is a vertical flat texture.
@ -9256,8 +9168,6 @@ Player properties need to be saved manually.
-- Wielditems are scaled a bit. If you want a wielditem to appear
-- to be as large as a node, use `0.667` in `visual_size`
-- "item" is similar to "wielditem" but ignores the 'wield_image' parameter.
-- "node" looks exactly like a node in-world (supported since 5.12.0)
-- Note that visual effects like waving or liquid reflections will not work.
visual_size = {x = 1, y = 1, z = 1},
-- Multipliers for the visual size. If `z` is not specified, `x` will be used
@ -9267,7 +9177,7 @@ Player properties need to be saved manually.
-- File name of mesh when using "mesh" visual
textures = {},
-- Number of required textures depends on visual:
-- Number of required textures depends on visual.
-- "cube" uses 6 textures just like a node, but all 6 must be defined.
-- "sprite" uses 1 texture.
-- "upright_sprite" uses 2 textures: {front, back}.
@ -9275,16 +9185,13 @@ Player properties need to be saved manually.
-- Deprecated usage of "wielditem" expects 'textures = {itemname}' (see 'visual' above).
colors = {},
-- Currently unused.
node = {name = "ignore", param1=0, param2=0},
-- Node to show when using the "node" visual
-- Number of required colors depends on visual
use_texture_alpha = false,
-- Use texture's alpha channel for transparency blending.
-- Use texture's alpha channel.
-- Excludes "upright_sprite" and "wielditem".
-- Note: currently causes visual issues when viewed through other
-- semi-transparent materials such as water.
-- Note: ignored for "item", "wielditem" and "node" visual.
spritediv = {x = 1, y = 1},
-- Used with spritesheet textures for animation and/or frame selection
@ -9301,7 +9208,7 @@ Player properties need to be saved manually.
-- If false, object is invisible and can't be pointed.
makes_footstep_sound = false,
-- If true, object is able to make footstep sounds of nodes
-- If true, is able to make footstep sounds of nodes
-- (see node sound definition for details).
automatic_rotate = 0,
@ -9324,7 +9231,6 @@ Player properties need to be saved manually.
backface_culling = true,
-- Set to false to disable backface_culling for model
-- Note: only used by "mesh" and "cube" visual
glow = 0,
-- Add this much extra lighting when calculating texture color.
@ -9360,7 +9266,6 @@ Player properties need to be saved manually.
shaded = true,
-- Setting this to 'false' disables diffuse lighting of entity
-- Note: ignored for "item", "wielditem" and "node" visual
show_on_minimap = false,
-- Defaults to true for players, false for other entities.
@ -10797,10 +10702,6 @@ performance and computing power the practical limit is much lower.
-- distribution of the biomes.
-- Heat and humidity have average values of 50, vary mostly between
-- 0 and 100 but can exceed these values.
weight = 1.0,
-- Relative weight of the biome in the Voronoi diagram.
-- A value of 0 (or less) is ignored and equivalent to 1.0.
}
```
@ -10874,9 +10775,10 @@ See [Decoration types]. Used by `core.register_decoration`.
flags = "liquid_surface, force_placement, all_floors, all_ceilings",
-- Flags for all decoration types.
-- "liquid_surface": Find the highest liquid (not solid) surface under
-- open air. Search stops and fails on the first solid node.
-- Cannot be used with "all_floors" or "all_ceilings" below.
-- "liquid_surface": Instead of placement on the highest solid surface
-- in a mapchunk column, placement is on the highest liquid surface.
-- Placement is disabled if solid nodes are found above the liquid
-- surface.
-- "force_placement": Nodes other than "air" and "ignore" are replaced
-- by the decoration.
-- "all_floors", "all_ceilings": Instead of placement on the highest
@ -11571,14 +11473,6 @@ texture = {
-- (default) blends transparent pixels with those they are drawn atop
-- according to the alpha channel of the source texture. useful for
-- e.g. material objects like rocks, dirt, smoke, or node chunks
-- note: there will be rendering bugs when particles interact with
-- translucent nodes. particles are also not transparency-sorted
-- relative to each other.
blend = "clip",
-- pixels are either fully opaque or fully transparent,
-- depending on whether alpha is greater than or less than 50%
-- (just like `use_texture_alpha = "clip"` for nodes).
-- you should prefer this if you don't need semi-transparency, as it's faster.
blend = "add",
-- adds the value of pixels to those underneath them, modulo the sources
-- alpha channel. useful for e.g. bright light effects like sparks or fire

View file

@ -1,3 +1,3 @@
Moved to lua_api.md
URL: https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md
URL: https://github.com/minetest/minetest/blob/master/doc/lua_api.md

View file

@ -124,7 +124,7 @@ Colon delimited list of directories to search for mods.
Path to Luanti user data directory.
.SH BUGS
Please report all bugs at https://github.com/luanti-org/luanti/issues.
Please report all bugs at https://github.com/minetest/minetest/issues.
.SH AUTHOR
.PP
@ -134,4 +134,4 @@ This man page was originally written by
Juhani Numminen <juhaninumminen0@gmail.com>.
.SH WWW
http://www.luanti.org/
http://www.minetest.net/

View file

@ -1,7 +1,7 @@
/** @mainpage The Luanti engine internal documentation
/** @mainpage The Minetest engine internal documentation
Welcome to the Luanti engine Doxygen documentation site!\n
This page documents the internal structure of the Luanti engine's C++ code.\n
Welcome to the Minetest engine Doxygen documentation site!\n
This page documents the internal structure of the Minetest engine's C++ code.\n
Use the tree view at the left to navigate.
*/

View file

@ -1,4 +1,4 @@
Luanti Lua Mainmenu API Reference 5.12.0
Luanti Lua Mainmenu API Reference 5.10.0
========================================
Introduction
@ -105,6 +105,11 @@ of manually putting one, as different OSs use different delimiters. E.g.
* `spec` = `SimpleSoundSpec` (see `lua_api.md`)
* `looped` = bool
* `handle:stop()` or `core.sound_stop(handle)`
* `core.get_video_drivers()`
* get list of video drivers supported by engine (not all modes are guaranteed to work)
* returns list of available video drivers' settings name and 'friendly' display name
e.g. `{ {name="opengl", friendly_name="OpenGL"}, {name="software", friendly_name="Software Renderer"} }`
* first element of returned list is guaranteed to be the NULL driver
* `core.get_mapgen_names([include_hidden=false])` -> table of map generator algorithms
registered in the core (possible in async calls)
* `core.get_cache_path()` -> path of cache
@ -218,7 +223,6 @@ GUI
* `core.set_clouds(<true/false>)`
* `core.set_topleft_text(text)`
* `core.show_keys_menu()`
* `core.show_touchscreen_layout()`
* `core.show_path_select_dialog(formname, caption, is_file_select)`
* shows a path select dialog
* `formname` is base name of dialog response returned in fields
@ -382,7 +386,7 @@ Settings
* `core.settings:save()` -> nil, save all settings to config file
For a complete list of methods of the `Settings` object see
[lua_api.md](./lua_api.md)
[lua_api.md](https://github.com/minetest/minetest/blob/master/doc/lua_api.md)
Worlds

View file

@ -281,27 +281,15 @@ storing coordinates separately), but the format has been kept unchanged for
that part.
## `map.sqlite`
`map.sqlite` is an `SQLite3` database, containing a single table, called
`map.sqlite` is a `SQLite3` database, containing a single table, called
`blocks`. It looks like this:
```sql
CREATE TABLE `blocks` (
`x` INTEGER, `y` INTEGER, `z` INTEGER,
`data` BLOB NOT NULL,
PRIMARY KEY (`x`, `z`, `y`)
);
```
Before 5.12.0 it looked like this:
```sql
CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY, `data` BLOB);
```
## Position Hashing
Applies to the pre-5.12.0 schema:
`pos` (a node position hash) is created from the three coordinates of a
`MapBlock` using this algorithm, defined here in Python:
@ -347,8 +335,8 @@ See below for description.
> * NOTE: Byte order is MSB first (big-endian).
> * NOTE: Zlib data is in such a format that Python's `zlib` at least can
> directly decompress.
> * NOTE: Since version 29 zstd is used instead of zlib. In addition, the
> **entire block** is first serialized and then compressed (except version byte).
> * NOTE: Since version 29 zstd is used instead of zlib. In addition, the entire
> block is first serialized and then compressed (except the version byte).
`u8` version
* map format version number, see serialization.h for the latest number

View file

@ -1,7 +0,0 @@
Luanti is a voxel-based game platform with multiplayer capabilities.
The objective of the available games varies, from sandbox games where you can explore, dig and build in a very large voxel world, to arcade-style games.
There is a wide range of built-in map generators for procedurally generated terrain, and voxel-based lighting that adapts to the environment and light sources.
All games and mods are written in Lua with a scripting API that is easy to use and makes it easy for modders to get started.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View file

@ -1 +0,0 @@
Voxel-based multiplayer game platform

View file

@ -1 +0,0 @@
Luanti

Some files were not shown because too many files have changed in this diff Show more