Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
MapClickCodes
Click code markers on the main ship radar to activate terminal codes (doors, turrets, mines, traps).
| Date uploaded | 2 weeks ago |
| Version | 1.0.12 |
| Download link | MrGlim-MapClickCodes-1.0.12.zip |
| Downloads | 372 |
| Dependency string | MrGlim-MapClickCodes-1.0.12 |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2100README
MapClickCodes
Click a terminal code marker (door / turret / mine / trap / etc.) on the main ship radar screen to activate that object's code — same effect as typing the code into the terminal.
Features
- Aligned click boxes (1.0.12) — ship radar hits use the screen submesh UV plus the map camera's lens distortion, so the hover tip and E land on the code you see. The old full-monitor box guess is not used on that screen.
- Tip → E sync (1.0.10) — hover tip caches the resolved marker for 0.25s; E activates that same object (
via=peek-cache) so tip code always matches activate even when UV is messy. - Gameplay-viewport match (1.0.10) — markers projected through the monitor glass into gameplay viewport (
how=gvp); preferred over broken screen-space AABB (V≈0 /ss-uv-no-aabb). - Screen-space UV (1.0.9+) — UV from the visible monitor face (multi-winding inverse bilinear). MeshCollider UV kept as bonus.
- Hover tip == click target (1.0.8+) — activate shares resolve with hover; gvp / peek-cache / mesh UV preferred over bounds guesses.
- MeshCollider look-ray UV (1.0.8) — RaycastAll map hits also MeshCollider-raycast the look ray for
textureCoord(runtime collider if needed; bonus when it works). - Hitbox shrink (1.0.7) — actual marker AABB + small pad (default HitRadius 0.012); no minHalf inflate.
- Radar never suppressed (1.0.7) — vanilla
SwitchRadarTargetForwardalways runs after a click attempt (code activate + radar advance OK). - Main map first (1.0.6) —
StartOfRound.mapScreenresolves before CrewMonitors map-feed panels; crew panels still work when clearly aimed at. - Terminal-occlusion UV (1.0.6) — plane/barycentric/
MeshColliderpreferred over ClosestBounds phantom UV; no hover miss spam on Terminal. - Hover feedback (1.0.5) — cursor icon +
Activate/Open CODE : [E]tip when aimed at a marker; HUD tip on activate. - Activate harden (1.0.5) — logs
inCooldown; no silent false success; no double door toggle; mesh-first UV. - Main radar fully standalone (1.0.9) —
StartOfRound.mapScreenworks with no CrewMonitors installed (no hard dependency / no TypeLoadException). CrewMonitors is an optional soft-dep for map-feed panel clicks only (reflection;crew=skipwhen absent). - Robust hits (1.0.3–1.0.9) —
RaycastAllprefers the real map mesh; screen-space UV primary; MeshCollider look-ray UV as bonus; falls back toCollider.Raycast,Bounds.IntersectRay, plane, closest-on-bounds. - Precise markers — UV →
mapCameraviewport, then actual AABB (+ small pad). Nearest-center / tight ray are hover-only / non-activating. Empty map areas do nothing. - Vanilla-friendly — radar target switching is never blocked; high-confidence mesh-UV hits still activate the code alongside the vanilla cycle.
- Host-gated — click-to-code is active only when the lobby host has this mod enabled (same fairness pattern as other MrGlim advantage QoL mods). Clients retry hello sync until the host acknowledges.
- Host-authoritative activate — non-host players hit-test locally, then the host runs
CallFunctionFromTerminal(local SFX on the clicker is fine). - SFX — plays the terminal code-broadcast animation/sound when available.
- Diagnostics — Info on successful activate and on interact-edge miss when markers>0; routine empty misses are Verbose-only. Enable VerboseLogging for UV/match detail.
How to use
- Stand in the ship and look at the large main map / radar monitor (or a CrewMonitors panel showing a map feed).
- Aim at a green/red code box on the radar feed — the cursor tip should change to Activate/Open CODE : [E] when you are on a marker.
- Press Interact (E) — that object's terminal code runs (
CallFunctionFromTerminal), with a short HUD tip confirming activation.
Config (BepInEx/config/com.benhough.lethal.MapClickCodes.cfg)
| Key | Default | Notes |
|---|---|---|
| Enabled | true | Master toggle |
| VerboseLogging | false | Extra UV / match traces |
| HitRadius | 0.012 | Extra UV padding around marker rects (small pad only; no minHalf inflate) |
| FlipUvV | true | Prefer V-flip when ranking UV candidates (all flip/orientation variants are still tried) |
| InteractRange | 4.5 | Max ray distance to the screen mesh |
| ShowHoverTip | true | Cursor icon + tip when aimed at a code marker |
Networking
Non-host clients with the mod send a named Netcode activate request to the host after a successful marker hit. The host validates the TerminalAccessibleObject (NetworkObjectId, with object-code fallback) and calls CallFunctionFromTerminal(). Door/turret/mine behaviour continues to use the object's own UnityEvents / ServerRpcs, so activation syncs like typing a code.
Both host and clients should install this mod from Thunderstore so everyone can click markers. Host must enable it for the lobby. Clients without the mod still see synced activations when someone else clicks, but cannot click themselves.
This is a convenience over walking to the terminal — treat it as an advantage feature for your lobby rules.
Dependencies
- BepInExPack only (no OpenBodyCams).
- CrewMonitors — optional. Main mapScreen click-to-code works without it.
Credits
Ben Hough (MrGlim) — Thunderstore team MrGlim.
AI disclosure
This mod was made with the help of generative AI. The code and this README were produced with an AI coding agent, directed by the author (MrGlim / Ben Hough). The Thunderstore package is listed in the AI Generated category.
CHANGELOG
Changelog
1.0.12
- Ship monitor hit test matches the picture. The radar image is only
Cube.001submesh 1 (material slot 1), not the whole monitor mesh. Clicks were measured on the full box, so the boxes sat offset from the codes. Hover and activate now ray-test that screen submesh and use its real UVs. - Lens distortion. The map camera's
RadarCameraVolumebends the image (Lens Distortion intensity 0.45) after the codes are drawn. The same HDRP warp is applied to the glass UV before it is compared to a code, so the tip and the click land on the marker you see. - Bounds / flip / gameplay-viewport guesses are not used on this monitor anymore.
1.0.11
- Non-readable mesh safety — before any
mesh.vertices/mesh.uv/mesh.trianglesaccess (barycentric UV), requiremesh.isReadable. ShipmapScreenmeshCube.001has Read/Write off; the old path spammed Unity Errors every hover/activate frame. Skip silently and keep tip/E via ss / gvp / peek-cache / bounds / existing MeshCollider textureCoord. - Runtime MeshCollider cook — do not add a new MeshCollider from a non-readable
MeshFilter.sharedMesh(same isReadable guard). Prefer any existing collider only. - One Verbose log per session when a CPU mesh path is skipped for
isReadable=false.
1.0.10
- Tip → E sync (peek-cache) — when hover tip resolves a marker, cache
TerminalAccessibleObject+ code +Time.unscaledTime(+ NetworkObjectId). On activate (Tick / SwitchRadar / Interact), if cache age ≤ 0.25s and the object is still valid/active, activate that same object. Logvia=peek-cache code=…. Guarantees tip code == E even when UV is messy. - Gameplay-viewport marker match (
how=gvp) — project each activemapRadarObjectthrough the monitor world quad into gameplay viewport; pick nearest within ~0.05 viewport of the look sample (flip variants). Prefer over broken screen-space AABB (ss-uv-no-aabbwith V≈0). High-confidence for peek and activate. - SS UV windings — try multiple corner windings when inverse bilinear collapses to edge V≈0/U≈0; skip weak edge
ss-onlyso it cannot block gvp/peek-cache. - Kept: never suppress SwitchRadar; main map before CrewMonitors soft-dep; terminal-style activate all matching codes + broadcast; tight-ish pads.
1.0.9
- Screen-space monitor UV (root fix) —
TryScreenSpaceMonitorUv: build the visible monitor face quad from mesh/renderer bounds (thinnest axis = normal, face toward gameplay camera), project corners + look sample withgameplayCamera.WorldToViewportPoint, inverse-bilinear to [0,1] UV. Tagss|uRaw|vFlipetc.; prefer over bounds-axis guesses. Fixes tip code mismatch and activate miss when MeshCollider look-ray UV fails (mcLook=0/bounds-uv-no-aabbwith U≈0). - Peek and activate share this path (unchanged unified resolve).
- If screen-space succeeds, bounds-only U=0 candidates are not scored as winners; phys/tex/bary kept as bonus when available.
- CrewMonitors panels: same screen-space UV on the panel MeshRenderer.
- Kept: tight hitboxes (actual rect + HitRadius pad); never suppress SwitchRadar; main map before crew; Info on interact miss with
why=+ UV tag. - Activate like terminal — on match, host/local calls
Terminal.CallFunctionInAccessibleTerminalObject(code)(all TAOs with that code) +PlayBroadcastCodeEffect; Info log only when CallFunction actually ran. - CrewMonitors soft-dep — no hard
BepInDependency; main mapScreen path never requires CrewMonitors; reflection failures →crew=skip.
1.0.8
- Unify hover + activate UV — activate uses the same UV→marker path as the hover tip (
requireMeshUv: false). Preferphys/tex/barywhen present; otherwise score bounds-orientation candidates (no more harduv=bounds-only missthat dead-ends activate while tip still works). - MeshCollider look-ray UV — when RaycastAll / force hits find the map via
OwnsRendereron a non-MeshCollider, alsoMeshCollider.Raycastthe player look ray (full interact range) fortextureCoord, adding a runtime non-convex collider if missing. Barycentric uses that surface hit point. - Auto orientation/flip — when only bounds UV is available, score all 3 axis-pair orientations × U/V flips and pick the global best AABB; winning tag logged.
- Logging — routine empty / bounds-only misses demoted to Verbose; interact-edge miss with
markers>0still one Info line withwhy=; successful activate keeps Info (code + UV tag + matchHow). - Kept: tight hitboxes (no minHalf); never suppress SwitchRadar; main map before CrewMonitors; no Terminal hover spam.
1.0.7
- Hitbox shrink — removed
minHalffloor (Max(0.028, pad*1.25)≈ 5.6% viewport boxes). Markers use actual RectTransform viewport AABB + small pad only (default HitRadius 0.012). Tiny markers (w/h < 0.008) use radiusMax(0.01, pad). - UV quality gate — activate matching prefers physics
textureCoord/ barycentric / mesh UV only. If anyphys/bary/texcandidates exist, bounds-orientation candidates are not scored. If only bounds candidates exist → activate miss (uv=bounds-only miss); hover can still peek via bounds. - Radar switch restored —
SwitchRadarTargetForward/SwitchRadarTargetAndSyncnever suppress vanilla. Prefix still tries high-conf activate, then alwaysreturn true. False aabb must never eat camera cycle; activating a code + advancing radar once is acceptable.ClickConsumedunused for radar (InteractTrigger dedupe only). - Ray tighten —
rayViewportMax0.1 → 0.04; loose ray removed from high-confidence activate path. - Kept: main
mapScreenbefore CrewMonitors; hover tip; no Terminal spam.
1.0.6
- Radar switch safety —
SwitchRadarTargetForwardonly suppresses when a high-confidence marker match activates (aabb/ray/bary/phys).center/centerFallbacknever activate and never setClickConsumed(empty-map E always cycles radar). Prefix wraps activate in try/catch and falls through to vanilla on any exception. - Main mapScreen first — resolve
StartOfRound.mapScreenmesh/mesh2 before CrewMonitors map-feed panels so the big radar is never stolen by a weak/false crew match. CrewMonitors panels still work when the look ray clearly hits those screens (main resolve fails). - Terminal-occlusion UV — under force/near, prefer
Collider.Raycast(with runtime non-convexMeshColliderif missing) →Bounds.IntersectRay→ plane face projection + barycentric/texture UV overClosestBounds(AABB phantom UV≈0,0 always missed). Mesh cast range up to ~10m behind Terminal blockers. Diag logsmc=0/1andvia=/ UV source (bary/phys/plane). - Hover spam fix —
forceMapContextonly when looking near the map screen or hovering a Map/Switch/Radar/monitor interact — not Terminal. Peek path never Info-logs misses every frame; activate keeps Info logs on interact edge only. - Reject corner junk UV
(0,0)/(1,1)from bounds-only candidates instead of loggingtried:N → miss.
1.0.5
- Hover cursor + tip — when aimed at a code marker on the main radar or CrewMonitors map panels, overrides the vanilla hover tip with
Activate CODE : [E](orOpen CODE : [E]for big doors) and enables the interact cursor icon so you can tell you are on a clickable code. - Activate path hardened — logs
inCooldownbefore invoke; vanillaCallFunctionFromTerminalis a silent no-op while cooling down, so we warn and skip claiming success (still play broadcast SFX; powered big doors maySetDoorToggleLocalClientonly when cooled-out or whenterminalCodeEventhas zero listeners). Never double-toggles doors when the event is already wired. - UV reliability — prefer
MeshCollider.textureCoord/ triangle barycentric UV over bounds-axis guesses; deprioritize/remove noisy edge UVs from ClosestBounds/IntersectRay force paths; tighten nearest-center max to 0.06 and center fallback to 0.05. - When
markers=0, logs why (orbit/ship vs TAOs without activemapRadarObject/mapRadarText). - Activate feedback — HUD tip (
Map code/Activated CODE) plus terminal broadcast SFX/animator. - Config: ShowHoverTip (default true) to toggle the hover cursor/tip override.
- Peek uses the same resolve + UV + marker match as activate (no cooldown / no side effects).
1.0.4
- Fix InteractTrigger playerBody check — vanilla calls
InteractTrigger.InteractwithPlayerControllerB.thisPlayerBody, notplayer.transform. The prefix now acceptsplayer.transform,thisPlayerBody, or any transform under the local player, so near-map interact clicks actually run. - Center fallback (forceMapContext) — when precise multi-UV AABB/center/ray matching still misses on SwitchRadar / near-map interact, pick the active
mapRadarObjectclosest to the click UV in mapCamera viewport space only if within 0.12 (via=centerFallback). Precise matching stays primary. - Optional CrewMonitors map-panel clicks — soft-detect look hits on panels whose material
mainTextureis aRenderTexturenamedCrewMapFeedRT_*, or whose parent name containsCrewMonitor. ReflectsCrewMonitors.CrewMonitorManagerslots for that panel'sMapFeedCamerawhen the assembly is present; otherwise skips. RT hits without a feed camera fall back tomapScreen.mapCamera. - Always keep Info logs on click / resolve attempts.
1.0.3
- Always Info-log on interact edge /
SwitchRadarTargetForward/ near-mapInteractTrigger— resolve failures now emitMapClick: resolve-fail … via=none(hits list) instead of staying silent when VerboseLogging is off. - Harder hit resolve — after RaycastAll + Collider.Raycast, prefer
mesh.bounds.IntersectRay; underforceMapContext, fall back to closest point on bounds so SwitchRadar almost never fails to produce a hitPoint when the mesh exists. Plane projection kept as last resort. Logvia=path that won. - Multi-UV marker match — score across ~12 UV candidates (3 local axis-pair orientations × U/V flips, plus MeshCollider texcoord variants). Markers scored by padded AABB / nearest-center and
mapCamera.ViewportPointToRay→ world distance to the marker (≤4m or viewport ≤0.1). Global best wins; no single-marker auto-fire. - Interact detection —
IngamePlayerSettingsInteract action,playerActions.Movement.Interact, thenKeyboard.current.eKeyhangar fallback. Tick forces map context when looking near the screen orhoveringOverTriggeris set. - Optional
InteractTrigger.Interactprefix — when local player interact fires while looking near the map mesh, try activate withforceMapContextalongside vanilla (does not block other triggers).
1.0.2
- Hit detection rewrite —
Physics.RaycastAll/ NonAlloc prefers a hit owned bymap.mesh/mesh2even when another collider sits in front; also triesCollider.Raycaston mesh colliders directly. - Plane fallback — if the mesh is missed but the player is in range (or vanilla
SwitchRadarTargetForwardfired), project the look ray onto the screen plane / bounds and derive UV from local mesh axes. - SwitchRadar force context — map-switch prefix always attempts UV→marker (
forceMapContext), so a blocker collider cannot skip click-to-code. - More forgiving markers — raised minimum hit half-size so old
HitRadius=0.012configs still work; also nearest-center match withinmax(0.06, HitRadius*3). - Sparse always-on Info logs on every map click attempt (top RaycastAll colliders, UV, flip, marker count, hit/miss) so hosts can verify without enabling VerboseLogging.
- Still main
mapScreenonly — never CrewMonitors clones. HostModGate client→host activate unchanged.
1.0.1
- Client map clicks now send a host-authoritative activate request (
NetworkObjectId+ object code); the host runsCallFunctionFromTerminal. - HostModGate retries hello sync every ~2s while connected until the host hello arrives; re-registers on
StartOfRound/NetworkManager.Initialize. - Clear warning logs when interact is blocked by the gate (waiting for hello vs host missing/disabled).
- Default HitRadius raised to
0.022; tiny door marker rects get a larger minimum hit size. - Still main radar only (
mapScreen.mesh/mesh2); CrewMonitors clones unchanged.
1.0.0
- Initial release.
- Click terminal code markers on the main ship radar to activate
CallFunctionFromTerminal. - Precise UV / viewport hit test against
mapRadarObjectRectTransforms. - Suppresses vanilla radar target switch only when a marker is hit.
- Host-gated networking (features active only when host has the mod enabled).
- Config: Enabled, VerboseLogging, HitRadius, FlipUvV, InteractRange.