AimUrWay
Soft aim assist for mouse and keyboard, with a damage penalty that scales to how much help you took. Tracks fish and animals only, never players. Includes an exact sensitivity converter and FOV fixes.
By PapaSalazar
| Last updated | 4 hours ago |
| Total downloads | 128 |
| Total rating | 1 |
| Categories | Mods Tools |
| Dependency string | PapaSalazar-AimUrWay-0.1.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
Aim Ur Way — How to Fish
v0.1.0 — early. Loads and patches cleanly; the assist's feel has not been tuned against live play yet.
A soft aim assist for mouse-and-keyboard players, with a damage penalty that scales to how much help you actually took — plus a sensitivity converter from other shooters.
The goal is a genuine accessibility aid that a lobby can accept, not a hidden advantage.
Host or client?
Entirely client-side. No host cooperation, and nobody else needs to install anything.
- The assist only rotates your camera. Nothing about it is networked.
- The damage penalty is real, not cosmetic. Damage in this game is client-authoritative: your
client computes damage and tells the server to apply it (
PlayerVitals.LocalHit→Server.HitPlayer, andProjectileManagerstamps damage onto each projectile on the shooter's machine). So when this mod lowers your damage locally, it is lowered — there is no server-side value overriding it.
That cuts both ways, and it's worth saying plainly: because the game trusts clients on damage, this mod's honesty is a property of the mod, not something the server enforces. The penalty is real for anyone running this build.
Why this isn't an aimbot
The game already ships its own aim assist (PlayerAimAssist) — for controllers, while aiming down
sights. This mod keeps that design and lifts the controller restriction. Specifically:
- It hooks the game's own extension point.
PlayerCamera.ApplyAimAssist()already asksPlayerAimAssist.GetRotationDelta(..)for a rotation nudge each frame. That one method is the patch target, so the assist runs where the game intends and inherits its feel. - It never targets players. The vanilla scan walks
ItemManager.Itemsand takes each item'sCreature, so it only ever tracks fish and animals. This mod does the same, and there is no player-targeting option — deliberately. That single property is what makes "not cheating" defensible, and it's why fighting other players is unaffected. - It cannot snap. The pull is an exponential approach toward the target, hard-clamped by
MaxRotationSpeed(default 90°/s). There is no instant correction anywhere in the code. - You always win. The pull scales down by how fast you're turning; past
ManualOverrideDegPerSec(default 140°/s) it stops entirely. A flick always beats the assist. - Narrow acquisition. Default 12° half-angle, requires line of sight, capped at 60 m — the game's own numbers.
- It refuses to run un-penalised. If the damage-penalty patch fails to apply, the assist disables itself rather than becoming a straight advantage.
The damage penalty is proportional, not flat. The mod keeps a decaying tally of how many degrees of aiming it did versus how many you did. That ratio drives the reduction:
damage x= 1 - (MaxDamagePenalty * assistShare)
Aim manually and land the shot: no penalty. Let the assist track a target for you and shoot: the
full penalty. It's applied at Attachments.Damage, the single property every shot's damage flows
through, so hitscan and travelling projectiles are both covered. The shop's stat panel reads the
underlying array rather than the property, so displayed weapon stats stay honest.
Sensitivity converter
This part is exact rather than eyeballed. From PlayerCamera.MouseInput:
LookInput = new Vector2(-raw.y, raw.x) * _sensitivity * SensMulti * 0.025f;
_rot += LookInput;
_rot is in degrees and raw is the Input System mouse delta in counts, so:
degrees per mouse count =
sensitivity × 0.025(at hip fire, whereSensMulti == 1)
Which gives, using cm/360 as the common currency because it's independent of FOV and resolution:
$$\text{game sens} = \frac{360 \times 2.54}{\text{cm/360} \times \text{DPI} \times 0.025} = \frac{36576}{\text{cm/360} \times \text{DPI}}$$
Worked example: CS2 at 1.0 / 800 DPI is 51.95 cm/360 → this game wants 0.880. The game's default of 0.5 is about 91 cm/360 at 800 DPI, which is slow by comp standards.
Press F10 for the panel. Pick a game, enter your sensitivity and DPI, and it shows the value to
use plus the cm/360 both before and after. Apply writes it via PlayerCamera.SetSensitivity.
Note the game already scales sensitivity by zoom correctly — SensMulti = _curFov / _origFov — so
your ADS sensitivity stays proportional without any help. That is 360-distance matched zoom, the
usual competitive choice.
Field of view
Measured in game, not guessed:
| Slider range | 40–140 vertical = 66–157 horizontal at 16:9 |
| Default | 74 vertical = 106.5 horizontal at 16:9 |
Those are the game's own limits, read off its options slider at runtime. This mod does not widen them, and the panel's FOV box clamps whatever you type to that same range.
Two things worth knowing.
Unity's fieldOfView is vertical, but every shooter quotes horizontal, so the two are never
directly comparable. The panel shows both, using your actual resolution's aspect ratio. Neatly, the
default 74 vertical works out at 106.5° horizontal — within a quarter of a degree of CS2's 106.26°,
so the stock FOV is already CS-equivalent.
Base FOV changes your aimed sensitivity. Because SensMulti = curFov / baseFov, aiming
multiplies sensitivity by AdsFov / baseFov. Raise your base FOV and your scoped aim gets slower.
The panel shows the exact multiplier for whatever you're holding.
The FOV persistence bug
The options menu saves your FOV with PlayerPrefs.SetInt("FOV", …) but loads it with
PlayerPrefs.GetInt("Fov", 74). PlayerPrefs keys are case sensitive, so the two never meet and
your FOV reverts to 74 on every launch — quietly shifting your aimed sensitivity by up to 1.9× at
the extremes of the slider.
FixFovPersistence (on by default) mirrors the saved value into the key the game actually reads, and
forces it for the current session if the menu already loaded the wrong one. Verified in the registry:
both FOV_h193442778 and Fov_h193443802 now hold the same value.
Caveat: the slider appears to fire its change callback on enable, so the first repair may pin the slider's serialized default rather than a value you chose. Set your FOV once through the panel's Apply FOV button to pin it deliberately — that writes both keys.
Two ways to convert
The panel gives you a straight choice:
- Keep the same turning speed (default) — the mouse travels the same distance to spin all the way round as it did in your other game. Ignores FOV, so it's exact.
- Adjust for the FOV difference — if the two games show different amounts of the world, this makes aiming feel the same on screen instead of turning at the same rate. Needs that game's FOV.
Most people want the first one. The second is there because if you're coming from a 103° game to a 116° one, matching raw turn speed can feel too fast even though the numbers agree.
There's a FovAdjustStrength in the config for the second mode if you already know you want the
adjustment weighted toward the screen edge rather than the centre. If that sentence means nothing to
you, you don't need it.
Presets
Counter-Strike 2 / CS:GO · Valorant · Apex Legends · Overwatch 2 · Team Fortress 2 · Quake
Games whose sensitivity depends on their own FOV slider (Rainbow Six Siege) or use a non-linear percentage scale (Fortnite) are deliberately absent rather than approximated. Use the cm/360 field for those — read the figure out of any online calculator and it's exact for every game ever made.
Caveat
The conversion assumes one Input System delta unit equals one mouse count — true with Windows pointer speed at the default 6/11 and "enhance pointer precision" off. If you run pointer acceleration, no converter can give you a stable answer.
Config
BepInEx/config/howtofish.aimurway.cfg. Hotkeys: F9 assist on/off, F10 converter panel.
Assist
| Setting | Default | |
|---|---|---|
Strength |
0.55 |
Fraction of the pull to apply. 1 matches the game's controller assist |
Sharpness |
8 |
How eagerly it closes the gap. Higher is stickier |
MaxRotationSpeed |
90 |
Hard ceiling in °/s. This is what prevents snapping |
ManualOverrideDegPerSec |
140 |
Turn this fast and the assist steps aside entirely |
AcquireAngle |
12 |
Half-angle to pick up a target. Keep small |
BreakAngle |
35 |
Angle at which a locked target is dropped |
MaxDistance |
60 |
Metres. The game's own default |
AssistFromHip |
false |
Vanilla is ADS-only; leaving this off stays closer to intent |
AlsoAssistController |
false |
Off so it never stacks with the built-in controller assist |
Fairness
| Setting | Default | |
|---|---|---|
DamagePenalty |
true |
Trade damage for aim help |
MaxDamagePenalty |
0.3 |
Largest reduction, at full assist share. 0.3 = −30% |
PenaltyWindowSeconds |
1.5 |
How long assist usage keeps counting against you |
Set ShowDebugText = true under [Diagnostics] to watch the target lock, live assist share and
current damage multiplier — the fastest way to tune Strength and see the penalty working.
Status and what's left
Verified: the plugin loads, binds to the game, and both Harmony patches apply
(PlayerAimAssist.GetRotationDelta, Attachments.get_Damage) with no errors.
Not yet done:
- Feel is untuned. The defaults are reasoned, not playtested.
StrengthandSharpnessare the two to adjust first, withShowDebugTexton. - Melee is uncovered.
Meleehas its own damage path, so the penalty doesn't apply to it. Not a problem today because the assist only helps ranged aiming. - No lobby-side disclosure. There's no chat announcement or host-side gate. If you play with people who care, tell them.
Design notes
Unlike the crosshair mod, this one changes behaviour, so Harmony patches are unavoidable. They're
kept to two, both at stable extension points, and there's still no compile-time reference to
Assembly-CSharp — everything is resolved by name at runtime, so a game update degrades to a
logged warning and a disabled feature rather than a crash.