← All 10 Apps

04LootForge

Procedural loot. 10 bases x 6 rarities x 12 affinities.

Level x Rarity x Affinity = Item. Deterministic. Seedable. Same seed = same item. Drop tables for any game genre.

Atoms
10 bases
Latency
~15,000ns
Size
5 KB
Use Cases
ARPG loot drops, roguelike item generation, gacha game rewards, crafting systems
Download .py

Output

Click "Run Demo" to execute in your browser (Python runs via Pyodide)...

How It Works

How LootForge Works

The lattice is a Python dict. Lookup is a hash table operation. Input keys, output values. That's the entire pattern.

Integrating With Your Engine

Unity: Call from C# via the embedded Python interpreter, or export the lattice to JSON and load it with JsonUtility.

Unreal: Use the Python plugin, or convert the Python dict to a TMap in C++.

Godot: GDScript can import Python directly, or use JSON.parse_string on the exported lattice.

Web/WASM: Pyodide runs the Python file directly in the browser. This demo page demonstrates that approach.

Extending the App

Add new entries to the lattice dictionary. The lookup function is generic: it takes any key and returns the corresponding value, or a default. The more entries you add, the more coverage you get. Performance stays O(1) regardless of size.

Key Insight

Every game logic problem that's hard-coded with if/else chains is actually a lookup table in disguise. (state, event) -> action is the universal pattern. The lattice just makes that pattern explicit and O(1).

Source Code

#!/usr/bin/env python3
"""
LootForge: Procedural loot generation.
Level x Rarity x Affinity = Item. Deterministic. Seedable. O(1).

No dependencies. Pure Python.
"""
import random
import time

# === THE LATTICE: loot tables ===
RARITY_TIERS = {
    "common":    {"weight": 50, "color": "\033[90m", "stat_mult": 1.0},
    "uncommon":  {"weight": 25, "color": "\033[92m", "stat_mult": 1.5},
    "rare":      {"weight": 15, "color": "\033[96m", "stat_mult": 2.5},
    "epic":      {"weight": 7,  "color": "\033[95m", "stat_mult": 4.0},
    "legendary": {"weight": 2,  "color": "\033[93m", "stat_mult": 7.0},
    "mythic":    {"weight": 1,  "color": "\033[91m", "stat_mult": 12.0}
}

ITEM_BASES = {
    "sword":  {"base_dmg": 10, "base_spd": 5, "affinity": ["fire", "ice", "lightning", "holy", "dark"]},
    "axe":    {"base_dmg": 15, "base_spd": 2, "affinity": ["earth", "fire", "blood"]},
    "bow":    {"base_dmg": 8,  "base_spd": 8, "affinity": ["wind", "ice", "poison"]},
    "staff":  {"base_dmg": 12, "base_spd": 4, "affinity": ["arcane", "fire", "nature", "holy", "dark"]},
    "dagger": {"base_dmg": 6,  "base_spd": 10,"affinity": ["poison", "shadow", "blood"]},
    "mace":   {"base_dmg": 14, "base_spd": 3, "affinity": ["holy", "earth", "lightning"]},
    "spear":  {"base_dmg": 11, "base_spd": 5, "affinity": ["wind", "earth", "ice"]},
    "hammer": {"base_dmg": 18, "base_spd": 1, "affinity": ["earth", "fire", "lightning"]},
    "scythe": {"base_dmg": 13, "base_spd": 4, "affinity": ["dark", "blood", "shadow"]},
    "wand":   {"base_dmg": 5,  "base_spd": 12,"affinity": ["arcane", "nature", "ice"]}
}

PREFIXES = {
    "fire":     {"name": "Flame",      "stat": "dmg", "mult": 1.3, "desc": "burns foes"},
    "ice":      {"name": "Frost",      "stat": "spd", "mult": 1.2, "desc": "freezes foes"},
    "lightning":{"name": "Thunder",    "stat": "spd", "mult": 1.4, "desc": "shocks foes"},
    "holy":     {"name": "Divine",     "stat": "dmg", "mult": 1.2, "desc": "blesses wielder"},
    "dark":     {"name": "Shadow",     "stat": "dmg", "mult": 1.3, "desc": "curses foes"},
    "earth":    {"name": "Stone",      "stat": "dmg", "mult": 1.4, "desc": "crushes armor"},
    "wind":     {"name": "Gale",       "stat": "spd", "mult": 1.3, "desc": "swift strikes"},
    "poison":   {"name": "Venom",      "stat": "dmg", "mult": 1.1, "desc": "poisons foes"},
    "blood":    {"name": "Bloodletting","stat":"dmg", "mult": 1.5, "desc": "drains life"},
    "arcane":   {"name": "Arcane",     "stat": "dmg", "mult": 1.2, "desc": "mana flows"},
    "nature":   {"name": "Verdant",    "stat": "spd", "mult": 1.1, "desc": "nature aids"},
    "shadow":   {"name": "Umbral",     "stat": "spd", "mult": 1.2, "desc": "strikes from shadow"}
}

AFFINITY_PREFIX_LOOKUP = {}
for base, info in ITEM_BASES.items():
    for aff in info["affinity"]:
        AFFINITY_PREFIX_LOOKUP[(base, aff)] = aff

def roll_rarity(rng: random.Random) -> str:
    """O(1) rarity roll weighted by tier."""
    tiers = list(RARITY_TIERS.keys())
    weights = [RARITY_TIERS[t]["weight"] for t in tiers]
    return rng.choices(tiers, weights=weights, k=1)[0]

def roll_base(rng: random.Random) -> str:
    """O(1) base weapon roll."""
    return rng.choice(list(ITEM_BASES.keys()))

def roll_affinity(rng: random.Random, base: str) -> str:
    """O(1) affinity roll for the base."""
    affinities = ITEM_BASES[base]["affinity"]
    return rng.choice(affinities)

def generate_item(level: int, seed: int = None) -> dict:
    """O(1) item generation. Deterministic with seed."""
    rng = random.Random(seed) if seed is not None else random.Random()

    base = roll_base(rng)
    rarity = roll_rarity(rng)
    affinity = roll_affinity(rng, base)

    base_stats = ITEM_BASES[base]
    rarity_mult = RARITY_TIERS[rarity]["stat_mult"]
    level_mult = 1.0 + (level - 1) * 0.1
    prefix = PREFIXES[affinity]

    if prefix["stat"] == "dmg":
        damage = int(base_stats["base_dmg"] * rarity_mult * level_mult * prefix["mult"])
        speed = base_stats["base_spd"]
    else:
        damage = int(base_stats["base_dmg"] * rarity_mult * level_mult)
        speed = int(base_stats["base_spd"] * rarity_mult * level_mult * prefix["mult"])

    return {
        "name": f"{prefix['name']} {base.title()}",
        "rarity": rarity,
        "affinity": affinity,
        "level": level,
        "damage": damage,
        "speed": speed,
        "effect": prefix["desc"],
        "seed": seed
    }

# === DEMO ===
def demo():
    print("=" * 50)
    print("  LootForge: Procedural loot, O(1) generation")
    print("=" * 50)
    print()
    print("  Dropping 10 items at level 15...")
    print()

    for i in range(10):
        start = time.perf_counter_ns()
        item = generate_item(level=15, seed=42+i)
        elapsed = time.perf_counter_ns() - start

        rarity_color = RARITY_TIERS[item["rarity"]]["color"]
        reset = "\033[0m"
        print(f"  [{item['seed']}] {rarity_color}{item['rarity'].upper():10s}{reset} {item['name']:25s} "
              f"DMG:{item['damage']:4d} SPD:{item['speed']:3d} [{elapsed}ns]")

    print()
    print("=" * 50)
    print("  Same seed = same item. Deterministic. O(1).")
    print("=" * 50)

if __name__ == "__main__":
    demo()