osrlib.core.treasure
Treasure tables and treasure generation: the types monsters carry, gems, jewellery, and magic items.
This module turns a treasure type into loot. It takes the compiled tables that
load_treasure_tables returns and produces a
GeneratedTreasure: coins, gems and jewellery,
and magic item instances ready for an
Inventory or a chest in a dungeon.
Which entry point you want depends on what you are stocking:
generate_treasurefor a treasure type, the letter a monster's stat block names.generate_unguarded_treasurefor a cache nothing is guarding, by dungeon level.generate_magic_itemfor one magic item rolled at random, andinstantiate_magic_itemfor a particular item you have already chosen.plan_treasure_refto work out what a monster's treasure entry means: what it carries and what waits in its lair.roll_room_contentsto stock a room at all, which is the roll that settles whether there is treasure to generate.
Under a running game, treasure is generated for you when a monster is placed or a cache
is stocked, and reaches the party through the
TakeTreasure command. Call these functions
directly when you are using the rules without a session, or building an adventure ahead
of play.
Every entry point takes a tier, either "basic" or "expert". The rules print two
probability columns for magic items, B and X, one for each half of the game, and the
tier picks the column: a game chooses by how experienced the party is, and the crawl
uses Basic while the party's highest living level is 1 to 3 and Expert from 4 up.
Every printed entry of a treasure type parses to one fixed shape: an optional percentage
chance that the entry is there at all, then either a quantity of coins, a count of gems
or jewellery, or a magic item allotment. Allotments are structured rather than free text,
so "any 3 magic items" and "1 potion" and "a sword, suit of armour, or weapon" are all
MagicAllotments a program can read.
Generation draws in printed order: the presence roll for each entry, then the quantity dice, then each item resolved completely before the next one starts. That order is the contract, so the same seed and the same table always produce the same hoard.
Typical usage:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, generate_treasure
stream = RngStreams(master_seed=1).get(TREASURE_STREAM)
hoard = generate_treasure("B", tier="basic", stream=stream, allocator=IdAllocator())
print(hoard.coins.value_gp, len(hoard.valuables), len(hoard.magic_items))
# 3000 4 0
TREASURE_STREAM
module-attribute
TREASURE_STREAM = StreamName.TREASURE
The name of the RNG stream treasure generation draws from.
Pass streams.get(TREASURE_STREAM) to any generation function, where streams is the
RngStreams of the session or of your own master seed.
Using the named stream is what makes a hoard reproducible: every stream advances
independently, so the treasure a party finds does not change because a fight went
differently.
Nothing forces the choice, and the generation functions take whatever stream you hand them. Use this one unless you have a reason not to.
CoinDenomination
CoinQuantity
Bases: BaseModel
How many coins of one denomination a treasure entry yields.
The printed multiplier is folded into the dice expression, so an entry that reads
1d6 × 1,000 gp arrives here as dice of 1d6×1000 and a denomination of gold. Roll it
with roll if you are generating by hand. The generation
functions do it for you.
GemValueBand
Bases: BaseModel
One band of the gem value table: the d20 rolls that make a gem worth a given amount.
roll_min
class-attribute
instance-attribute
The lowest d20 result in this band.
roll_max
class-attribute
instance-attribute
The highest d20 result in this band.
GemValueTable
Bases: BaseModel
What a gem is worth, and how much a piece of jewellery is worth.
Generation rolls a gem's value on the d20 bands and a piece of jewellery on the dice,
once per piece, and stamps the result onto a
ValuableInstance whose value never changes
afterwards. Roll a gem yourself with
value_for_roll.
bands
class-attribute
instance-attribute
bands: tuple[GemValueBand, ...] = Field(min_length=1)
The gem value bands, covering the whole d20. See GemValueBand.
jewellery_dice
instance-attribute
jewellery_dice: str
What one piece of jewellery is worth, as a dice expression.
manual_notes
class-attribute
instance-attribute
The rules the referee applies by hand, as printed: that rough treatment can halve a piece of jewellery's value, and that several gems may be combined into fewer, larger ones. osrlib does neither. Show these to the referee if your game applies them.
value_for_roll
Return what a gem is worth for a d20 roll.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roll
|
int
|
The d20 result, 1 to 20. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The value in gold pieces. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the roll is outside 1 to 20. |
Examples:
MagicAllotment
Bases: BaseModel
One magic item clause of a treasure entry: how many items, and how free the choice is.
Read kind to know what the clause means:
any: roll the master Magic Item Type table for each item, re-rolling anything inexclude. This is how "any 3 magic items" and "any 1 magic item, no weapons" are stored.category: roll the one table named incategories, as in "1 potion".pool: choose evenly among the types incategories, then roll that type's table, as in "a magic sword, suit of armour, or weapon".
Exactly one of count and count_dice sizes the clause. Only an any clause has
exclusions, because a clause that names its type has nothing to exclude.
categories
class-attribute
instance-attribute
categories: tuple[MagicItemType, ...] = ()
The types the clause names. See MagicItemType. Empty for any, one for
category, two or more for pool.
count
class-attribute
instance-attribute
count: int | None = None
A fixed number of items, or None when the count is rolled.
count_dice
class-attribute
instance-attribute
count_dice: str | None = None
The number of items as a dice expression, or None when it is fixed.
exclude
class-attribute
instance-attribute
exclude: tuple[MagicItemType, ...] = ()
Types an any clause re-rolls. Empty on the other kinds.
MagicItemType
Bases: StrEnum
The types of the master Magic Item Type table, which is the first roll in generating a magic item.
Roll the master table to get one of these, then roll that type's own table for the item:
generate_magic_item does both. A magic
allotment for one kind of item names its type here.
These are the table's types, not the catalog's categories. Rods, staves, and wands share
a single printed row and a single table, while the catalog keeps them apart. See
MagicItemCategory.
The wire values are lowercase and serialize into the compiled treasure data. Changing
them is a schema_version bump.
ROD_STAFF_WAND
class-attribute
instance-attribute
The rod, staff, and wand row, which covers all three.
SCROLL
class-attribute
instance-attribute
The scroll row, which covers treasure maps as well as spell scrolls.
MagicItemTypeRow
Bases: BaseModel
One row of the master Magic Item Type table: a type and the d% rolls that select it, in both columns.
The rules print two columns, B for Basic play and X for Expert, and a type's odds differ
between them: scrolls and swords get likelier in Expert play, potions less likely. A
printed 00 is read as 100, so both columns close at 100.
basic_min
class-attribute
instance-attribute
The lowest d% roll that selects it in the B column.
basic_max
class-attribute
instance-attribute
The highest d% roll that selects it in the B column.
expert_min
class-attribute
instance-attribute
The lowest d% roll that selects it in the X column.
MagicItemTypeTable
Bases: BaseModel
The master Magic Item Type table: which kind of magic item a random roll produces.
The first of the two rolls that generate a magic item. Roll it with
category_for_roll, then
roll the type's own table, which
MagicItemCatalog.sub_table returns. Or
let generate_magic_item do both and
instantiate the item.
rows
class-attribute
instance-attribute
rows: tuple[MagicItemTypeRow, ...] = Field(min_length=1)
The rows, in printed order, each column covering the whole d%. See
MagicItemTypeRow.
category_for_roll
category_for_roll(roll: int, *, tier: str) -> MagicItemType
Return the type of magic item a d% roll produces, under one tier's column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roll
|
int
|
The d% result, 1 to 100, with a rolled |
required |
tier
|
str
|
|
required |
Returns:
| Type | Description |
|---|---|
MagicItemType
|
The selected type. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the tier is not one of the two, or the roll is outside 1 to 100. |
Examples:
RoomContentsResult
Bases: BaseModel
What one roll on the room stocking table produced.
Returned by roll_room_contents. It reports
both rolls so an adventure author can see how a room was decided, and so a tool that
stocks a level can log it.
treasure_roll
class-attribute
instance-attribute
treasure_roll: int | None = None
The d6 rolled for treasure, or None when the row gives no chance of treasure and no die was rolled.
treasure_present
class-attribute
instance-attribute
treasure_present: bool = False
True when the room has treasure as well as its contents. Which treasure is yours to decide: generate it with
generate_unguarded_treasure for an empty or trapped room, or
from the monster's own type when a monster is there.
StockingRow
Bases: BaseModel
One row of the room stocking table: what is in a room, and how likely treasure is with it.
roll_min
class-attribute
instance-attribute
The lowest d6 result in this row.
roll_max
class-attribute
instance-attribute
The highest d6 result in this row.
contents
instance-attribute
contents: Literal['empty', 'monster', 'special', 'trap']
What is in the room: "empty", "monster", "special", or "trap".
StockingTable
Bases: BaseModel
The Random Dungeon Room Contents table: what to put in a room when you are stocking a dungeon.
Rolling it is a two-step procedure, so call
roll_room_contents rather than this table
directly unless you are rolling by hand: it rolls the contents, then the treasure chance
that goes with them, and reports both.
This is an authoring tool, not something play calls: it is how you fill a dungeon level before anyone explores it.
rows
class-attribute
instance-attribute
rows: tuple[StockingRow, ...] = Field(min_length=1)
The rows, covering the whole d6. See StockingRow.
row_for_roll
row_for_roll(roll: int) -> StockingRow
Return the stocking row a d6 roll selects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roll
|
int
|
The d6 result, 1 to 6. |
required |
Returns:
| Type | Description |
|---|---|
StockingRow
|
The selected row. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the roll is outside 1 to 6. |
TreasureEntry
Bases: BaseModel
One printed line of a treasure type: one thing that might be in the hoard.
A treasure type is a list of these, and generation walks them in order. Each has exactly
one payload, so an entry is coins, or gems, or jewellery, or magic items, never a
mixture. Generate a list of them with
generate_treasure_entries, which is
also how you generate the hoard a treasure map leads to.
chance_pct
class-attribute
instance-attribute
The percentage chance the entry is present at all. 0 means it always is, which is how the entries printed without a chance are stored.
coins
class-attribute
instance-attribute
coins: CoinQuantity | None = None
The coins this entry yields, or None. See CoinQuantity.
gems_dice
class-attribute
instance-attribute
gems_dice: str | None = None
How many gems, as a dice expression, or None. Each gem's value is rolled separately on the gem table.
jewellery_dice
class-attribute
instance-attribute
jewellery_dice: str | None = None
How many pieces of jewellery, as a dice expression, or None. Each piece's value is rolled separately.
magic
class-attribute
instance-attribute
magic: tuple[MagicAllotment, ...] = ()
The magic item clauses, or empty. See MagicAllotment.
TreasureRefPlan
Bases: BaseModel
A monster's treasure entry, worked out into what to generate and when.
plan_treasure_ref produces one of these from
a stat block's treasure reference. The three letter lists say when each letter is
generated: the lair ones once when you stock the lair, the individual ones once per
monster, and the group ones once for the whole group. A letter in parentheses on the stat
block is lair treasure whatever section it belongs to, which is how the bandit's U (A)
means each bandit carries type U and the camp has a type A hoard.
Some references generate nothing at all. Where a stat block marks the treasure special or describes it below, the referee writes it, and those parts are left out of the plan. So are the two adjustments the rules leave to the referee: reducing a hoard for a small lair, and changing a hoard's value by hand.
lair
class-attribute
instance-attribute
Letters to generate once for the lair, in the order the stat block lists them.
individual
class-attribute
instance-attribute
Letters to generate once per monster.
group
class-attribute
instance-attribute
Letters to generate once for the group.
extra_gp
class-attribute
instance-attribute
extra_gp: int = 0
Flat gold pieces the entry adds to the lair hoard.
multiplier
class-attribute
instance-attribute
multiplier: int = 1
How many times to run the whole generation, for an entry like the noble's V × 3. 1 for everything else.
TreasureSection
Bases: StrEnum
Which section of the treasure tables a letter belongs to, which is when you generate it.
A monster's stat block names treasure types by letter, and when you generate a letter
depends on its section: once for the lair, once per monster, or once for the whole
group.
plan_treasure_ref sorts a stat block's
letters into those three piles for you.
The wire values are lowercase and serialize into the compiled treasure data. Changing
them is a schema_version bump.
HOARD
class-attribute
instance-attribute
Types A to O: the treasure in a monster's lair, generated once for the lair.
INDIVIDUAL
class-attribute
instance-attribute
Types P to T: what one monster carries, generated once per monster.
TreasureTables
Bases: BaseModel
Every treasure table there is, loaded and ready to generate from.
Call load_treasure_tables to get the shipped set.
It is frozen, cached, and shared. The generation functions load it themselves, so you
need this only to read a table: to show a referee what a letter can produce, or to roll
a table by hand.
treasure_types
instance-attribute
treasure_types: tuple[TreasureTypeTable, ...]
Every treasure type, A through V. See TreasureTypeTable. Reach one by
letter with treasure_type.
magic_item_types
instance-attribute
magic_item_types: MagicItemTypeTable
Which kind of magic item a roll produces. See MagicItemTypeTable.
stocking
instance-attribute
stocking: StockingTable
What is in a room when you stock a dungeon. See StockingTable.
unguarded
instance-attribute
unguarded: UnguardedTreasureTable
What an unguarded cache contains, by level. See
UnguardedTreasureTable.
treasure_type
treasure_type(letter: str) -> TreasureTypeTable
Return the treasure type for letter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
letter
|
str
|
The type letter, for example |
required |
Returns:
| Type | Description |
|---|---|
TreasureTypeTable
|
The treasure type. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no type has that letter. |
Examples:
TreasureTypeTable
Bases: BaseModel
One treasure type, A through V: everything a hoard of that letter can contain.
Get one with
TreasureTables.treasure_type, or
skip straight to the result with
generate_treasure. Read the entries when you
want to show a referee what a letter can produce before rolling it.
letter
class-attribute
instance-attribute
The type letter, for example "A". See the treasure type index.
kind
instance-attribute
kind: TreasureSection
Whether the letter is lair treasure, carried by one monster, or carried by a group. See
TreasureSection.
average_gp
class-attribute
instance-attribute
The average value of a hoard of this type in gold pieces, as the rules print it. A planning figure for an adventure author, not something generation aims at.
entries
class-attribute
instance-attribute
entries: tuple[TreasureEntry, ...] = Field(min_length=1)
The printed lines, in order. See TreasureEntry.
UnguardedTreasureBand
Bases: BaseModel
One dungeon-level band of the unguarded treasure table.
Deeper levels have more, so the table is banded by level. The entries have the same shape as a treasure type's.
label
class-attribute
instance-attribute
The band as the table prints it, for example "Level 2–3".
min_level
class-attribute
instance-attribute
The shallowest dungeon level in the band.
max_level
class-attribute
instance-attribute
The deepest dungeon level in the band.
entries
class-attribute
instance-attribute
entries: tuple[TreasureEntry, ...] = Field(min_length=1)
The printed lines, in order. See TreasureEntry.
UnguardedTreasureTable
Bases: BaseModel
The unguarded treasure table: what a cache nobody is guarding contains, by dungeon level.
Use it through
generate_unguarded_treasure, which
picks the band and generates from it. Levels past the deepest printed band use that band,
so a level 12 cache is as rich as a level 9 one and no richer.
bands
class-attribute
instance-attribute
bands: tuple[UnguardedTreasureBand, ...] = Field(min_length=1)
The bands, in level order and contiguous from level 1. See
UnguardedTreasureBand.
band_for_level
band_for_level(level: int) -> UnguardedTreasureBand
Return the band for a dungeon level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
The dungeon level, counting from 1. |
required |
Returns:
| Type | Description |
|---|---|
UnguardedTreasureBand
|
The band covering that level. Levels past the deepest band get the deepest band, |
UnguardedTreasureBand
|
the same clamp the encounter tables use. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
generate_magic_item
generate_magic_item(
category: MagicItemType | None,
*,
tier: str,
stream: RngStream,
allocator: Any,
exclude: tuple[MagicItemType, ...] = ()
) -> list[MagicItemInstance]
Roll one magic item at random: which kind, which item, and all its details.
Three steps in one call. When category is None it rolls the master Magic Item Type
table for the kind, re-rolling anything you excluded. Then it rolls that kind's own table
for the item. Then
instantiate_magic_item rolls the item's
details. Pass a category when the kind is already decided, as it is for an allotment
for a potion.
Use it when you want a single random item: a reward, a gift, a hand-placed surprise. For
a monster's whole hoard call
generate_treasure, which rolls allotments as
well as coins and gems.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
MagicItemType | None
|
The kind of item to roll, or |
required |
tier
|
str
|
|
required |
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
allocator
|
Any
|
The id source for the new instances, which take the |
required |
exclude
|
tuple[MagicItemType, ...]
|
Kinds to re-roll when the kind is being rolled. Excluded rolls consume draws, as re-rolling at the table does. |
()
|
Returns:
| Type | Description |
|---|---|
list[MagicItemInstance]
|
The new instances, unidentified. Usually one. Two when the table's row is a suit of |
list[MagicItemInstance]
|
armour that comes with a shield. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, generate_magic_item
stream = RngStreams(master_seed=9).get(TREASURE_STREAM)
items = generate_magic_item(None, tier="basic", stream=stream, allocator=IdAllocator())
print([(item.instance_id, item.template_id) for item in items])
# [('magic-item-0001', 'rope_of_climbing')]
generate_treasure
generate_treasure(treasure_type: str, *, tier: str, stream: RngStream, allocator: Any) -> GeneratedTreasure
Generate one treasure type's contents.
The entry point for a monster's treasure: a stat block names a letter, and this rolls
everything that letter can contain. Which letters to roll, and whether each belongs to the
lair, one monster, or the group, is what
plan_treasure_ref works out from the stat
block.
Nothing is placed: what comes back is yours to put in a chest, hand to a monster, or add to an inventory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
treasure_type
|
str
|
The type letter, |
required |
tier
|
str
|
|
required |
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
allocator
|
Any
|
The id source for generated gems, jewellery, and magic items, which take
the |
required |
Returns:
| Type | Description |
|---|---|
GeneratedTreasure
|
The coins, valuables, and magic items. See |
GeneratedTreasure
|
|
GeneratedTreasure
|
empty. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no treasure type has that letter, or if |
Examples:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, generate_treasure
stream = RngStreams(master_seed=1).get(TREASURE_STREAM)
hoard = generate_treasure("A", tier="expert", stream=stream, allocator=IdAllocator())
assert hoard.coins.total_coins == 7000
assert len(hoard.valuables) == 19
assert {item.template_id for item in hoard.magic_items} == {
"sword_plus_1_plus_3_vs_dragons",
"ring_of_protection",
"potion_of_poison",
}
generate_treasure_entries
generate_treasure_entries(
entries: Sequence[TreasureEntry], *, tier: str, stream: RngStream, allocator: Any
) -> GeneratedTreasure
Generate treasure from a list of printed entries.
The engine the other generation functions share, and the one to call when you have entries in hand rather than a letter or a level: the hoard a treasure map leads to is a list of entries on the map's own template, and this is how you turn it into loot.
Entries are resolved in printed order: for each one, the presence roll if it is gated, then the quantity dice, then each gem, piece of jewellery, or magic item resolved completely before the next begins. That order is the contract behind reproducibility, so the same seed and the same entries always give the same result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entries
|
Sequence[TreasureEntry]
|
The printed entries. See
|
required |
tier
|
str
|
|
required |
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
allocator
|
Any
|
The id source for generated gems, jewellery, and magic items, which take
the |
required |
Returns:
| Type | Description |
|---|---|
GeneratedTreasure
|
The coins, valuables, and magic items. See |
GeneratedTreasure
|
|
GeneratedTreasure
|
empty, and entries that failed their presence roll contribute nothing. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, generate_treasure_entries
from osrlib.data import load_magic_items
recipe = load_magic_items().get("treasure_map_i").hoard_recipe
stream = RngStreams(master_seed=2).get(TREASURE_STREAM)
hoard = generate_treasure_entries(recipe, tier="basic", stream=stream, allocator=IdAllocator())
print([item.template_id for item in hoard.magic_items])
# ['mace_plus_1']
generate_unguarded_treasure
generate_unguarded_treasure(dungeon_level: int, *, tier: str, stream: RngStream, allocator: Any) -> GeneratedTreasure
Generate a cache of treasure nobody is guarding, for a dungeon level.
The counterpart to generate_treasure: use it
when the treasure belongs to the room rather than to a monster, which is what
roll_room_contents reports when an empty or
trapped room turns out to have something.
Deeper levels have more. Levels past the deepest printed band use that band, so treasure stops getting richer below level 9.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dungeon_level
|
int
|
The dungeon level, counting from 1. |
required |
tier
|
str
|
|
required |
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
allocator
|
Any
|
The id source for generated gems, jewellery, and magic items. An
|
required |
Returns:
| Type | Description |
|---|---|
GeneratedTreasure
|
The coins, valuables, and magic items. See |
GeneratedTreasure
|
|
GeneratedTreasure
|
alone. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, generate_unguarded_treasure
stream = RngStreams(master_seed=3).get(TREASURE_STREAM)
cache = generate_unguarded_treasure(1, tier="basic", stream=stream, allocator=IdAllocator())
print(cache.coins.sp, cache.coins.value_gp, len(cache.magic_items))
# 300 30 0
instantiate_magic_item
instantiate_magic_item(
item_id: str, *, tier: str, stream: RngStream, allocator: Any, params: Mapping[str, Any] | None = None
) -> MagicItemInstance
Create one copy of a magic item you have already chosen, rolling the details that differ between copies.
This is how a hand-placed magic item becomes something a character can carry. An
adventure names the item (FeatureSpec.magic_item_ids
does exactly this), and this rolls what the item's own page leaves to chance: what a
generic suit of enchanted armour is made of, how many charges a wand has, how many
arrows are in the bundle, how many wishes the ring has, which spells are on the scroll,
how many levels the sword can drain, and last of all whether a sword is sentient. Nothing
is left unrolled: the instance that comes back is ready to use.
When you want the item chosen at random too, call
generate_magic_item, which rolls the tables
and then calls this.
The copy comes back unidentified. The party learns what it is by using it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item_id
|
str
|
The item to create. See the magic item id index. |
required |
tier
|
str
|
|
required |
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
allocator
|
Any
|
The id source for the new instance's id, which takes the |
required |
params
|
Mapping[str, Any] | None
|
Overrides from a generation table row, when this is being called from one:
the quantity dice a printed band gives, a fixed Basic-tier quantity, a wish
count. Leave it |
None
|
Returns:
| Type | Description |
|---|---|
MagicItemInstance
|
The new instance, unidentified. See |
MagicItemInstance
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
from osrlib.core.monsters import IdAllocator
from osrlib.core.rng import RngStreams
from osrlib.core.treasure import TREASURE_STREAM, instantiate_magic_item
stream = RngStreams(master_seed=11).get(TREASURE_STREAM)
staff = instantiate_magic_item("staff_of_striking", tier="expert", stream=stream, allocator=IdAllocator())
print(staff.instance_id, staff.charges_remaining, staff.identified)
# magic-item-0001 18 False
plan_treasure_ref
plan_treasure_ref(ref: TreasureRef) -> TreasureRefPlan
Work out what a monster's treasure entry means.
Call this before generating a monster's treasure: the letters on a stat block are not all
generated at the same moment, and this sorts them into the ones you roll for the lair, the
ones you roll per monster, and the ones you roll for the group. Then call
generate_treasure once per letter, repeated
multiplier times.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
TreasureRef
|
The treasure reference from a monster template's |
required |
Returns:
| Type | Description |
|---|---|
TreasureRefPlan
|
The plan. See |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the reference names a letter that is not a treasure type. |
Examples:
roll_room_contents
roll_room_contents(stream: RngStream) -> RoomContentsResult
Roll what is in a room and whether there is treasure with it.
The stocking roll, for filling a dungeon level before play: it rolls the d6 for contents, then, when the row gives a chance of treasure, a second d6 for that. A row printing no chance of treasure consumes no second die, which keeps the draw sequence exact.
Generating the treasure is a separate step, because which table to use depends on what is
in the room: the monster's own treasure type when a monster is there, and
generate_unguarded_treasure
otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stream
|
RngStream
|
The RNG stream to draw from, conventionally
|
required |
Returns:
| Type | Description |
|---|---|
RoomContentsResult
|
Both rolls and the row they selected. See |
RoomContentsResult
|
Examples: