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