Skip to content

Raycast python layer (collision raycast foundation)#1031

Open
sloppynacho wants to merge 1 commit into
apoguita:mainfrom
sloppynacho:raycast-only
Open

Raycast python layer (collision raycast foundation)#1031
sloppynacho wants to merge 1 commit into
apoguita:mainfrom
sloppynacho:raycast-only

Conversation

@sloppynacho

Copy link
Copy Markdown
Contributor

Summary

Adds the Python layer of the collision-raycast foundation: an ergonomic,
typed Map.Raycast API over the native PyMap bridge, with all geometry math
in Python
(the native side is a thin raw bridge — paired C++ change lives on
the Raycastcpp branch of the C++ repo). Enemy/agent detection is intentionally
kept out of the library foundation.

What's included

  • Map.Raycast (Py4GWCoreLib/Map.py) — new nested class beside Map.Pathing:
    • Cast(start, end) — combined terrain + walkable-prop (engine returns a point).
    • CastTerrain(start, end) — terrain only (scales the native fraction by seg_len).
    • CastInteractive(start, end) — interactive-prop meshes (doors/gates/gadgets).
    • HasLos(start, end, terrain=, props=) — nearest-block combine; .blocked is the LoS answer.
    • GetProps() / GetPropGeometry(prop_id) — prop enumeration + world-space collision mesh.
    • Returns typed RaycastHit / PropHit / PropInfo; not @frame_cache'd.
  • raycast_math.py (Py4GWCoreLib/native_src/internals/) — pure, DLL-free math
    helper (normalize, segment length, blocked decision, hit reconstruction, prop-mesh
    v*M) + the result NamedTuples. Unit-testable without the game running.
  • __init__.py — surfaces the native module (import PyMap + rebind).
  • stubs/PyMap.pyi — type stub for the thinned raw native signatures.
  • Raycaster Tester widget (Widgets/Coding/Debug/Guild Wars/) — renamed from
    LoS Tester; consumes Map.Raycast.*; cone/enemy detection stays widget-side;
    cone rays configurable up to 200.

Design notes

  • C++ is a faithful RAW bridge (engine intersect + live-memory walk only); every
    derived calculation lives in Python, so behavior is tunable without a rebuild.
  • CastTerrain corrects a pre-existing bug: the bound terrain kernel returns a
    parametric fraction [0,1], not world units — now scaled by seg_len so the
    hit lands at the wall, not the player's feet.
  • Availability is explicit: a probe that couldn't run is distinct from "clear LoS"
    (source='unavailable' / n_scanned == -1), so callers never read a failed
    probe as line of sight.

Test plan

  • raycast_math unit-tested during development (27 cases) — pass on Python 3.13 (32-bit), no DLL needed.
  • All touched modules ast.parse clean.
  • In-game parity via the Raycaster Tester widget: terrain/prop/cone behavior matches the pre-refactor LoS Tester; terrain block marker lands on the wall.

Notes

  • Breaking native change — requires the matching thinned Py4GW.dll from the C++ Raycastcpp branch. The Python wrapper and the rebuilt DLL must ship together.

  feat: add Map.Raycast python layer (collision raycast foundation)

  Python side of the collision-raycast foundation: surfaces the thinned native
  PyMap bridge as an ergonomic, typed Map.Raycast API, with ALL geometry math in
  Python (the native side returns raw engine numbers).

  - Py4GWCoreLib/Map.py: new nested Map.Raycast class beside Map.Pathing, with
    point->point primitives Cast / CastTerrain / CastInteractive / HasLos plus
    GetProps / GetPropGeometry. Returns typed RaycastHit / PropHit / PropInfo; not
    @frame_cache'd (results vary by start/end). CastTerrain scales the native
    terrain hit fraction [0,1] by seg_len to world units.
  - Py4GWCoreLib/native_src/internals/raycast_math.py: pure, DLL-free math helper
    (segment length, normalize, blocked decision, hit reconstruction, prop-mesh
    v*M transform) + frozen RaycastHit / PropHit / PropInfo result types.
  - Py4GWCoreLib/__init__.py: surface the native module (import PyMap + rebind),
    matching the PyAgent / PyPlayer precedent.
  - stubs/PyMap.pyi: type stub for the thinned raw native signatures.
  - Widgets/Coding/Debug/Guild Wars/Raycaster Tester.py: debug widget (renamed
    from LoS Tester) consuming Map.Raycast.*; cone/enemy detection stays widget
    side; cone rays configurable up to 200.

  Pairs with the native thinning on the Raycastcpp branch of the C++ repo. Enemy/
  agent detection is intentionally out of the library foundation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant