ItemRT rare drop table

← Back to Home

ItemRT (Item Rare Table) is PSO’s rare drop table. It determines whichrare itemeach enemy or box can drop, and at what probability. Figures such as “Dragon Slayer 1/456” and “Tyrell's Parasol 1/3660” come from ItemRT. Together with ItemPT (whether anything drops and its category) and ItemPMT (the item’s own parameters), it forms PSO’s complete drop system.

Overview

In PSO’s drop checks, rare checks areindependent ofcommon drops. When an enemy dies or a box is broken, the game first checks for a rare drop:

  1. Look up the rare pool for this enemy or box in ItemRT.
  2. Roll for the candidate rare items one at a time, stopping at the first hit (Sega's original method; newserv decides with a single roll, see "Complete drop-check flow" below).
  3. If a roll succeeds, that rare item becomes the drop,bypassing ItemPT’s common-drop flow.
  4. If all rolls fail, return to ItemPT’s common-drop flow.

An enemy’s common drops and rare drops therefore follow separate paths. A low rare drop rate is not reduced further by the number of common items.

File layout

ItemRT stores subtables for each difficulty × Section ID combination, giving 4 × 10 = 40 subtables (EP4 has a separate episode table). Each subtable has two parts:

  • Enemy rare pool (Monster Rares): indexed by enemy type. Each enemy has at most one rare item and its probability.
  • Box rare pool (Box Rares): indexed by area. Boxes in an area usually have several candidates; Ruins 3 boxes, for example, have nearly ten possible rares.

PSOBB uses two separate files: ItemRT.gsl (Ep1 & Ep2) and ItemRT_Ep4.gsl. GSL is Sega’s compact archive format (GStreamLib); each entry contains one subtable.

Generating a rare drop

  1. Select the subtable: use the current difficulty and the game’s Section ID.
  2. Find candidates:
    • Enemy rares: use the enemy type index to obtain (item ID, probability).
    • Box rares: use the area index to obtain a candidate list.
  3. Roll: Sega's original generates a random 32-bit integer for each candidate in turn and compares it with that candidate's probability, stopping at the first hit; newserv generates one 32-bit number and subtracts each candidate's probability in turn, hitting when the result goes negative. "Complete drop-check flow" below explains the difference.
  4. On success: construct the item immediately. Weapons also use the current area’s ItemPT bonus/special generation; frames/shields require a slot decision. Finally, ItemPMT supplies the name and model.

Probability encoding: why use compression?

In PSOBB’s ItemRT files, a rare item’s probability is not stored directly as a fraction. Instead, it is compressed into a uint8 (one byte), allowing Sega to fit hundreds of rare entries into a small file. The byte is interpreted as SSSSS VVV :

  • The high 5 bits are the shift; the low 3 bits are the base value.
  • The approximate expansion formula is (2 << shift) × (value + 7), producing a 32-bit probability value.
  • Final drop rate = this 32-bit value / 0xFFFFFFFF (4,294,967,295).

Two examples:

  • 0x40000000: final drop rate = 25% (0x40000000 / 0xFFFFFFFF ≈ 1/4)
  • 0x00FFFFFF: final drop rate ≈ 1/256

The compressed format offers only 256 possible values, so ItemRT cannot represent arbitrary probabilities exactly. Familiar rates such as 1/456, 1/3660, 1/11702 look unusual because they are the nearest values this format can represent.

How Section IDs are used

Each PSOBB character has one of ten fixed colour-based Section IDs, determined by a hash of the name at creation and described here as unchangeable. The ID:

  • Selects the game's ItemRT subtable at every difficulty, using the Section ID of the player who created the room.
  • Gives access to a different rare pool; some rares appear only under specific IDs.
  • For example, Parasitic Gene "Flow" can drop when an Oran player defeats Olga Flow on Ultimate.

This is why players hunt under particular IDs for particular rares. The Section ID calculator can help find a name that yields the required ID.

Enemy rares versus box rares

Enemy rares

  • Indexed by rt_index (the enemy type enumeration), with one record per type.
  • Each fixed-length record contains (item ID, packed probability).
  • One rare per enemy type is the limit. If an enemy has different rares under different IDs (for example, Hildebear dropping different swords), the ID selects a different subtable; the enemy does not roll for all those items at once.

Box rares

  • Indexed by area, with multiple candidates possible in each area.
  • An area usually has 1–30 candidates, each with its own probability.
  • The game checks the candidate list one entry at a time, giving each candidate a chance (see "Roll" above for how).
  • This explains the rich rare-box pools in later areas such as Ruins 3, CCA, Tower and Desert 3.

Rare drop rate modifiers

The raw ItemRT probabilities are Sega’s base values. Servers commonly apply a global drop rate multiplier:

  • Ephinea defaults to 1x (base rate). Anniversary milestones can raise this multiplier.
  • The global multiplier affects every rare item’s probability.

Data structures

The binary ItemRT format uses a fixed-length packed-probability/item-code record as its smallest unit. Each difficulty × ID subtable starts with this offset header.

Subtable header: Offsets (0x10 bytes)

OffsetFieldTypeDescription
0x00monster_rares_offsetu32Enemy rare pool pointer → PackedDrop[0x65] (only 0x33 entries in v1), indexed by rt_index.
0x04box_countu32Total box rare entries, usually fixed at 30 (0x1E).
0x08box_areas_offsetu32Box area array → u8[box_count]. Entry i gives the area of rare entry i .
0x0Cbox_rares_offsetu32Box rare pool pointer → PackedDrop[box_count], corresponding one-to-one with box_areas.

Packed probability entry: PackedDrop (4 bytes)

Each rare record occupies four bytes, the smallest ItemRT unit. Enemy and box rare pools use the same structure.

OffsetFieldTypeDescription
0x00probabilityu8Packed probability (SSSSS VVV bit layout).
0x01item_codeu8×3Item code data1[0..2]; for example, 00 01 00 means Saber.

Packing and expanding probabilities

The one-byte probability is interpreted as SSSSS VVV :

  • The high 5 bits S determine the shift: shift = S − 4, range [−4, 27]; negative values are treated as 0.
  • The low 3 bits V determine the value: value = V + 7, range [7, 14].
  • Expanded 32-bit probability = (2 << shift) × value. This is the numerator for the rare drop rate; the denominator is 0xFFFFFFFF (all 32 bits).
  • Final drop rate = expanded value / 0xFFFFFFFF

Examples:

packed (hex)shiftvalueexpandedApproximately
0xFF27140xE000000087.5%
0xC02070x01C00000About 1/152
0x801270x0001C000About 1/38836
0x00070x0000000EExtremely small (< 1/300 million)

With only 256 available values, arbitrary exact drop rates cannot be stored. Figures such as 1/456, 1/3660, 1/11702 are the nearest representable values. An exact rate such as 1/500 cannot be specified.

Expanded structure: ExpandedDrop

newserv expands each PackedDrop into an in-memory structure used for calculations, interaction and serialisation:

FieldTypeDescription
probabilityu32Expanded 32-bit probability (numerator; denominator fixed at 0xFFFFFFFF)
dataItemDataFull item data, including data1/data2, not just the three-byte ID

Box rare: BoxRare

Box rare records embed the area number rather than being indexed directly by area:

FieldTypeDescription
area_norm_plus_1u8Area number + 1 (0 marks an unused entry)
dropExpandedDropProbability + item data

Complete subtable: SpecCollection

Each top-level subtable corresponds to a difficulty × Section ID key and contains the following after expansion:

FieldTypeDescription
enemy_specsmap⟨Enemy, ExpandedDrop[]⟩Rare pool for each enemy type.
box_specsExpandedDrop[][]Outer array indexed by area_norm; each area contains a candidate list whose entries are checked separately.

Complete drop-check flow

An enemy death or a broken box initiates a drop event. These separate paths first check for a rare, then use ItemPT’s common flow if that fails.

Enemy drops

// ① Initial check: does the enemy drop anything?
type_drop_prob = pt.enemy_type_drop_probs[enemy_type]   // 0–100
if rand(0..99) >= type_drop_prob:
    return nothing                                       // No drop

// ② Rare check (stacking: one roll for all specs)
specs = rare_item_set.get_enemy_specs(mode, episode, difficulty, section_id, enemy_type)
det = rand(0, 0x100000000)                               // 32 bits + 1
for spec in specs:
    det -= spec.probability                              // Subtract in order
    if det < 0:
        return create_rare_item(spec.data, area)          // Rare selected; finish

// ③ ItemPT common flow: choose a category
determinant = allow_meseta ? rand(0..2) : rand(0..1) + 1
switch determinant:
    case 0: item_class = 5 (Meseta)
    case 1: item_class = 4 (Consumable)
    case 2: item_class = pt.enemy_type_item_classes[enemy_type]   // 0..3: weapon/frame/barrier/unit

// ④ Generate the item by category (weights, grind, attributes, special…)
generate_common_item_variances(item, area)

Box drops

// ① Rare check (same stacking algorithm as enemies)
table_index = table_index_for_area(area)
specs = rare_item_set.get_box_specs(mode, episode, difficulty, section_id, table_index)
det = rand(0, 0x100000000)
for spec in specs:
    det -= spec.probability
    if det < 0:
        return create_rare_item(spec.data, area)

// ② No rare → choose a weighted category from box_item_class_prob_table
item_class = weighted_pick(pt.box_item_class_prob_table, table_index)
    // 0=weapon 1=frame 2=barrier 3=unit 4=consumable 5=Meseta 6=empty

// ③ Generate an item if item_class < 6
if item_class < 6:
    generate_common_item_variances(item, area)

An important note on stacking:
Stacking starts with det, subtracts each spec’s probability in turn, and succeeds when the result becomes negative. This is equivalent to one random roll deciding among all specs; spec order does not affect the final distribution.
Sega’s original client instead rolls independently for each spec using rand(0, 0xFFFFFFFF) and compares the result with spec.probability. Later specs are effectively rarer because a success ends the flow. This makes no difference for enemies with one spec, but box lists with many candidates differ from stacking. The newserv author documents this in the comments.

Related pages