Visual quest logic. Status evaluation in O(1).
5 complete quests with full state evaluation. Player has X, needs Y, give Z. Auto-detects progress, completion, missing items, and rewards.
The lattice is a Python dict. Lookup is a hash table operation. Input keys, output values. That's the entire pattern.
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.
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.
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).
#!/usr/bin/env python3
"""
QuestFlow: Visual quest logic.
Player has X, needs Y, give Z. O(1) evaluation. No conversation tree.
No dependencies. Pure Python.
"""
import time
# === THE LATTICE: quest state evaluation ===
QUESTS = {
"the_lost_sword": {
"title": "The Lost Sword",
"start": {"npc": "old_hermit", "level": 3},
"requires": {
"lost_sword_piece_1": "explore_forest",
"lost_sword_piece_2": "defeat_goblin_king",
"lost_sword_piece_3": "dungeon_ruins"
},
"rewards": {
"gold": 500,
"xp": 1000,
"item": "legendary_blade"
},
"status_atoms": {
"not_started": "Ask the old hermit about the lost sword.",
"in_progress": "Find the three pieces of the lost sword.",
"ready_to_complete": "Bring the pieces to the hermit.",
"completed": "You wield the Legendary Blade!"
}
},
"rescue_the_princess": {
"title": "Rescue the Princess",
"start": {"npc": "king", "level": 5},
"requires": {
"rescue_key": "defeat_dragon",
"rescue_map": "buy_from_merchant",
"rescue_potion": "brew_alchemist"
},
"rewards": {
"gold": 2000,
"xp": 5000,
"item": "royal_favor"
},
"status_atoms": {
"not_started": "The king begs for your help.",
"in_progress": "Gather what you need to storm the tower.",
"ready_to_complete": "Storm the dragon's tower!",
"completed": "The princess is safe. You are a hero."
}
},
"find_the_artifact": {
"title": "Find the Ancient Artifact",
"start": {"npc": "scholar", "level": 8},
"requires": {
"artifact_clue_1": "read_ancient_book",
"artifact_clue_2": "interview_ghost",
"artifact_clue_3": "solve_riddle"
},
"rewards": {
"gold": 5000,
"xp": 10000,
"item": "ancient_artifact"
},
"status_atoms": {
"not_started": "The scholar seeks the ancient artifact.",
"in_progress": "Follow the three clues.",
"ready_to_complete": "Claim the artifact!",
"completed": "The artifact is yours. Power flows."
}
},
"clear_the_dungeon": {
"title": "Clear the Haunted Dungeon",
"start": {"npc": "guard_captain", "level": 4},
"requires": {
"dungeon_boss_defeated": "explore_dungeon"
},
"rewards": {
"gold": 300,
"xp": 800,
"item": "dungeon_key"
},
"status_atoms": {
"not_started": "The dungeon is overrun.",
"in_progress": "Descend and clear all monsters.",
"ready_to_complete": "The boss awaits!",
"completed": "The dungeon is safe."
}
},
"master_the_forge": {
"title": "Master the Forge",
"start": {"npc": "blacksmith", "level": 2},
"requires": {
"forge_hammer": "buy_supplies",
"forge_anvil": "complete_tutorial",
"forge_bellows": "gather_coal"
},
"rewards": {
"gold": 200,
"xp": 500,
"item": "master_smith_title"
},
"status_atoms": {
"not_started": "Learn smithing from the master.",
"in_progress": "Gather forge components.",
"ready_to_complete": "Build the forge!",
"completed": "You are a Master Smith."
}
}
}
def evaluate_quest(quest_id: str, player_items: set) -> dict:
"""O(1) quest evaluation. Returns status, missing items, and rewards."""
quest = QUESTS.get(quest_id)
if not quest:
return {"status": "unknown_quest", "quest_id": quest_id}
required = set(quest["requires"].keys())
has = player_items & required
missing = required - player_items
if len(missing) == 0:
status = "ready_to_complete"
progress = "100%"
elif len(has) == 0:
status = "not_started"
progress = "0%"
else:
status = "in_progress"
progress = f"{len(has)}/{len(required)}"
return {
"quest_id": quest_id,
"title": quest["title"],
"status": status,
"progress": progress,
"missing": list(missing),
"hint": quest["status_atoms"].get(status, ""),
"rewards": quest["rewards"] if status == "ready_to_complete" else None
}
def get_quest_atom(quest_id: str, status: str) -> str:
"""O(1) quest status -> flavor text."""
quest = QUESTS.get(quest_id)
if not quest:
return "Quest not found."
return quest["status_atoms"].get(status, "Status unknown.")
# === DEMO ===
def demo():
print("=" * 50)
print(" QuestFlow: Visual quest logic, O(1) eval")
print("=" * 50)
print()
# Scenario: player has some quest items
player_inventory = {
"lost_sword_piece_1",
"lost_sword_piece_2",
"dungeon_boss_defeated",
"forge_hammer"
}
print(f" Player inventory: {sorted(player_inventory)}")
print()
for quest_id in QUESTS.keys():
start = time.perf_counter_ns()
result = evaluate_quest(quest_id, player_inventory)
elapsed = time.perf_counter_ns() - start
status_icon = {
"not_started": "[ ]",
"in_progress": "[~]",
"ready_to_complete": "[!]",
"completed": "[X]"
}.get(result["status"], "[?]")
print(f" {status_icon} {result['title']:30s} [{result['progress']}] [{elapsed}ns]")
print(f" Status: {result['status']}")
print(f" Hint: {result['hint']}")
if result['missing']:
print(f" Missing: {', '.join(result['missing'])}")
if result['rewards']:
print(f" REWARD: {result['rewards']}")
print()
print("=" * 50)
print(" 5 quests. 1 file. O(1) evaluation.")
print("=" * 50)
if __name__ == "__main__":
demo()