Skip to main content

Overview

The GameObj class represents any game object (NPC, loot, inventory item, room description, etc.) within Lich. It provides a powerful tracking system with categorized registries and efficient identity management. GameObj tracks all in-game entities across specialized registries:
  • Loot - Items on the ground
  • NPCs - Non-player characters
  • PCs - Player characters
  • Inventory - Your carried items
  • Room descriptions - Objects in room text
  • Containers - Items inside containers
  • Hands - What you’re holding

Quick Start

# Find an object by ID
obj = GameObj['12345']

# Find by noun
goblin = GameObj['goblin']

# Find by name pattern
item = GameObj[/silver.*sword/]

# Access all NPCs in the room
GameObj.npcs.each do |npc|
  echo "#{npc.name} (ID: #{npc.id})"
end

# Check loot on the ground
if coins = GameObj.loot.find { |obj| obj.noun == 'coins' }
  fput "get ##{coins.id}"
end

Instance Attributes

id
String
required
The unique string ID of this object from the game
noun
String
Noun used to refer to this object (e.g. “goblin”, “sword”)
name
String
Full descriptive name (e.g. “a snarling goblin”, “a silver-edged longsword”)
before_name
String
Text prepended before the name in full display
after_name
String
Text appended after the name in full display

Instance Methods

to_s

Returns the object’s noun as a string.
obj = GameObj['goblin']
echo obj.to_s  # => "goblin"
return
String
The object’s noun

full_name

Returns the complete display name, assembling before/name/after parts.
obj = GameObj['sword']
echo obj.full_name  # => "a silver-edged longsword"
return
String
The full assembled name

status

Returns the current status of this NPC or PC, or “gone” if not found.
npc = GameObj['goblin']
if npc.status == 'dead'
  echo "Goblin is dead"
end
return
String
Status string (“dead”, “stunned”, etc.) or nil if no status, “gone” if not present

type

Returns a comma-separated string of matching type tags for classification.
obj = GameObj['acantha']
echo obj.type  # => "herb,alchemy"

if obj.type?('herb')
  echo "This is an herb"
end
return
String
Comma-separated type tags, or nil if no types match

type?(type_to_check)

Checks if the object matches a specific type tag.
type_to_check
String
required
The type string to check for
if obj.type?('weapon')
  echo "This is a weapon"
end
return
Boolean
True if the object has this type tag

contents

Returns the contents of this container object.
pack = GameObj['backpack']
pack.contents.each do |item|
  echo item.name
end
return
Array<GameObj>
Array of GameObj instances inside this container, or nil

Class Methods - Registries

GameObj.npcs

Returns all NPCs currently visible in the room.
GameObj.npcs.each do |npc|
  echo "NPC: #{npc.name} (#{npc.id})"
end
return
Array<GameObj>
Array of NPC objects, or nil if none

GameObj.loot

Returns all loot items on the ground.
if skin = GameObj.loot.find { |obj| obj.noun == 'skin' }
  fput "get ##{skin.id}"
end
return
Array<GameObj>
Array of loot objects, or nil if none

GameObj.inv

Returns all items in your inventory (top-level, not inside containers).
GameObj.inv.each do |item|
  echo "Carrying: #{item.name}"
end
return
Array<GameObj>
Array of inventory objects, or nil if none

GameObj.pcs

Returns all player characters visible in the room.
GameObj.pcs.each do |pc|
  echo "Player: #{pc.name}"
end
return
Array<GameObj>
Array of PC objects, or nil if none

GameObj.right_hand / GameObj.left_hand

Returns the object in your right or left hand.
if weapon = GameObj.right_hand
  echo "Holding: #{weapon.name}"
end
return
GameObj
Object in hand, or nil if empty

GameObj.room_desc

Returns objects mentioned in the room description.
GameObj.room_desc.each do |obj|
  echo "Room object: #{obj.name}"
end
return
Array<GameObj>
Array of room description objects, or nil if none

GameObj.containers

Returns a hash of all containers and their contents.
GameObj.containers.each do |container_id, items|
  echo "Container #{container_id}:"
  items.each { |item| echo "  - #{item.name}" }
end
return
Hash
Hash mapping container IDs to arrays of GameObj instances

Class Methods - Lookup

GameObj[val]

Finds a GameObj by ID (numeric string), noun (single word), name, or Regexp.
val
String | Regexp
required
ID string, noun, name, or pattern to search for
# By ID
obj = GameObj['12345']

# By noun
goblin = GameObj['goblin']

# By name
sword = GameObj['silver longsword']

# By pattern
item = GameObj[/.*sword$/]
return
GameObj
First matching object, or nil if not found

Class Methods - Targeting

GameObj.targets

Returns active NPCs currently targeted (from XML target data).
GameObj.targets.each do |target|
  echo "Targeting: #{target.name}"
end
return
Array<GameObj>
Array of targeted NPC objects

GameObj.target

Returns the single NPC or PC matching the current target ID.
if target = GameObj.target
  echo "Current target: #{target.name}"
end
return
GameObj
Current target object, or nil

GameObj.dead

Returns all NPCs with a status of “dead”.
if corpses = GameObj.dead
  corpses.each { |npc| echo "Dead: #{npc.name}" }
end
return
Array<GameObj>
Array of dead NPCs, or nil if none

Class Methods - Clearing

GameObj.clear_loot / clear_npcs / clear_pcs / clear_inv

Clears the specified registry. The shared identity index is preserved.
GameObj.clear_loot  # Clear loot registry
GameObj.clear_npcs  # Clear NPCs and their status
GameObj.clear_pcs   # Clear PCs and their status
GameObj.clear_inv   # Clear inventory

Advanced: Identity Index

GameObj uses a shared persistent identity index for efficient object reuse. Objects with the same id, noun, and name are the same logical entity across all registries.

GameObj.prune_index!

Removes stale entries from the identity index (entries not seen within TTL).
ttl
Integer
default:"900"
Time-to-live in seconds (default 15 minutes)
verbose
Boolean
default:"false"
Print detailed memory report
# Prune entries older than 5 minutes
GameObj.prune_index!(ttl: 300)

# Prune with detailed report
GameObj.prune_index!(verbose: true)

GameObj.index_stats

Returns diagnostic information about the identity index state.
verbose
Boolean
default:"false"
Print formatted report to stdout
stats = GameObj.index_stats
echo "Total entries: #{stats[:total_entries]}"
echo "Stale entries: #{stats[:stale_entries]}"

# Or print full report
GameObj.index_stats(verbose: true)

Examples

Find and interact with objects

# Find and pick up specific loot
if coins = GameObj.loot.find { |obj| obj.noun == 'coins' }
  fput "get ##{coins.id}"
end

# Target the first living NPC
if npc = GameObj.npcs.find { |n| n.status != 'dead' }
  fput "target ##{npc.id}"
end

Filter objects by type

# Find all herbs in inventory
herbs = GameObj.inv.select { |obj| obj.type?('herb') }
herbs.each { |herb| echo herb.name }

# Check if holding a weapon
if weapon = GameObj.right_hand
  if weapon.type?('weapon')
    echo "Armed with #{weapon.name}"
  end
end

Search containers

# Find a specific container
if pack = GameObj.inv.find { |obj| obj.noun == 'backpack' }
  # Search its contents
  if gem = pack.contents.find { |obj| obj.type?('gem') }
    fput "get ##{gem.id} from ##{pack.id}"
  end
end

Combat targeting

# Attack all living targets
GameObj.targets.each do |target|
  next if target.status == 'dead'
  fput "attack ##{target.id}"
  waitrt?
end

# Check for dead NPCs to loot
if dead_npcs = GameObj.dead
  dead_npcs.each do |corpse|
    fput "loot ##{corpse.id}"
  end
end

Build docs developers (and LLMs) love