DynamicCrosshair
Crosshair that marks where your gun is really pointing and traces its live spread cone, including bullet drop and muzzle parallax. Client-side, no patches.
By PapaSalazar
| Last updated | 2 hours ago |
| Total downloads | 15 |
| Total rating | 1 |
| Categories | Mods |
| Dependency string | PapaSalazar-DynamicCrosshair-1.0.0 |
| Dependants | 0 other packages depend on this package |
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.2305README
Dynamic Crosshair — How to Fish
by PapaSalazar
A client-side crosshair that shows where your gun is actually pointing and traces the real spread cone the game will use for your next shot.
How to Fish ships no crosshair. The guns are held off to the side of the camera and their muzzles are driven by a physics recoil rig, so the barrel is almost never pointing at the middle of your screen. This mod stops you guessing: it reads the weapon's own numbers every frame, re-runs the game's own shot maths, and draws the result.
- Point of aim — a dot at the exact spot the muzzle is looking at, not the screen centre.
- Spread outline — the boundary of the cone your pellets can land in, traced from the game's live
_spreadvalue. - Bullet drop — weapons whose projectiles travel and fall are simulated with the game's own integrator, so the crosshair sits where the shot lands, not where the barrel points.
- Blocked-barrel warning — when you press the muzzle into a wall, crate or teammate, How to Fish silently resolves the shot at that obstruction instead of downrange. The crosshair turns red and snaps to the impact point.
No Harmony patches, no network traffic, no writes to game state. It reads and it draws.
Install
With a mod manager (recommended)
Search for DynamicCrosshair in Thunderstore Mod Manager or r2modman and install. BepInEx comes along as a dependency.
By hand
- Install BepInEx 5.4.23.5 (win_x64) into the folder containing
How to Fish.exe, then launch the game once so it creates its folders. - Drop
DynamicCrosshair.dllintoHow to Fish/BepInEx/plugins/. - Launch. The config file appears at
BepInEx/config/howtofish.dynamiccrosshair.cfg.
Press F8 in game to toggle the crosshair off and on.
Configuration
Edit BepInEx/config/howtofish.dynamiccrosshair.cfg (restart the game to apply).
Shape
Two independent settings: one for the spread cone, one for the point of aim. Set either to None
if you only want the other.
SpreadStyle |
|
|---|---|
None |
Do not draw the cone |
Ring |
Continuous outline (default) |
DashedRing |
Broken outline — reads better over busy scenery |
Ticks |
Four marks standing outward on the boundary |
Brackets |
Four short arcs, like brackets around the target |
CenterStyle |
|
|---|---|
None |
Do not mark the point of aim |
Dot |
Filled disc |
HollowDot |
Small open circle — readable on light and dark backgrounds |
Plus |
Four arms with a centre gap (default) — never covers what you are shooting |
Cross |
Four diagonal arms with a centre gap |
Diamond |
Small open diamond |
Size
Sizes are authored for 1080p and scaled to your screen height, so the crosshair looks the same at 1440p and 4K instead of shrinking to a few specks.
| Setting | Default | What it does |
|---|---|---|
ScaleWithResolution |
true |
Scale all sizes by screen height. Off = exact pixels |
ReferenceHeight |
1080 |
Height the sizes below are authored against |
Thickness |
2 |
Line thickness of the spread outline |
OutlineWidth |
1.5 |
Dark edge width per side. This is the main visibility control — raise it before anything else. 0 disables |
CenterSize |
3 |
Radius of Dot, HollowDot, Diamond |
CenterGap |
3 |
Empty space in the middle of Plus / Cross |
CenterArmLength |
8 |
Arm length for Plus / Cross |
TickLength |
9 |
Mark length for Ticks |
Segments |
40 |
Points used to trace the outline |
DashCount |
12 |
Dashes in DashedRing |
BracketArcDegrees |
34 |
How much of the boundary each Brackets arc covers |
MinRadiusPixels |
3 |
Smallest the outline may get. Weapons with no spread show only the centre marker, since a ring there would imply spread that does not exist |
MaxRadiusPixels |
900 |
Safety clamp |
Colours
All values are RRGGBBAA hex — the last two digits are opacity.
| Setting | Default | What it does |
|---|---|---|
Color |
5CFFC8FF |
Spread outline |
CenterColor |
FFFFFFFF |
Point-of-aim marker. Keeping this a different colour from the outline is the single easiest way to make the exact aim point pop |
BlockedColor |
FF4040FF |
Used when the barrel is obstructed |
OutlineColor |
000000C8 |
Dark edge drawn behind everything |
Behaviour
| Setting | Default | What it does |
|---|---|---|
HideWhileAiming |
false |
Hide once you are aiming down the weapon's own sights |
HideWithSniperScope |
true |
Hide behind the full-screen scope overlay, where it only adds clutter |
ShowBlockedIndicator |
true |
Recolour and relocate the crosshair when the muzzle is obstructed |
ConformToGeometry |
false |
Trace every outline point against the world so the cone wraps around corners and angled surfaces. Nicer looking; costs one cast per segment per frame |
MaxSimulationSteps |
250 |
Physics ticks simulated for projectiles that travel and drop |
MaxRange |
400 |
How far to follow a shot before drawing the crosshair at that distance |
Diagnostics
| Setting | Default | What it does |
|---|---|---|
ShowDebugText |
false |
On-screen readout of live spread, pellet count, delivery type, range and on-screen radius |
LogBindingDetails |
true |
Lists every game field the mod attached to at startup. Leave this on — it is the fastest way to see what a game update changed |
DumpWeaponTable |
false |
Once in game, log every weapon's id, spread, pellet count, speed and gravity, plus the id of every other item. Handy for checking weapons you are not holding, and for bug reports |
TestPattern |
false |
Draws a fixed ring at screen centre everywhere, including the main menu |
Can't see it? Try these
How to Fish is a bright, high-contrast game — pale sand, bright sky, white water. A thin crosshair disappears into it. In rough order of effectiveness:
- Raise
OutlineWidthto2–3. The dark edge behind the crosshair does more for legibility than any colour change. - Use a contrasting
CenterColor. MagentaFF00FFFFor yellowFFE800FFcut through sand and sea in a way white and cyan do not. - Switch
CenterStyletoPlusorCross. Four arms cover far more pixels than a dot while the centre gap keeps your target visible. - Raise
Thicknessto2.5–3andCenterArmLengthto10–12. - Check
ScaleWithResolutionistrue. If it is off on a 1440p or 4K screen, every size is being taken as literal pixels and will look tiny.
Ready-made combinations:
Maximum visibility
SpreadStyle = Ring
CenterStyle = Plus
Thickness = 2.8
OutlineWidth = 2.5
CenterArmLength = 11
CenterColor = FF00FFFF
Minimal — point of aim only
SpreadStyle = None
CenterStyle = HollowDot
CenterSize = 3.5
Shooter-familiar — four ticks that track the spread
SpreadStyle = Ticks
CenterStyle = Dot
TickLength = 11
Clean brackets
SpreadStyle = Brackets
CenterStyle = Diamond
BracketArcDegrees = 28
What "dynamic" actually means here
Worth being precise, because it affects how much you should trust the ring.
In the current game build, Weapon._spread is a constant per weapon — a cone half-angle in degrees, set on each weapon prefab. It is not a bloom value that grows while you spray. So the ring is not going to pulse when you fire.
And there are only five guns, of which exactly one has any spread at all:
| Weapon | Item ID | Spread | Pellets | Speed | Gravity |
|---|---|---|---|---|---|
| Pistol | 66 | 0° | 1 | 350 | 0 |
| Smg | 69 | 0° | 1 | 350 | 0 |
| Assault Rifle | 54 | 0° | 1 | 900 | 0 |
| Shotgun | 68 | 6° | 25 | 100 | 0 |
| Sniper Rifle | 70 | 0° | 1 | 1000 | 0 |
So be clear on what you are getting: the spread ring only ever appears on the shotgun. On the other four the crosshair is a point-of-aim marker, which is still the part that matters most — the barrel does not point at your screen centre, and that offset is large up close. Measured on the pistol: about 130 px off centre at 5 m, converging to nothing by 400 m.
No gun uses ProjectileGravity either, so the bullet-drop simulation is currently inert for player
weapons. It is kept because it costs nothing when gravity is zero and it means an arced weapon added
in a future update works on day one, with no mod change.
What genuinely changes frame to frame, and what this mod tracks:
- Where the cone points. The muzzle transform is driven by a
ConfigurableJointrecoil rig plus sway, sprint offsets and the aim-down-sights position. It moves constantly, and it does not point at your screen centre. - How big the cone looks. Aiming down sights changes the camera FOV, so the same angular spread covers a different number of pixels.
- Where the cone lands. For weapons with
ProjectileGravity, distance changes the drop, so the whole crosshair moves down as your target gets further away. - Which muzzle is used. Barrel attachments swap the fire point, so fitting a suppressor moves your point of aim.
- The scoped-weapon override. Past 90% zoom, a weapon with a sniper scope fires from the camera instead of the barrel. The crosshair follows that switch.
The value is read fresh every frame rather than cached, so if a future update turns _spread into a real dynamic bloom, this crosshair starts breathing with it on its own — no mod update needed.
The outline is sampled using the game's own expression, Quaternion.Euler(v * _spread) * forward with |v| == 1, rather than approximated with a circle. That matters because the game applies its Euler angles on world axes, which makes the cone slightly orientation-dependent. Sampling the real expression reproduces that instead of hiding it.
Why this should survive game updates
Most mods break on update because they hard-reference the game's assembly or patch a method whose signature moved. This one does neither.
- No compile-time reference to
Assembly-CSharp. The mod only links against BepInEx and stock Unity modules. A changed game assembly cannot produce aTypeLoadException, because there is nothing to load. - No Harmony patches. Nothing is hooked, so there is no signature to match, no patch to fail, and no conflict with other mods.
- Name-tolerant binding. Every field is looked up by a list of likely names; if none match, the mod searches the declaring type for a member of the right type whose name contains the relevant keyword.
_spreadbecoming_bulletSpreadstill binds, with a warning telling you it happened. - Independent feature degradation. Only six members are essential. Everything else — bullet drop, the blocked-barrel check, scope handling, water clamping — fails on its own, logs one warning, and leaves the rest working.
- It switches itself off rather than misbehaving. After 30 consecutive read failures the mod disables itself and says so once. It will never spam your log or tank your frame rate.
If a future update does break something, LogBindingDetails prints exactly which member could not be found, which is usually a one-line fix.
Troubleshooting
No crosshair at all. Set TestPattern = true and restart. A ring at screen centre means the overlay works and the problem is reading the weapon — check BepInEx/LogOutput.log. No ring means something else is covering the overlay; try raising sortingOrder by rebuilding, or check for a conflicting UI mod.
It only appears with a gun out. Correct. Fishing rods and melee weapons have no spread cone.
Nothing in the log. BepInEx is not loading. Confirm winhttp.dll and doorstop_config.ini sit next to How to Fish.exe, and that you used the win_x64 build.
Frame rate dip with a bow or harpoon. Those projectiles are simulated tick by tick. Lower MaxSimulationSteps, or MaxRange, or turn off ConformToGeometry.
Multiplayer
Entirely client-side and read-only: no RPCs, no synced state, and no data read about other players. Nothing to desync and nothing another client can detect.
That said, it is an aiming aid in a game that has friendly fire and a PvP-capable lobby. The game already sells a laser-sight attachment that does something similar at short range, so this is not far outside its own design — but it is worth checking with whoever is hosting before using it in a competitive lobby.
Building from source
Requires the .NET SDK (8 or newer). No NuGet packages; references come from your game install.
dotnet build -c Release
If your Steam library is not on C:, point the build at it:
dotnet build -c Release -p:GameDir="D:\SteamLibrary\steamapps\common\How to Fish\How to Fish"
build.ps1 builds, copies the DLL into your game's plugin folder and produces a Thunderstore-ready zip in dist/:
powershell -ExecutionPolicy Bypass -File build.ps1
validate-package.ps1 checks that zip against Thunderstore's manifest rules — required files, name
and version format, description length, dependency strings, icon dimensions — and queries the
community to confirm the name and version are not already taken:
powershell -ExecutionPolicy Bypass -File validate-package.ps1
The project targets netstandard2.1, because Unity 6's own assemblies do and anything lower fails to reference them.
Test save
tools/make-test-save.ps1 writes a save containing all five guns, one per hotbar slot, so you can
cycle 1–5 and check the crosshair against every weapon in the game:
powershell -ExecutionPolicy Bypass -File tools\make-test-save.ps1
It reads your SteamID from your newest existing save (saves are keyed by it), leaves your own saves
untouched, and creates a separate one called CrosshairTest. Weapons get default attachments,
because Sight, BarrelAttachment and AmmoType are indexes into per-weapon lists and an
out-of-range value would throw inside the game — buy attachments in game instead. Use -Name,
-Money and -SteamId to override.
Verified against
| How to Fish | 1.0.4 (Steam app 4001890, build 24860529) |
| Unity | 6000.4.4 (Mono backend) |
| BepInEx | 5.4.23.5 win_x64 |
Licence
MIT. See LICENSE.