2 new chapters translated by gamer777
This commit is contained in:
parent
c32f3d7f5d
commit
f11bcafd86
174
_de/advmap/lvm.md
Normal file
174
_de/advmap/lvm.md
Normal file
@ -0,0 +1,174 @@
|
||||
---
|
||||
title: Lua Voxel Manipulatoren
|
||||
layout: default
|
||||
root: ../..
|
||||
idx: 6.2
|
||||
description: Erfahren Sie, wie Sie LVMs nutzen können, um Map-Operationen zu beschleunigen.
|
||||
redirect_from:
|
||||
- /de/chapters/lvm.html
|
||||
- /de/map/lvm.html
|
||||
mapgen_object:
|
||||
level: warning
|
||||
title: LVMs und Mapgen
|
||||
message: Verwenden Sie nicht `minetest.get_voxel_manip()` mit mapgen, da dies zu Störungen führen kann.
|
||||
Verwenden Sie stattdessen `minetest.get_mapgen_object("voxelmanip")`.
|
||||
---
|
||||
|
||||
## Einleitung <!-- omit in toc -->
|
||||
|
||||
Die im Kapitel [Grundlegende Kartenoperationen](environment.html) beschriebenen Funktionen sind bequem und einfach zu benutzen, aber für große Gebiete sind sie ineffizient. Jedes Mal, wenn Sie `set_node` oder `get_node` aufrufen, muss Ihr Mod mit der Engine kommunizieren. Dies führt zu ständigen einzelnen Kopiervorgängen zwischen der
|
||||
Engine und Ihrem Mod, was langsam ist und die Leistung des Spiels schnell verringert. Die Verwendung eines Lua Voxel Manipulators (LVM) kann eine gute Alternative sein.
|
||||
|
||||
- [Konzepte](#konzepte)
|
||||
- [Einlesen in die LVM](#einlesen-in-den-lvm)
|
||||
- [Knoten lesen](#knoten-lesen)
|
||||
- [Knoten schreiben](#knoten-schreiben)
|
||||
- [Beispiel](#beispiel)
|
||||
- [Sie sind dran](#sie-sind-dran)
|
||||
|
||||
## Konzepte
|
||||
|
||||
Ein LVM ermöglicht es Ihnen, große Bereiche der Karte in den Speicher Ihres Mods zu laden. Sie können diese Daten dann ohne weitere Interaktion mit der Engine und ohne die Ausführung von Callbacks lesen und schreiben, was bedeutet, dass diese Operationen sehr schnell sind. Anschließend können Sie den Bereich wieder in die Engine zurückschreiben und Beleuchtungsberechnungen durchführen.
|
||||
|
||||
## Einlesen in den LVM
|
||||
|
||||
Sie können nur einen kubischen Bereich in einen LVM laden, also müssen Sie die minimalen und maximalen Positionen ausarbeiten, die Sie ändern möchten. Dann können Sie einen LVM erstellen und einlesen LVM einlesen. Zum Beispiel:
|
||||
|
||||
```lua
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
```
|
||||
|
||||
Aus Leistungsgründen wird ein LVM fast nie genau den Bereich lesen, den Sie ihm vorgeben. Stattdessen wird er wahrscheinlich einen größeren Bereich lesen. Der größere Bereich wird durch `emin` und `emax` angegeben, die für *emerged min pos* und *emerged max pos* stehen, auf Deutch: *Ermittelte Minimum-Position* bzw. *Ermittelte Maximum-Position*. Ein LVM lädt den Bereich, den er enthält, für Sie - sei es durch Laden aus dem Speicher, von der Festplatte oder Aufruf des Map-Generators.
|
||||
|
||||
{% include notice.html notice=page.mapgen_object %}
|
||||
|
||||
## Knoten lesen
|
||||
|
||||
Um die Typen von Knoten an bestimmten Positionen zu lesen, müssen Sie `get_data()` verwenden. Dies gibt ein flaches Array zurück, in dem jeder Eintrag den Typ eines bestimmten Knotens darstellt.
|
||||
|
||||
```lua
|
||||
local data = vm:get_data()
|
||||
```
|
||||
|
||||
Sie können param2 und Beleuchtungsdaten mit den Methoden `get_param2_data()` und `get_light_data()` erhalten.
|
||||
|
||||
Sie müssen `emin` und `emax` verwenden, um herauszufinden, wo ein Knoten in den flachen Arrays ist, die durch die oben genannten Methoden gegeben sind. Es gibt eine Hilfsklasse namens `VoxelArea`, die die die die Berechnung für Sie übernimmt.
|
||||
|
||||
```lua
|
||||
local a = VoxelArea:new{
|
||||
MinEdge = emin,
|
||||
MaxEdge = emax
|
||||
}
|
||||
|
||||
-- Get node's index
|
||||
local idx = a:index(x, y, z)
|
||||
|
||||
-- Read node
|
||||
print(data[idx])
|
||||
```
|
||||
|
||||
Wenn Sie den obigen Code ausführen, werden Sie feststellen, dass `data[vi]` eine Ganzzahl ist. Das ist so, weil die Engine aus Leistungsgründen keine Knoten in Form von Zeichenketten speichert. Stattdessen verwendet die Engine eine ganze Zahl, die sogenannte Inhalts-ID. Sie können die Inhalts-ID für einen bestimmten Knotentyp herausfinden mit `get_content_id()` herausfinden. Zum Beispiel:
|
||||
|
||||
```lua
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
```
|
||||
|
||||
Sie können dann überprüfen, ob der Knoten zum Beispiel Stein ist:
|
||||
|
||||
```lua
|
||||
local idx = a:index(x, y, z)
|
||||
if data[idx] == c_stone then
|
||||
print("ist Stein!")
|
||||
end
|
||||
```
|
||||
|
||||
Die Inhalts-IDs eines Knotentyps können sich während der Ladezeit ändern, daher wird es nicht empfohlen, diese während dieser Zeit abzurufen.
|
||||
|
||||
Knoten in einem LVM-Datenarray werden in umgekehrter oordinatenreihenfolge gespeichert. Deshalb sollten Sie immer in der Reihenfolge `z, y, x` *iterieren* (umdrehen). Zum Beispiel:
|
||||
|
||||
```lua
|
||||
for z = min.z, max.z do
|
||||
for y = min.y, max.y do
|
||||
for x = min.x, max.x do
|
||||
-- vi, voxel index, is a common variable name here
|
||||
local vi = a:index(x, y, z)
|
||||
if data[vi] == c_stone then
|
||||
print("ist Stein!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Der Grund dafür liegt im Bereich der Computerarchitektur. Das Lesen aus dem RAM ist ziemlich kostspielig, daher verfügen CPUs über mehrere Caching-Ebenen. Wenn die Daten, die ein Prozess anfordert,
|
||||
im Cache sind, kann er sie sehr schnell abrufen. Wenn sich die Daten nicht im Cache befinden, kommt es zu einem Cache-Miss und der Prozess holt sich die benötigten Daten aus dem RAM. Alles,
|
||||
was die angeforderten Daten umgibt, wird ebenfalls geholt und ersetzt dann die Daten im Cache. Dies geschieht, weil es sehr wahrscheinlich ist, dass der Prozess erneut Daten in der Nähe dieser Stelle anfordert. Das bedeutet, dass es eine gute Optimierungsregel ist, so zu iterieren, dass die Daten nacheinander gelesen werden und *Chache Trashing* zu vermeiden.
|
||||
|
||||
## Knoten schreiben
|
||||
|
||||
Zunächst müssen Sie eine neue Inhalts-ID im Datenfeld festlegen:
|
||||
|
||||
```lua
|
||||
for z = min.z, max.z do
|
||||
for y = min.y, max.y do
|
||||
for x = min.x, max.x do
|
||||
local vi = a:index(x, y, z)
|
||||
if data[vi] == c_stone then
|
||||
data[vi] = c_air
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Wenn Sie die Einstellung der Knoten im LVM abgeschlossen haben, müssen Sie das Daten Array in die Engine hochladen:
|
||||
|
||||
```lua
|
||||
vm:set_data(data)
|
||||
vm:write_to_map(true)
|
||||
```
|
||||
|
||||
Zum Setzen von Beleuchtungs- und Param2-Daten verwenden Sie, wie schon erwähnt, die entsprechend benannten Methoden `set_light_data()` und `set_param2_data()`.
|
||||
|
||||
Die Methode `write_to_map()` nimmt einen booleschen Wert an, der `true` ist, wenn die Beleuchtung berechnet werden soll. Wenn Sie `false` übergeben, müssen Sie die Beleuchtung zu einem späteren Zeitpunkt mit `minetest.fix_light` neu berechnen lassen.
|
||||
|
||||
## Beispiel
|
||||
|
||||
```lua
|
||||
local function grass_to_dirt(pos1, pos2)
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_grass = minetest.get_content_id("default:dirt_with_grass")
|
||||
|
||||
-- Read data into LVM
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
local a = VoxelArea:new{
|
||||
MinEdge = emin,
|
||||
MaxEdge = emax
|
||||
}
|
||||
local data = vm:get_data()
|
||||
|
||||
-- Modify data
|
||||
for z = pos1.z, pos2.z do
|
||||
for y = pos1.y, pos2.y do
|
||||
for x = pos1.x, pos2.x do
|
||||
local vi = a:index(x, y, z)
|
||||
if data[vi] == c_grass then
|
||||
data[vi] = c_dirt
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Write data
|
||||
vm:set_data(data)
|
||||
vm:write_to_map(true)
|
||||
end
|
||||
```
|
||||
|
||||
## Sie sind dran
|
||||
|
||||
* Erstellen Sie `replace_in_area(from, to, pos1, pos2)`, das alle Instanzen von `von` durch `bis` in dem angegebenen Bereich ersetzt, wobei `von` und `bis` Knotennamen sind.
|
||||
* Programmieren Sie eine Funktion, die alle Brustknoten um 90° dreht.
|
||||
* Erstellen Sie eine Funktion, die einen LVM benutzt, um zu bewirken, dass sich moosiges Kopfsteinpflaster auf nahegelegene Stein- und Pflastersteinknoten ausbreitet. Verursacht Ihre Implementierung, dass sich das Moospflaster auf mehr als einen Knoten ausbreitet? Wenn ja, wie können Sie dies verhindern?
|
157
_de/quality/translations.md
Normal file
157
_de/quality/translations.md
Normal file
@ -0,0 +1,157 @@
|
||||
---
|
||||
title: Übersetzung (i18n / l10n)
|
||||
layout: default
|
||||
root: ../..
|
||||
idx: 8.05
|
||||
marked_text_encoding:
|
||||
level: info
|
||||
title: Markierter-Text-Kodierung
|
||||
message: |
|
||||
Sie müssen das genaue Format des markierten Textes nicht kennen, aber es könnte Ihnen helfen Sie zu verstehen.
|
||||
|
||||
```
|
||||
"\27(T@mymod)Hello everyone!\27E"
|
||||
```
|
||||
|
||||
* `\27` is the escape character - it's used to tell Minetest to pay attention as
|
||||
something special is coming up. This is used for both translations and text
|
||||
colorisation.
|
||||
* `(T@mymod)` says that the following text is translatable using the `mymod`
|
||||
textdomain.
|
||||
* `Hello everyone!` is the translatable text in English, as passed to the
|
||||
translator function.
|
||||
* `\27E` is the escape character again and `E`, used to signal that the end has
|
||||
been reached.
|
||||
---
|
||||
|
||||
## Introduction <!-- omit in toc -->
|
||||
|
||||
Wenn Sie Ihre Mods und Spiele mit Übersetzungsunterstützung versehen, können mehr Menschen sie genießen. Laut Google Play haben 64 % der Minetest-Android-Nutzer Englisch nicht als ihre Hauptsprache. Minetest verfolgt keine Statistiken für Benutzer
|
||||
über alle Plattformen hinweg, aber es ist wahrscheinlich, dass es einen hohen Anteil an
|
||||
nicht-englischsprachiger Benutzer gibt.
|
||||
|
||||
Minetest ermöglicht es Ihnen, Ihre Mods und Spiele in verschiedene Sprachen zu übersetzen, indem Sie Texte auf Englisch verfassen und mit Hilfe von Übersetzungsdateien in übersetzen. Die Übersetzung wird auf dem Client eines jeden Spielers durchgeführt, so dass jeder Spieler eine andere Sprache sieht.
|
||||
|
||||
|
||||
- [Wie funktioniert die clientseitige Übersetzung?](#wie-funktioniert-die-clientseitige-übersetzung)
|
||||
- [Markierter Text](#markierter-text)
|
||||
- [Übersetzungsdateien](#übersetzungsdateien)
|
||||
- [Formatierte Zeichenketten](#formatierte-zeichenketten)
|
||||
- [Beste Verfahren und verbreitete Unwahrheiten über die Übersetzung](#verfahren)
|
||||
- [Server-seitige Übersetzungen](#server)
|
||||
- [Zusammenfassung](#zusammenfassung)
|
||||
|
||||
|
||||
## Wie funktioniert die clientseitige Übersetzung?
|
||||
|
||||
### Markierter Text
|
||||
|
||||
Der Server muss den Clients mitteilen, wie der Text zu übersetzen ist. Dies geschieht durch die Platzierung von Kontrollzeichen im Text, die Minetest mitteilen, wo und wie der Text zu übersetzen ist. Dies wird als *markierter Text* bezeichnet und wird später näher erläutert.
|
||||
|
||||
Um Text als übersetzbar zu markieren, verwenden Sie eine Übersetzungsfunktion (`S()`), die Sie mit `minetest.get_translator(textdomain)` nutzen können`:
|
||||
|
||||
```lua
|
||||
local S = minetest.get_translator("mymod")
|
||||
|
||||
minetest.register_craftitem("mymod:item", {
|
||||
description = S("My Item"),
|
||||
})
|
||||
```
|
||||
|
||||
Das erste Argument von `get_translator` ist `textdomain`, die als Namensraum dient. Anstatt alle Übersetzungen für eine Sprache in einer einzigen Datei zu speichern, werden die Übersetzungen in Textdomänen aufgeteilt (eine Datei pro Textdomäne
|
||||
pro Sprache). Die Textdomain sollte mit dem Namen des Mods übereinstimmen, da dies hilft, Mod-Konflikte zu vermeiden.
|
||||
|
||||
Markierter Text kann an den meisten Stellen verwendet werden, wo menschenlesbarer Text akzeptiert wird, einschließlich *formspecs*, *item def*-Felder, Infotext und mehr. Wenn Sie markierten Text in Formspecs, müssen Sie den Text mit `minetest.formspec_escape` entschlüsseln.
|
||||
|
||||
Wenn der Client auf übersetzbaren Text stößt, wie den, der an `description` übergeben wird, schaut er in der Übersetzungsdatei der Sprache des Spielers nach. Wenn eine Übersetzung nicht gefunden wird, greift er auf die englische Übersetzung zurück.
|
||||
|
||||
Der übersetzbare markierte Text enthält den englischen Ausgangstext, die Textdomäne,
|
||||
und alle zusätzlichen Argumente, die an `S()` übergeben werden. Es ist im Wesentlichen eine Textkodierung des `S`-Aufrufs, die alle erforderlichen Informationen enthält.
|
||||
|
||||
Eine andere Art von markiertem Text ist der, der von `minetest.colorize` zurückgegeben wird.
|
||||
|
||||
{% include notice.html notice=page.marked_text_encoding %}
|
||||
|
||||
|
||||
### Übersetzungsdateien
|
||||
|
||||
Übersetzungsdateien sind Mediendateien, die sich im Ordner `locale` für jeden Mod befinden. Zurzeit wird nur das Format `.tr` unterstützt, aber die Unterstützung für weitere gängige Formate wird wahrscheinlich in der Zukunft hinzugefügt. Übersetzungsdateien müssen folgendermaßen benannt werden: `[textdomain].[lang].tr`.
|
||||
|
||||
Dateien im `.tr` beginnen mit einem Kommentar, der die Textdomäne angibt, und dann weiteren Zeilen, die den englischen Ausgangstext auf die Übersetzung abbilden.
|
||||
|
||||
Zum Beispiel: `mymod.fr.tr`:
|
||||
|
||||
```
|
||||
# textdomain: mymod
|
||||
Hello everyone!=Bonjour à tous !
|
||||
I like grapefruit=J'aime le pamplemousse
|
||||
```
|
||||
|
||||
Sie sollten Übersetzungsdateien auf der Grundlage des Quellcodes Ihres Mods/Spiels erstellen, unter Verwendung eines Tools wie [update_translations](https://github.com/minetest-tools/update_translations). Dieses Tool sucht nach `S(` in Ihrem Lua-Code und erstellt automatisch eine Vorlage, die Übersetzer für die Übersetzung in ihre Sprache verwenden können. Es kümmert sich auch darum, die Übersetzungsdateien zu aktualisieren, wenn sich Ihr Quelltext ändert.
|
||||
|
||||
Sie sollten immer wörtlichen Text (`"`) in S einfügen, anstatt eine Variable zu verwenden,
|
||||
da dies den Werkzeugen hilft, Übersetzungen zu finden.
|
||||
|
||||
## Formatierte Zeichenketten
|
||||
|
||||
Es ist üblich, variable Informationen in einen Übersetzungsstring aufzunehmen. Dabei ist es ist wichtig, dass der Text nicht einfach aneinandergereiht wird, da das Übersetzer daran hindert, die Reihenfolge der Variablen innerhalb eines Satzes zu ändern. Stattdessen, sollten Sie das Format/Argumente-System des Übersetzungssystems verwenden:
|
||||
|
||||
```lua
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
minetest.chat_send_all(S("Everyone, say hi to @1!", player:get_player_name()))
|
||||
end)
|
||||
```
|
||||
|
||||
Wenn Sie ein wörtliches `@` in Ihre Übersetzung einfügen wollen, müssen Sie die Escape-Schreibweise verwenden, indem Sie `@@` schreiben.
|
||||
|
||||
Sie sollten die Verkettung *innerhalb* eines Satzes vermeiden, aber es wird empfohlen, dass mehrere Sätze durch Konkatenation zu verbinden. Dies hilft den Übersetzern, weil Zeichenketten kleiner gehalten sind.
|
||||
|
||||
```lua
|
||||
S("Hello @1!", player_name) .. " " .. S("You have @1 new messages.", #msgs)
|
||||
```
|
||||
|
||||
|
||||
## Beste Verfahren und verbreitete Unwahrheiten über die Übersetzung <a name="verfahren"></a>
|
||||
|
||||
* Vermeiden Sie die Verkettung von Text und verwenden Sie stattdessen Formatierungsargumente. Dies gibt Übersetzer die volle Kontrolle über die Änderung der Reihenfolge der Dinge.
|
||||
* Erstellen Sie Übersetzungsdateien automatisch, indem Sie
|
||||
[update_translations](https://github.com/minetest-tools/update_translations) verwenden.
|
||||
* Es ist üblich, dass Variablen den umgebenden Text verändern, zum Beispiel durch
|
||||
Geschlecht und Pluralisierung. Dies ist oft schwer zu handhaben, daher wird
|
||||
häufig mit geschlechtsneutralen Formulierungen umgangen.
|
||||
* Übersetzungen können viel länger oder viel kleiner als der englische Text sein. Stellen Sie
|
||||
sicher, dass Sie viel Platz lassen.
|
||||
* In anderen Sprachen werden Zahlen möglicherweise anders geschrieben, zum Beispiel mit Kommas als Dezimalkomma. `1.000,23`, `1'000'000,32`
|
||||
* Gehen Sie nicht davon aus, dass andere Sprachen die Großschreibung auf die gleiche Weise verwenden.
|
||||
|
||||
|
||||
## Server-seitige Übersetzungen <a name="server"></a>
|
||||
|
||||
Manchmal muss man z. B. die Übersetzung eines Textes auf dem Server kennen, um Text zu sortieren oder zu suchen. Sie können `get_player_information` benutzen, um die Sprache des Spielers zu erhalten und `get_translated_string`, um markierten Text zu übersetzen.
|
||||
|
||||
```lua
|
||||
local list = {
|
||||
S("Hello world!"),
|
||||
S("Potato")
|
||||
}
|
||||
|
||||
minetest.register_chatcommand("find", {
|
||||
func = function(name, param)
|
||||
local info = minetest.get_player_information(name)
|
||||
local language = info and info.language or "en"
|
||||
|
||||
for _, line in ipairs(list) do
|
||||
local trans = minetest.get_translated_string(language, line)
|
||||
if trans:contains(query) then
|
||||
return line
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Die Übersetzungs-API ermöglicht es, Mods und Spiele besser zugänglich zu machen, aber es ist Vorsicht geboten, um sie richtig zu nutzen.
|
||||
|
||||
Minetest wird ständig verbessert und die Übersetzungs-API wird wahrscheinlich in Zukunft erweitert werden. Zum Beispiel wird die Unterstützung für gettext-Übersetzungsdateien die Verwendung gängiger Übersetzungswerkzeuge und -plattformen (wie weblate) ermöglichen und es wird wahrscheinlich eine Unterstützung für Pluralisierung und Geschlecht hinzugefügt werden.
|
@ -37,6 +37,7 @@ formspec language version = formspec-Sprachversion
|
||||
games = Spiele
|
||||
getter = Getter
|
||||
glasslike = Glasartig
|
||||
glitch = Störung
|
||||
grid = Raster
|
||||
Header = Header
|
||||
Heads Up Display = Heads Up Display
|
||||
@ -59,6 +60,7 @@ key-value table = Schlüssel-Wert-Tabelle
|
||||
large data = große Daten
|
||||
Legacy Coordinates = Legacy-Koordinaten
|
||||
Lua entity = Lua entity
|
||||
Lua Voxel Manipulator
|
||||
main inventory = Hauptinventar
|
||||
map = Karte
|
||||
MapBlock = Map-Block
|
||||
|
Loading…
Reference in New Issue
Block a user