Add target resolution system documentation
This commit is contained in:
parent
0e1c46cdcc
commit
0c43859651
1 changed files with 96 additions and 0 deletions
96
docs/how/targeting.rst
Normal file
96
docs/how/targeting.rst
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
=======================
|
||||
target resolution
|
||||
=======================
|
||||
|
||||
how we find what the player is talking about.
|
||||
|
||||
the problem
|
||||
===========
|
||||
|
||||
when a player types "attack goblin" or "get sword", we need to figure out
|
||||
which goblin, which sword. could be multiple matches. could be an alias.
|
||||
could be "2.goblin" to mean the second one.
|
||||
|
||||
the system uses graceful degradation: try exact matches, fall back to prefix
|
||||
matches, then aliases, then ordinal selection.
|
||||
|
||||
parsing the raw input
|
||||
=====================
|
||||
|
||||
``parse_target(raw)`` extracts ordinal prefixes::
|
||||
|
||||
"goblin" → (1, "goblin")
|
||||
"2.goblin" → (2, "goblin")
|
||||
"3.rat" → (3, "rat")
|
||||
|
||||
only ordinals >= 1 are valid. "0.goblin" or "-1.goblin" are treated as literal
|
||||
names (weird, but no crash).
|
||||
|
||||
matching priority
|
||||
=================
|
||||
|
||||
``resolve_target(name, candidates, key=None)`` uses a priority-based matching
|
||||
flow:
|
||||
|
||||
**four match priorities** (checked in order, stops at first non-empty result):
|
||||
|
||||
1. exact name match (case-insensitive)
|
||||
2. name prefix match ("gob" matches "goblin")
|
||||
3. exact alias match
|
||||
4. alias prefix match ("gobb" matches alias "gobby")
|
||||
|
||||
collects ALL matches at each priority level before moving to the next. this
|
||||
prevents a prefix match from shadowing a later exact alias match.
|
||||
|
||||
**ordinal selection**: if an ordinal was parsed (e.g., "2.goblin"), picks the
|
||||
Nth match from whichever priority level produced results.
|
||||
|
||||
**fallback**: returns None if no matches found at any level.
|
||||
|
||||
custom key function lets you adapt to non-standard objects (e.g., dicts with
|
||||
a "name" field).
|
||||
|
||||
finding entities
|
||||
================
|
||||
|
||||
``find_entity_on_tile(name, player, z_filter=True)`` searches players and mobs
|
||||
on the same tile.
|
||||
|
||||
filters:
|
||||
- excludes the player themselves
|
||||
- skips dead mobs
|
||||
- z-axis filtering: only matches entities on same z-level (both grounded or
|
||||
both flying). flying creatures can't attack grounded ones by default.
|
||||
|
||||
sorts results to prefer Players over Mobs.
|
||||
|
||||
finding things
|
||||
==============
|
||||
|
||||
``find_thing_on_tile(name, zone, x, y)`` searches ground items at coordinates.
|
||||
only Thing instances.
|
||||
|
||||
``find_in_inventory(name, player)`` searches player inventory. only Thing
|
||||
instances.
|
||||
|
||||
ordinal disambiguation
|
||||
======================
|
||||
|
||||
if there are three goblins, you can target the second with "2.goblin"::
|
||||
|
||||
attack 2.goblin
|
||||
|
||||
the ordinal is parsed, then resolve_target collects matches and picks the Nth
|
||||
one. ordinal selection happens after all four priority levels have been tried,
|
||||
operating on whichever level produced matches.
|
||||
|
||||
case sensitivity
|
||||
================
|
||||
|
||||
all matching is case-insensitive. "Goblin", "goblin", "GOBLIN" all work.
|
||||
|
||||
code
|
||||
====
|
||||
|
||||
- ``src/mudlib/commands/targeting.py`` - parse and resolve functions
|
||||
- ``tests/test_targeting.py`` - test coverage for all priority levels
|
||||
Loading…
Reference in a new issue