Raycast python layer (collision raycast foundation)#1030
Closed
sloppynacho wants to merge 11 commits into
Closed
Conversation
…dow collapsed An indentation regression left the "Follow Publish" section (thresholds, unstuck knobs, dirty_runtime_cfg check) outside the `if ImGui.Begin(...)` block. When the Follow Formations window was collapsed, Begin returned False, skipping `dirty_runtime_cfg = False`, but the dedented `if dirty_runtime_cfg:` still ran — raising UnboundLocalError every frame. Re-indent the block back inside Begin and restore the "Show Flagging Window" checkbox as a sibling of the dirty check (it was accidentally nested under it, only rendering on frames where a setting changed)
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.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Python layer of the collision-raycast foundation: an ergonomic,
typed
Map.RaycastAPI over the nativePyMapbridge, with all geometry mathin Python (the native side is a thin raw bridge — paired C++ change lives on
the
Raycastcppbranch of the C++ repo). Enemy/agent detection is intentionallykept out of the library foundation.
What's included
Map.Raycast(Py4GWCoreLib/Map.py) — new nested class besideMap.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;.blockedis the LoS answer.GetProps()/GetPropGeometry(prop_id)— prop enumeration + world-space collision mesh.RaycastHit/PropHit/PropInfo; not@frame_cache'd.raycast_math.py(Py4GWCoreLib/native_src/internals/) — pure, DLL-free mathhelper (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.Widgets/Coding/Debug/Guild Wars/) — renamed fromLoS Tester; consumes
Map.Raycast.*; cone/enemy detection stays widget-side;cone rays configurable up to 200.
Design notes
derived calculation lives in Python, so behavior is tunable without a rebuild.
CastTerraincorrects a pre-existing bug: the bound terrain kernel returns aparametric fraction
[0,1], not world units — now scaled byseg_lenso thehit lands at the wall, not the player's feet.
(
source='unavailable'/n_scanned == -1), so callers never read a failedprobe as line of sight.
Test plan
raycast_mathunit-tested during development (27 cases: normalize, hitreconstruction, blocked decision,
v*M, nearest-block combine) — pass onPython 3.13 (32-bit), no DLL needed.
ast.parseclean.matches the pre-refactor LoS Tester; terrain block marker lands on the wall.
Notes
Py4GW.dllfrom theC++
Raycastcppbranch. The Python wrapper and the rebuilt DLL must ship together.