docs: ticket 16 (loot-tabellen) aufloesen, nachtraege an 10 und 14, loot-tabelle ins glossar, destination erreicht

This commit is contained in:
2026-08-12 14:18:44 +02:00
parent 5faa5d6165
commit 9c5efab331
5 changed files with 188 additions and 5 deletions

View File

@@ -160,7 +160,8 @@ struct Room {
prefab: PrefabId, // fuer room_entered und Trigger prefab: PrefabId, // fuer room_entered und Trigger
rect: Rect, rect: Rect,
enemies: Vec<Creature>, enemies: Vec<Creature>,
loot: Vec<(Pos, ItemInstance)>, loot_table: LootTableId, // Nachtrag 16: Prefab-loot oder Etagentabelle
loot: Vec<Pos>, // Haufen, erst beim Aufheben aufgeloest
cleared: bool, cleared: bool,
} }
@@ -178,6 +179,21 @@ Ladeprüfung über die 04-Maschinerie: **`layout`-Zeilen müssen gleich lang sei
kein Rechteck und die Platzierung rechnet mit Müll. Ein Zweizeiler, der eine ganze Klasse von kein Rechteck und die Platzierung rechnet mit Müll. Ein Zweizeiler, der eine ganze Klasse von
Modder-Frust abfängt. Modder-Frust abfängt.
### Nachtrag aus Ticket 16
**Bodenbeute wird erst beim Aufheben gezogen**, deshalb hält `Room.loot` nur noch Positionen und der
Raum *eine* `loot_table` — alle Haufen eines Raums ziehen ohnehin aus derselben Tabelle (dem
Prefab-`loot` oder, wenn es fehlt, der Etagentabelle). Die *Zahl* der Haufen steht weiterhin bei der
Erzeugung fest, es sind die `l`-Zeichen; ihr Inhalt nicht. Der Save wird dadurch kleiner.
Möglich ist das nur, weil **alle Haufen dasselbe generische Symbol zeigen**: Die Anzeige verrät damit
nichts, was noch nicht gewürfelt ist. Der Gewinn ist, dass ein Glücksring auch auf Beute wirkt, die auf
dieser Etage schon liegt.
Dazu bekommt ein Prefab ein **optionales `loot`-Feld**, das die Etagentabelle für seine `l`-Plätze
ersetzt — sonst wäre ein `core:treasure`-Raum nur ein Raum mit mehr `l`-Zeichen. Es nennt eine
Tabellen-ID, keine Gegenstände, und bleibt damit über alle Tiefen verwendbar.
### Siegbedingung — bisher nirgends definiert ### Siegbedingung — bisher nirgends definiert
Kein Ticket hatte je festgelegt, was beim Abstieg von der letzten Etage passiert. Kein Ticket hatte je festgelegt, was beim Abstieg von der letzten Etage passiert.

View File

@@ -213,6 +213,9 @@ fünfzig Zeilen. Dazu bekommt die `creatures`-Registry ein Feld `exp_reward`.
Ausdrücklich **nicht** dazugekommen ist `points_per_level`: Ein Aufstieg gibt genau einen Punkt, das Ausdrücklich **nicht** dazugekommen ist `points_per_level`: Ein Aufstieg gibt genau einen Punkt, das
ist eine Regel und kein Stellknopf. ist eine Regel und kein Stellknopf.
**Nachtrag aus Ticket 16:** `LUCK_FACTOR` kommt dazu — `luck` gewährt eine Chance auf einen
zusätzlichen Zug auf jeder Beutetabelle. Damit hat `[balance]` acht Felder.
### Vier Nachträge an geschlossene Tickets ### Vier Nachträge an geschlossene Tickets
| Ticket | Nachtrag | | Ticket | Nachtrag |

View File

@@ -1,7 +1,7 @@
# 16 — Loot-Tabellen # 16 — Loot-Tabellen
Type: grilling Type: grilling
Status: open Status: resolved
Blocked by: 02 Blocked by: 02
## Question ## Question
@@ -35,3 +35,147 @@ Seltenheit, oder gar nicht?
Affixe sind eine eigene Registry (die sechste), also gilt für sie derselbe Mod-Einhängepunkt wie für Affixe sind eine eigene Registry (die sechste), also gilt für sie derselbe Mod-Einhängepunkt wie für
Gegenstände. Gegenstände.
## Answer
Begriffe im [Glossar](../../../CONTEXT.md). Der Zufall war bereits entschieden: derselbe gesetzte
Generator aus Ticket 14, dessen Seed im Save liegt — Beute würfelt beim Nachladen nicht neu.
### Eine Maschinerie für Gegenstände und Affixe
Zwölfte Registry `[[loot_tables]]`:
```toml
[[loot_tables]]
id = "core:weapon_affixes"
rolls = "0-1"
entries = [
{ affix = "core:flaming", weight = 5 },
{ affix = "core:greater_flaming", weight = 1 }, # Stufe, kein Wert
{ nothing = true, weight = 20 },
]
[[loot_tables]]
id = "core:floor_3_table"
rolls = "1-3"
entries = [
{ item = "core:health_potion", weight = 10, count = "1-2" },
{ item = "core:iron_sword", weight = 3, affixes = "core:weapon_affixes" },
{ table = "core:rare_table", weight = 1 },
{ nothing = true, weight = 20 },
{ item = "core:boss_blade", guaranteed = true },
]
```
**Gewichte statt Prozent** — keine Geschmacksfrage, sondern eine Modding-Frage: Prozentwerte müssen
sich auf 100 summieren, und ein hinzugefügter Eintrag macht die Summe kaputt, woraufhin jemand alle
anderen anpassen muss. Gewichte verdünnen sich anteilig, ohne dass irgendwer rechnet.
**Nieten sind gewöhnliche Einträge**, kein eigenes `drop_chance`-Feld. Ein Gegner, der selten etwas
fallen lässt, bekommt ein hohes `nothing`-Gewicht — die Engine kennt eine Mechanik statt zweier.
**Tabelle-in-Tabelle** ist eine Zeile und liefert Seltenheitsstufen, ohne dass „Seltenheit" ein Begriff
werden muss.
**`guaranteed = true`** wird immer ausgegeben und nimmt an der Gewichtung nicht teil. Mit Gewichten
allein lässt sich „sicher" nicht ausdrücken, und Bosse stehen in der Destination; Questgegenstände sind
derselbe Fall.
**Mehrfachziehung erlaubt**, kein `unique`-Flag. Drei Heiltränke sind ein normales Ergebnis, und
stapelbare Gegenstände (02) tragen das ohne Zutun. Wer Einzelstücke will, gibt ihnen eine eigene
Tabelle mit `rolls = "1-1"`. Die Decke: Falls „nie zweimal dasselbe Schwert" nötig wird, ist `unique`
ein Flag — jetzt wäre es eine Regel ohne Fall.
### Affix-Stufen statt Affix-Werte
Ticket 07 hat festgelegt, dass eine `ItemInstance` **nur Affix-IDs** trägt. „Flammend" und „Stark
flammend" sind deshalb zwei Registry-Einträge mit unterschiedlichen Modifikatoren und Preisfaktoren,
keine Zahl am Exemplar.
Eine Stärke je Exemplar hätte drei Dinge auf einmal gekostet: das Save-Format (ID-Liste), die
Preisformel `base_price × Π price_factor` und die Stapelregel — zwei Schwerter „Flammend 3" und
„Flammend 4" stapeln nicht mehr, aber wie zeigt man den Unterschied an? Mit Stufen kann der Modder
seine Abstufungen **benennen**, statt eine Zahl auszuliefern, die keine Anzeige hat.
### `luck` hat genau eine Regel
**Eine Chance auf einen zusätzlichen Zug — auf jeder Tabelle.**
```
p_extra = clamp(luck * LUCK_FACTOR, 0.0, 0.9)
```
Ein Knopf mehr in `[balance]`. Die Regel wirkt dreifach, ohne dreimal geschrieben zu werden: mehr
Gegenstände, mehr Affixe, und häufiger die stärkere Stufe — weil die als eigener Eintrag mit kleinem
Gewicht danebensteht.
Der Grund gegen „Glück verschiebt zur Seltenheit" ist ein Ausschluss: **Es gibt keinen
Seltenheitsbegriff.** Das Schema kennt nur Gewichte; Seltenheit erst zu definieren und dann Gewichte
umzurechnen wäre ein zweites Konzept für dasselbe Gefühl.
### Der Mod-Einhängepunkt existiert bereits
Ticket 03 gilt unverändert: ganzer Eintrag wird ersetzt. Ein neuer Mechanismus wird trotzdem nicht
gebraucht — **Tabelle-in-Tabelle ist der Einhängepunkt**, zwei gewöhnliche Überschreibungen und null
neue Begriffe:
```toml
[[loot_tables]]
id = "meinmod:floor_3"
entries = [ { table = "core:floor_3_table", weight = 100 },
{ item = "meinmod:zauberstab", weight = 5 } ]
[[floors]]
id = "core:floor_3"
overrides = "core:floor_3"
loot = "meinmod:floor_3"
```
Decke: Zwei Mods, die dieselbe Etage umhängen, kollidieren — der letzte gewinnt. Das ist derselbe
Konflikt wie bei jeder anderen Überschreibung in 03. Falls er häufig wird, ist `[[loot_additions]]` der
Nachbau; ihn *vorher* zu bauen hieße, einen zweiten Mechanismus für etwas einzuführen, das der erste
schon kann.
### Beute wird beim Aufheben gezogen
`Room` aus Ticket 10 bekommt **eine `loot_table` und `loot: Vec<Pos>`** statt fertiger Instanzen — alle
Haufen eines Raums ziehen ohnehin aus derselben Tabelle, die ID je Haufen zu wiederholen wäre
Redundanz. Aufgelöst wird erst beim Aufheben; der Save wird dadurch sogar kleiner.
Die **Zahl** der Haufen steht bei der Erzeugung fest (die `l`-Zeichen im Prefab), ihr Inhalt nicht.
Alle zeigen **dasselbe generische Symbol** — deshalb verrät die Anzeige nichts, und ein Glücksring
wirkt auch auf das, was auf dieser Etage bereits liegt. Bei Ziehung zur Erzeugungszeit wäre der Wurf
für diese Etage schon gefallen, bevor der Spieler den Ring findet.
Fällt der Wurf beim Aufheben auf eine Niete, **verschwindet der Haufen mit einer Meldung**. Kein
Neuwürfeln — das hängt sich bei einer reinen Nieten-Tabelle auf und bräuchte dann doch einen Zähler.
Keine Ladeprüfung „Tabellen für `l`-Plätze dürfen keine Nieten enthalten": Das wäre die Bevormundung,
die Ticket 02 abgeräumt hat. Wer leere Haufen nicht will, lässt Nieten aus der Tabelle weg.
### Etagenskalierung — die Auflage aus 15 ist strukturell erfüllt
Eine Tabelle je Etage, wie Ticket 10 es mit dem `loot`-Feld bereits angelegt hat. **Nirgends steht eine
Fünf**: Etagen sind Registry-Einträge, jeder bringt seine Tabelle mit, ein Mod mit Etage 6 bringt ihre
gleich mit, und der Endlosmodus wiederholt mit der letzten Etage auch deren Tabelle.
Bedingungen am Eintrag (`floor at_least 3` auf einer gemeinsamen Tabelle) klingen flexibler, lösen das
Endlos-Problem aber gerade *nicht*: Ein Eintrag mit `at_least = 3` ist auf Etage 500 genauso gültig wie
auf Etage 3. Echte Tiefenskalierung bräuchte Gewichte als *Funktion* der Etage — eine Formel, keine
Daten, und die wird gebaut, wenn der Endlosmodus kommt.
Ein Prefab darf über ein **optionales** `loot`-Feld seine eigene Tabelle nennen. Sonst ist ein
Schatzkammer-Raum nur ein Raum mit mehr `l`-Zeichen — mehr vom Gleichen statt etwas Besserem. Es nennt
dabei eine Tabellen-**ID**, keine Gegenstände, und bleibt damit über alle Tiefen verwendbar; dieselbe
Begründung, mit der 10 festgelegt hat, dass ein `e` nicht sagt, *welcher* Gegner.
### Wo Beute hängt
An der `creatures`-Registry (14), an der Etage (10) und optional am Prefab. Alle drei nennen schlicht
eine Tabellen-ID.
### Zwei Nachträge an geschlossene Tickets
| Ticket | Nachtrag |
|---|---|
| **10** | `Room` hält `loot_table: LootTableId` plus `loot: Vec<Pos>` statt `Vec<(Pos, ItemInstance)>`; optionales `loot`-Feld am Prefab; generischer Beute-Marker im Grid |
| **14** | `LUCK_FACTOR` in `[balance]` |

View File

@@ -17,7 +17,13 @@ dort als Konvention im Body. Zuordnung Ticket → Gitea-Issue:
| 13 Script-Engine wählen | [#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14) | 14 Kampfformeln | [#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15) | | 13 Script-Engine wählen | [#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14) | 14 Kampfformeln | [#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15) |
| 15 Progression | [#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16) | 16 Loot-Tabellen | [#17](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/17) | | 15 Progression | [#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16) | 16 Loot-Tabellen | [#17](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/17) |
## Destination ## Destination — **erreicht am 2026-08-12**
Alle sechzehn Tickets sind geschlossen. Was jetzt existiert: sechzehn Entscheidungsdokumente, ein
Glossar mit den kanonischen Begriffen, und ein 342-Zeilen-Wegwerfprototyp auf dem Branch
`prototyp/12-ratatui-durchstich`. Was **nicht** existiert: das Spiel. Der nächste Schritt ist die
Implementierung, und sie hat mit `src/` (heute `print_box`, `include_str!`, `enum ItemType`) fast
nichts gemein.
Alle Architektur- und Design-Entscheidungen für rustkeep 1.0 sind getroffen — nicht gebaut, entschieden. Alle Architektur- und Design-Entscheidungen für rustkeep 1.0 sind getroffen — nicht gebaut, entschieden.
1.0 heißt: 5 Etagen mit Boss, Solo-Held mit Rasse und Klasse, Grid-Erkundung mit Menü-Kampf, 1.0 heißt: 5 Etagen mit Boss, Solo-Held mit Rasse und Klasse, Grid-Erkundung mit Menü-Kampf,
@@ -78,6 +84,7 @@ auch über Ticket 13.
- [13 — Script-Engine wählen](issues/13-script-engine-waehlen.md) ([#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14)) — **Rhai**, aber die Wahl ist dank der Leitplanke aus 05 nur noch eine *Implementierungs*-Entscheidung: Scripts lesen ueber eine Handvoll Funktionen (gespiegelt an der Bedingungsgrammatik aus 08 — sie sehen nichts, was eine Bedingung nicht auch saehe) und schreiben ausschliesslich ueber Aktionen. Begruendung unbequem, aber ehrlich — **fuer ein unveroeffentlichtes Terminal-Roguelike schreibt niemand Mods**, der Lua-Vorsprung zahlt sich erst mit einer Gemeinde aus. Mods gelten als **vertrauenswuerdig** (wie bei Factorio, Minecraft, Skyrim), gehaertet wird gegen Unfaelle: acht Engine-Schalter, gegen die Doku geprueft; `set_max_operations` ausdruecklich **nicht** in `[balance]`, sonst hebt ein Mod sein eigenes Limit auf. `rand()` laeuft durch den Seed aus 14, sonst wuerfelten ausgerechnet Scripts beim Laden neu. `run_script` als neunte Aktion, Scripts als **elfte Registry**. Risiken beobachtet mit benanntem Ausstiegssignal; `smartstring` ist ein INFO-Advisory, kein Ausstiegsgrund. **Stufe (c) wandert hinter 1.0** — eine Script-Engine zu bauen, bevor jemand an eine Vokabular-Luecke gestossen ist, baut die Antwort vor der Frage. - [13 — Script-Engine wählen](issues/13-script-engine-waehlen.md) ([#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14)) — **Rhai**, aber die Wahl ist dank der Leitplanke aus 05 nur noch eine *Implementierungs*-Entscheidung: Scripts lesen ueber eine Handvoll Funktionen (gespiegelt an der Bedingungsgrammatik aus 08 — sie sehen nichts, was eine Bedingung nicht auch saehe) und schreiben ausschliesslich ueber Aktionen. Begruendung unbequem, aber ehrlich — **fuer ein unveroeffentlichtes Terminal-Roguelike schreibt niemand Mods**, der Lua-Vorsprung zahlt sich erst mit einer Gemeinde aus. Mods gelten als **vertrauenswuerdig** (wie bei Factorio, Minecraft, Skyrim), gehaertet wird gegen Unfaelle: acht Engine-Schalter, gegen die Doku geprueft; `set_max_operations` ausdruecklich **nicht** in `[balance]`, sonst hebt ein Mod sein eigenes Limit auf. `rand()` laeuft durch den Seed aus 14, sonst wuerfelten ausgerechnet Scripts beim Laden neu. `run_script` als neunte Aktion, Scripts als **elfte Registry**. Risiken beobachtet mit benanntem Ausstiegssignal; `smartstring` ist ein INFO-Advisory, kein Ausstiegsgrund. **Stufe (c) wandert hinter 1.0** — eine Script-Engine zu bauen, bevor jemand an eine Vokabular-Luecke gestossen ist, baut die Antwort vor der Frage.
- [14 — Kampfformeln und Rundenablauf](issues/14-kampfformeln-und-rundenablauf.md) ([#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15)) — **Ein Zug = Spielerhandlung plus alle Gegnerreaktionen**, sonst tickte ein Debuff bei drei Gegnern viermal. Initiative als `i32` **am Wesen** statt als Reihenfolgeliste (die waere eine zweite Indexsammlung mit demselben Ungueltigkeitsproblem); tote Gegner erst am Ende von `execute`, nach dem Leeren der Warteschlange. Trefferformel und Schadenskette mit drei Klemmbereichen — `0.8` bei Resistenz, weil `1.0` Immunitaet und damit ein Spielabbruch waere. **Die Krit-Reihenfolge-Frage loest sich auf**: multiplikativ ist kommutativ. Eigener xorshift, **Seed im Save** — Nachladen wuerfelt nicht neu. Faehigkeiten kosten Ausdauer, Abklingzeit in Zuegen, gesperrt ⇒ `Rejected` ohne Zug. **Achte Registry: Wesen** — die Luecke lag seit 02 offen; `ai` als geordnete Bedingungsliste. `[balance]` verschmilzt **feldweise**, ausdrueckliche Ausnahme zu 03 (festes Schema). Vier Nachtraege: `scale` und `flee` an 01, drei Felder an 07, zwei Events an 08, `GameOver` an 11. - [14 — Kampfformeln und Rundenablauf](issues/14-kampfformeln-und-rundenablauf.md) ([#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15)) — **Ein Zug = Spielerhandlung plus alle Gegnerreaktionen**, sonst tickte ein Debuff bei drei Gegnern viermal. Initiative als `i32` **am Wesen** statt als Reihenfolgeliste (die waere eine zweite Indexsammlung mit demselben Ungueltigkeitsproblem); tote Gegner erst am Ende von `execute`, nach dem Leeren der Warteschlange. Trefferformel und Schadenskette mit drei Klemmbereichen — `0.8` bei Resistenz, weil `1.0` Immunitaet und damit ein Spielabbruch waere. **Die Krit-Reihenfolge-Frage loest sich auf**: multiplikativ ist kommutativ. Eigener xorshift, **Seed im Save** — Nachladen wuerfelt nicht neu. Faehigkeiten kosten Ausdauer, Abklingzeit in Zuegen, gesperrt ⇒ `Rejected` ohne Zug. **Achte Registry: Wesen** — die Luecke lag seit 02 offen; `ai` als geordnete Bedingungsliste. `[balance]` verschmilzt **feldweise**, ausdrueckliche Ausnahme zu 03 (festes Schema). Vier Nachtraege: `scale` und `flee` an 01, drei Felder an 07, zwei Events an 08, `GameOver` an 11.
- [15 — Progression und Level-up](issues/15-progression-und-levelup.md) ([#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16)) — Ein Aufstieg gibt **genau einen** frei verteilbaren Punkt auf die fuenf Grundwerte; `AssignPoints` ist **ein** Command mit allen Punkten (drei Stufen waeren sonst drei Zuege im Menue). **Keine Obergrenze** — `clamp(1, 50)` faellt, die Kurve begrenzt sich ueber steigende Kosten (`exp_base`, `exp_exponent` in `[balance]`). Erfahrung aus Toetungen (`exp_reward` am Wesen) und Quests (`give_exp`, zehnte Aktion), **nicht** fuers Betreten einer Etage — das belohnte das Durchrennen. **Die Zuwachs-Regel bleibt eng**: nur Aufstieg und `AssignPoints` heben den Lebensstand mit `max_health`, Ausruestung nie — sonst „heilt ein Ring beim Anlegen" (01). Rasse und Klasse bleiben **flach**, `per_level` entfaellt ersatzlos; was sie traegt, sind Faehigkeiten. `level` darf modifiziert werden, aber Punkte haengen an `base.level` — ein `+1 level`-Ring schenkt keinen. Vier Nachtraege: `give_exp` an 01, `current_exp`/`unspent_points` an **`Game`** statt ans Wesen (07 hatte die Platzierung hierher delegiert), `AssignPoints` an 11, zwei Balance-Knoepfe plus `exp_reward` an 14. - [15 — Progression und Level-up](issues/15-progression-und-levelup.md) ([#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16)) — Ein Aufstieg gibt **genau einen** frei verteilbaren Punkt auf die fuenf Grundwerte; `AssignPoints` ist **ein** Command mit allen Punkten (drei Stufen waeren sonst drei Zuege im Menue). **Keine Obergrenze** — `clamp(1, 50)` faellt, die Kurve begrenzt sich ueber steigende Kosten (`exp_base`, `exp_exponent` in `[balance]`). Erfahrung aus Toetungen (`exp_reward` am Wesen) und Quests (`give_exp`, zehnte Aktion), **nicht** fuers Betreten einer Etage — das belohnte das Durchrennen. **Die Zuwachs-Regel bleibt eng**: nur Aufstieg und `AssignPoints` heben den Lebensstand mit `max_health`, Ausruestung nie — sonst „heilt ein Ring beim Anlegen" (01). Rasse und Klasse bleiben **flach**, `per_level` entfaellt ersatzlos; was sie traegt, sind Faehigkeiten. `level` darf modifiziert werden, aber Punkte haengen an `base.level` — ein `+1 level`-Ring schenkt keinen. Vier Nachtraege: `give_exp` an 01, `current_exp`/`unspent_points` an **`Game`** statt ans Wesen (07 hatte die Platzierung hierher delegiert), `AssignPoints` an 11, zwei Balance-Knoepfe plus `exp_reward` an 14.
- [16 — Loot-Tabellen](issues/16-loot-tabellen.md) ([#17](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/17)) — Zwoelfte Registry `[[loot_tables]]`, **eine Maschinerie fuer Gegenstaende und Affixe**. **Gewichte statt Prozent**, weil Prozente sich auf 100 summieren muessen und ein hinzugefuegter Mod-Eintrag die Summe kaputt macht. Nieten sind gewoehnliche Eintraege (kein `drop_chance`), Tabelle-in-Tabelle liefert Seltenheitsstufen, ohne dass „Seltenheit" ein Begriff wird. **Affix-Stufen statt Affix-Werte** — eine Staerke je Exemplar haette Save-Format, Preisformel und Stapelregel aus 07 auf einmal gekostet. **`luck` hat genau eine Regel**: Chance auf einen zusaetzlichen Zug auf jeder Tabelle — wirkt dreifach (mehr Gegenstaende, mehr Affixe, haeufiger die staerkere Stufe), ohne dreimal geschrieben zu werden. Der **Mod-Einhaengepunkt existiert schon**: Tabelle-in-Tabelle plus zwei Ueberschreibungen, kein zweiter Mechanismus. Bodenbeute wird **erst beim Aufheben** gezogen (`Room` haelt eine `loot_table` plus Positionen), moeglich nur weil alle Haufen dasselbe Symbol zeigen — dadurch wirkt ein Gluecksring auch auf das, was schon liegt. `guaranteed = true` fuer Bosse, Mehrfachziehung erlaubt. Nachtraege: `Room`-Umbau und optionales Prefab-`loot` an 10, `LUCK_FACTOR` an 14.
## Not yet specified ## Not yet specified

View File

@@ -218,10 +218,22 @@ anderes Layout erzeugen und den Helden in eine Wand stellen.
Fehlt beim Laden ein [Mod](#mod), wird der betroffene Eintrag verworfen und gewarnt — nie der ganze Fehlt beim Laden ein [Mod](#mod), wird der betroffene Eintrag verworfen und gewarnt — nie der ganze
Speicherstand abgelehnt. Speicherstand abgelehnt.
## Loot-Tabelle
Eine gewichtete Liste, aus der gezogen wird. Ein Eintrag ist ein [Gegenstand](#gegenstand), ein
[Affix](#affix), eine andere Tabelle oder eine **Niete** — dieselbe Maschinerie zieht damit Beute
*und* Affixe.
Gewichtet wird mit **Gewichten, nicht mit Prozenten** — Prozente müssten sich auf 100 summieren, und
ein Eintrag, den ein [Mod](#mod) hinzufügt, machte die Summe kaputt.
Es gibt **keinen Seltenheitsbegriff**: Abstufungen sind eigene Einträge mit kleinerem Gewicht
(`core:flaming` neben `core:greater_flaming`).
## Registry ## Registry
Eine benannte Sammlung moddbarer Definitionen, geschlüsselt nach namespaced ID. Es gibt **elf**, und Eine benannte Sammlung moddbarer Definitionen, geschlüsselt nach namespaced ID. Es gibt **zwölf**, und
das hier ist die kanonische Liste — sie ist über sechs Tickets gewachsen und stand sonst nirgends das hier ist die kanonische Liste — sie ist über sieben Tickets gewachsen und stand sonst nirgends
vollständig: vollständig:
| Registry | TOML-Tabelle | | Registry | TOML-Tabelle |
@@ -236,6 +248,7 @@ vollständig:
| [Wesen](#wesen) | `[[creatures]]` | | [Wesen](#wesen) | `[[creatures]]` |
| [Prefabs](#prefab) | `[[prefabs]]` | | [Prefabs](#prefab) | `[[prefabs]]` |
| [Etagen](#etage) | `[[floors]]` | | [Etagen](#etage) | `[[floors]]` |
| [Loot-Tabellen](#loot-tabelle) | `[[loot_tables]]` |
| Scripts | `[[scripts]]` | | Scripts | `[[scripts]]` |
Jede dieser Tabellen darf in jeder beliebigen `*.toml` eines [Mods](#mod) stehen. Jede dieser Tabellen darf in jeder beliebigen `*.toml` eines [Mods](#mod) stehen.