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.
FearNoSpear
Protects thrown spears from disappearing on long throws and adds a `!myspear` chat command to pin tracked spears on the map.
| Date uploaded | a month ago |
| Version | 1.0.0 |
| Download link | sighsorry-FearNoSpear-1.0.0.zip |
| Downloads | 131 |
| Dependency string | sighsorry-FearNoSpear-1.0.0 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2333README
FearNoSpear
Protects thrown spears from disappearing on long throws and adds a !myspear chat command to pin tracked spears on the map.
FearNoSpear is a Valheim BepInEx/Harmony mod that reduces the chance of permanently losing thrown spears during very long throws, high mountain throws, zone unloads, or network ownership disruptions.
Valheim recoverable thrown spears are not ordinary dropped items while they are flying. They exist as Projectile objects, and the original spear item is normally recreated only after the projectile hit path runs. If the projectile expires, unloads, loses simulation, or is destroyed before that hit path completes, the spear can disappear before it ever becomes an ItemDrop.
This mod adds a conservative safety net around that lifecycle.
What It Does
- Detects recoverable thrown spear projectiles.
- Raises their initial projectile TTL to a configurable minimum.
- Tracks the projectile while it is alive.
- Rescues the original spear shortly before projectile TTL expiry if no normal hit occurred.
- Rescues before unexpected
ZNetScene.Destroy(GameObject)cleanup when possible. - Uses Valheim's own
Projectile.SpawnOnHitpath first. - Falls back to
ItemDrop.DropItemfor the stored original item data if the internal hit-spawn path cannot run. - Uses owner-only rescue and a ZDO claim flag to reduce multiplayer duplicate-spawn risk.
- Uses a fixed 4 meter nearby duplicate check before and after rescue. If an equivalent spear item already exists at the rescue point, the mod skips spawning another one. If rescue still produces overlapping equivalent drops, it keeps the closest one and removes the extras.
- Adds a configurable chat-only locator command, default
!myspear, that asks the server for known tracked spear locations and pins up to the configured limit on the minimap. - Reports tracked spear positions to the server while the spear is flying, so dedicated servers can answer later locator requests from the thrower.
- Clears matching locator pins and session records when a tracked spear is picked up.
- Supports ServerSync so server operators can lock the gameplay settings for all clients.
Chat Command
Type the configured locator command in the normal in-game chat. The default is:
!myspear
The command is consumed locally, so it is not sent as a public chat message. It adds saved minimap pins for known tracked spear locations and opens the map to those points. A single result is named Spear!; multiple results are named Spear 1, Spear 2, and so on.
When the mod is installed on both the server and the client, the client reports tracked spear positions to the server while the spear is flying and when a rescued or loaded matching spear drop is observed. The configured command asks the server for recent known records first, then falls back to local current-session records if the server has no record.
When a tracked spear is picked up, the client removes locator pins it created for the matching locator identity and tells the server to remove matching session records. This keeps a recovered spear from continuing to appear in later !myspear results.
The locator identity is intentionally stable across normal durability changes. If several otherwise identical spears from the same crafter have the same custom data, they can be treated as the same locator identity for cleanup and location tracking.
The server-side locator registry is session-based. It survives a client reconnect as long as the dedicated server process is still running, but it is not written to disk and is cleared on server restart or world reload. Records do not expire by time, but each player keeps only a small recent set of logical spear records. The number of pins created by each command is controlled by MaxPinsPerCommand.
The locator is intentionally not a generic prefab scanner. If a spear was thrown before the mod tracked it, was picked up after being pinned, or is an unrelated identical spear on the ground, the command may not have a useful location.
Multiplayer Safety
The recovery path stays close to Valheim's native behavior: the mod first tries to let the projectile live long enough for the normal hit path, then tries Valheim's internal Projectile.SpawnOnHit, and only uses the ItemDrop.DropItem fallback if that internal path cannot safely run.
Rescue is guarded by the current projectile ZNetView owner when the network view is valid. If the network view has already become invalid, the optional last-known-owner fallback can still recover the spear for a short grace period. When a valid ZDO exists, the mod also writes a rescue claim flag so other clients that observe the same projectile skip their own rescue attempt. If the item spawn path fails before rescue completes, that claim is released so another observer can still try.
The server is used as a synchronized config authority through ServerSync and as a session-based spear locator registry for the chat locator command. It does not authorize the final item-rescue attempt; that path stays guarded by ZNetView ownership, ZDO claim flags, and nearby duplicate cleanup. Location reports and requests are attributed by resolving the routed peer to the connected Player object on the server, so the server does not trust a client-supplied player ID. Server-side spear attribution also avoids using crafter ID as a thrower fallback; if the thrower cannot be proven, the server skips that attribution instead of recording the spear under the wrong player.
Custom locator RPCs include a protocol header. Server and clients should run the same mod version; ServerSync also advertises and enforces the configured mod version.
Config Options
All user-facing options are in the [General] section. Server-synchronized options are marked in the generated BepInEx config description. Verbose is intentionally local-only.
If you used an earlier test build, delete the old generated config file once to let BepInEx regenerate the simplified config. BepInEx may leave removed legacy keys in existing config files, but this version only reads the options documented below.
Lock Configuration
Default: On
Locks synchronized gameplay settings to the server's config when the mod is installed on a server. Keep this enabled for multiplayer servers so every client uses the same spear rescue timing and ownership safety rules.
Enabled
Default: true
Master switch for the mod. When disabled, the mod does not track spear projectiles, extend TTL, or rescue spear items.
MinimumInitialTTLSeconds
Default: 45
Minimum lifetime, in seconds, for tracked thrown spear projectiles. If Valheim's original projectile TTL is lower than this value, the mod raises it once after Projectile.Setup.
Higher values give very long throws more time to hit terrain naturally before rescue logic is needed. Lower values keep projectile lifetime closer to vanilla behavior but may make extreme throws less protected.
TTLRescueWindowSeconds
Default: 1.0
How close to projectile TTL expiry the mod should rescue a still-airborne tracked spear. A value of 1.0 means the stored spear item is respawned during the final second of projectile lifetime if no normal hit occurred.
Increase this if projectiles are still being cleaned up before rescue. Decrease it if rescued spears feel like they stop flying too early. Very large values are not recommended because they can turn a still-flying spear back into an item too soon.
AllowLastKnownOwnerIfZNetViewInvalid
Default: true
Allows a rescue attempt when the projectile ZNetView has already become invalid, but only if this client was the most recent known owner. This helps recover spears lost during unload, ownership disruption, or network cleanup.
Disable this if multiplayer testing shows duplicate rescued spears. Leaving it enabled favors loss prevention; disabling it favors stricter duplicate prevention.
LastKnownOwnerGraceSeconds
Default: 2
Maximum age, in seconds, for the last-known owner state used by the invalid-ZNetView fallback.
Lower values reduce duplicate-spawn risk but may miss late cleanup cases. Higher values are more forgiving when cleanup happens after ownership information has already become invalid, but they are less conservative in multiplayer.
ChatCommand
Default: !myspear
Chat command used to pin the latest known tracked spear location on the minimap.
The comparison is case-insensitive and the command is consumed locally instead of being sent to public chat. Server operators can change this to another command, such as !spear or !lostspear, and lock it through ServerSync. Leave it empty to disable the chat command.
MaxPinsPerCommand
Default: 5
Maximum number of known spear locations to pin each time the chat locator command is used.
The accepted range is 1 to 20. The server keeps up to 20 recent records per player, so this setting controls how many of those records are returned and pinned. Use 1 for the old single-pin behavior.
Verbose
Default: false
Enables detailed local BepInEx logging for tracker attachment, lazy tracker arming, TTL extension, rescue attempts, skipped rescues, ZDO claim behavior, and fallback paths.
This option is not synchronized with the server. Keep it disabled during normal play and enable it only while testing or diagnosing spear loss.
Internal Fixed Safety Behavior
The following behaviors are intentionally not exposed as normal config options. They are fixed to the safer default so the mod has fewer confusing toggles and fewer ways to accidentally disable the safety net.
Spear Name Fallback
Fixed: enabled
The mod first checks recoverable projectile item data and spear skill metadata. If metadata is inconclusive, it also accepts names containing spear or $item_spear. This keeps custom or localized spear-like items more likely to be protected.
Track All Recoverable Projectiles
Fixed: disabled
The mod does not track every recoverable projectile. It limits tracking to spears so arrows, thrown utility projectiles, or other recoverable projectiles are not accidentally affected.
Initial TTL Extension
Fixed: enabled
Tracked thrown spears always get the configurable minimum TTL protection. The actual minimum is controlled by MinimumInitialTTLSeconds.
Rescue Before TTL Expiry
Fixed: enabled
Tracked spears are rescued shortly before TTL expiry if no normal hit occurred. The timing is controlled by TTLRescueWindowSeconds.
Rescue On Unexpected Destroy
Fixed: enabled
The mod hooks ZNetScene.Destroy(GameObject) and the tracker component's OnDestroy fallback. If a tracked spear is about to be destroyed before normal hit handling, the mod attempts rescue first.
ItemDrop Fallback
Fixed: enabled
The mod first tries Valheim's internal Projectile.SpawnOnHit method because that is closest to vanilla behavior. If that path is unavailable or cannot run safely in the rescue context, it falls back to ItemDrop.DropItem using the stored original item data.
Owner-Only Rescue
Fixed: enabled
Only the current projectile ZNetView owner may rescue while the ZNetView is valid. This is one of the main protections against duplicate item spawning in multiplayer.
ZDO Rescue Claim Flag
Fixed: enabled
When a valid ZDO is available, the mod writes a FearNoSpear.Rescued boolean claim flag around the rescue attempt. Other clients that see the flag skip rescue, reducing duplicate-spawn risk. If the item spawn path fails before rescue completes, the mod clears the flag again instead of leaving the spear permanently claimed.
Nearby Duplicate Cleanup
Fixed: enabled, 4 meter radius
Before rescue, the mod searches within 4 meters of the projectile for an equivalent spear item drop. If it finds one, rescue is treated as already satisfied and no new item is spawned. After rescue, it performs the same nearby check again and removes overlapping equivalent duplicates, keeping the closest drop to the rescue point.
The equivalence check compares the drop prefab, shared item name, quality, variant, world level, durability, crafter data, and custom data. This keeps the cleanup focused on duplicate rescues rather than unrelated spears nearby.
Suggested Test Flow
- Start with default config.
- Set
Verbose = trueonly while testing. - Throw spears from high mountains and across long distances.
- Watch BepInEx logs for
Tracked thrown spear,Lazy-armed thrown spear tracker, andRescued thrown spear before projectile loss. - In multiplayer, verify that only one item is rescued per thrown spear.
- If duplicates appear, set
AllowLastKnownOwnerIfZNetViewInvalid = falseand retest.
See Docs/TEST_PLAN.md and Docs/TEST_MATRIX_KO.md for a broader validation matrix.
CHANGELOG
Version |
Update Notes |
|---|---|
| 1.0.4 | - Simplified the spear locator around thrower-tagged world ZDO spear drops, fixed thrown spears being skipped when pickedUp is set, and removed stale projectile-location fallback records. |
| 1.0.3 | - Use thrower metadata and server-side ZDO scanning as the primary !myspear locator path, with tracked records kept as fallback. |
| 1.0.2 | - Fixed tombstone deathpin cleanup patch failing to load on Valheim builds where TombStone.Setup uses ownerUID as the parameter name. |
| 1.0.1 | - Deathpin can be removed if tombstone is recovered. |
| 1.0.0 | - Initial Release |