REPOPathfinder
BepInEx plugin for R.E.P.O. Renders an in-world NavMesh dot trail to the current extraction or truck. Cached corners + player projection keep dots stable as you move. F4 toggle, F5 Auto/Truck, F6 IMGU
About this mod Author’s original text
REPOPathfinder
A BepInEx plugin for R.E.P.O. that renders an in-world dot trail along the NavMesh path to the current extraction point — or back to the truck once all extractions are complete. It mirrors the same target-selection logic the in-map "backtrack" dots use, projected into world space so you can follow it without opening the map.
Hotkeys (configurable, all default to F-keys):
- F4 — toggle the trail on / off.
- F5 — switch the destination between Auto (game-driven: current extraction, or truck when all are complete) and Truck (forces the truck regardless of extraction state, for going back to charge items mid-run). Choice persists.
- F6 — open the customization panel: RGBA color sliders, hex input, color presets, and live sliders for dot size / flow speed / spacing. Edits write back to the BepInEx config so they persist across sessions.
What the DLL actually does
On plugin Awake(), it:
- Reads its config. A standard BepInEx config file (BepInEx/config/isaia.repopathfinder.cfg) defines all hotkeys, dot visuals, animation tunables, and the path-recompute threshold. A [Internal] ConfigVersion key migrates stale defaults from prior versions in place — values that exactly match a previous default get overwritten with the current default; user-customized values are left alone.
- Creates a DontDestroyOnLoad GameObject. Adds two MonoBehaviours to it: PathfinderManager (path / animation / rendering) and PathfinderCustomizeUI (the F6 IMGUI overlay).
- Installs Harmony input-blocking patches. InputBlocker is gated on a single static BlockInput flag flipped by the customize UI; it is inert when the menu is closed. While the menu is open, the following are short-circuited so cursor movement doesn't drive the camera and clicks don't fire weapons:
- Legacy: UnityEngine.Input.GetAxis, GetAxisRaw, GetMouseButton, GetMouseButtonDown, GetMouseButtonUp — return 0f / false.
- New: UnityEngine.InputSystem.InputAction.ReadValue() for Vector2, float, and Vector3 — return default(T). Bound dynamically via reflection, so the plugin still loads if the new InputSystem assembly is absent.
- Input.GetKey / GetKeyDown / GetKeyUp are deliberately not patched, so F4 / F5 / F6 keep working.
Path computation
The path is cached in world space, not recomputed every frame:
- Target resolution. Auto mode: RoundDirector.allExtractionPointsCompleted (read by reflection) → LevelGenerator.LevelPathTruck.transform.position; otherwise RoundDirector.extractionPointCurrent.transform.position. Truck mode: always LevelPathTruck. Identity is the ExtractionPoint reference or the literal string "truck".
- Recompute trigger. A new path is computed only when:
- There is no cached path yet,
- The target identity changed (different extraction, or Auto↔Truck flip),
- The player has drifted further than OffPathRecomputeThresholdMeters (default 3.0) from the cached polyline (closest-point-on-line-segment over each cached segment), or
- A scene change invalidated the cache.
- Compute & cache. NavMesh.CalculatePath(playerNavmeshPos, targetPos, AllAreas, path) is called once. The corners and prefix arc-distances are stored; the displayed dots reference these stable world-space points for as long as the cache lives. playerNavmeshPos is PlayerAvatar.LastNavmeshPosition (read by reflection — internal field).
- Each frame. The player is projected onto the cached polyline to produce a playerArc scalar; that's the trail's "back end". Walking forward changes only playerArc; the cached corners are untouched, so dot world positions stay stable regardless of how the player moves.
Animation & rendering
- A pool of MaxDots (default 30) sphere primitives, colliders stripped, sharing one material with per-dot color set via MaterialPropertyBlock.
- A single shared _animOffset ∈ [0, spacing) advances by FlowSpeed m/s. When it crosses spacing the circular pool pointer _frontPool decrements, which makes every sphere's slot index increment by 1 simultaneously. Spacing stays per
Install & use Install: BepInEx plugin
- The archive from playbuff is the mod itself — usually a BepInEx plugin (a .dll or a plugin folder once unzipped).
- Recommended: use a community mod manager (such as r2modman) — pick this game, import the mod, and the manager sets up BepInEx and its dependencies for you.
- Manual route: install the BepInEx loader in the game folder, then drop the unzipped .dll or plugin folder into BepInEx/plugins/.
- Launch the game — the BepInEx console logs every plugin it loads; seeing this mod in the log means it is installed.
Mods with listed dependencies need those installed too, or they will not load. Options are usually changed in-game or in the plugin's config file.
Install these first, or the mod will not work: