Harrisonburg-HarrisonCustomLootTable icon

HarrisonCustomLootTable

Server-controlled monster loot with star scaling, inventory delivery, flexible reward distribution, and customizable reward pouches.

Last updated a day ago
Total downloads 21
Total rating 0 
Categories Mods Server-side Client-side AI Generated
Dependency string Harrisonburg-HarrisonCustomLootTable-0.0.3
Dependants 0 other packages depend on this package

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2350 icon
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.2350
ValheimModding-Jotunn-2.30.2 icon
ValheimModding-Jotunn

Jötunn (/ˈjɔːtʊn/, 'giant'), the Valheim Library was created with the goal of making the lives of mod developers easier. It enables you to create mods for Valheim using an abstracted API so you can focus on the actual content creation.

Preferred version: 2.30.2

README

Buy me a coffee

HarrisonCustomLootTable

HarrisonCustomLootTable lets Valheim server owners customize monster rewards and create reward pouches. Configured monster loot goes directly into players' inventories, and players can right-click pouches to receive randomized rewards.

Use it to reward boss kills, give stronger monsters better drops, or distribute rewards to nearby players. The server controls loot settings and rolls.

Features

  • Custom loot tables for monsters and bosses, with chance and quantity scaling per star.
  • Reward distribution to the last hitter, the highest damage contributor, or every nearby player.
  • A per-monster option to keep or remove vanilla ground drops.
  • Custom pouch names, descriptions, stack sizes, weights, and opening messages.
  • Inventory delivery with an optional ground fallback for excess rewards.

Version: 0.0.3. Plugin GUID: com.harrison.customloottable.

Install and set up

  1. Install Valheim-compatible BepInEx 5.x and Jötunn on the server/host and every client. This build was compiled against Jötunn 2.30.2.
  2. Stop the game/server and copy HarrisonCustomLootTable.dll into BepInEx/plugins/HarrisonCustomLootTable/ on every peer. Everyone must use the same mod version.
  3. Launch once to generate the configuration files, then stop the game/server. You can also copy the ready-made files from examples before the first launch. Existing files are preserved.
  4. Edit the server/host's .cfg, monster drops, pouch definitions, and pouch loot using the instructions below.
  5. Copy the same pouch definitions JSON to every client. Pouch definitions, including opening messages, are loaded locally and are not automatically synced. Server loot settings and both loot tables synchronize when clients connect. ShowLootNotification is a local client preference and does not synchronize.
  6. Restart the server/host and clients. Check BepInEx/LogOutput.log for successful initialization, pouch registration, and loot synchronization.

For a mod manager, use its active profile's BepInEx folder. For a dedicated server, use the server's BepInEx folder. The final layout is:

BepInEx/
  plugins/
    HarrisonCustomLootTable/
      HarrisonCustomLootTable.dll
  config/
    HarrisonCustomLootTable.cfg
    HarrisonCustomLootTable/
      HarrisonCustomLootTable_PouchDefinitions.json
      HarrisonCustomLootTable_MonsterDrops.json
      HarrisonCustomLootTable_PouchLoot.json

Restart after JSON changes. For predictable .cfg updates, stop the server/host, edit its file, and restart. Connected clients cannot override server settings, including clients listed as server admins. Synced loot JSON remains in memory and does not overwrite the client's local files.

Server settings

Edit BepInEx/config/HarrisonCustomLootTable.cfg:

[Star Scaling]
DropChanceMultiplierPerStar = 0.5
DropAmountMultiplierPerStar = 1.0

[Distribution]
DefaultDistributionMode = LastHit
MaxParticipantDistance = 60.0
DropOnGroundIfInventoryFull = true

[UI / Notification]
ShowLootNotification = true
Setting What it controls
DropChanceMultiplierPerStar Added chance multiplier per star; 0.5 gives 1x, 1.5x, and 2x base chance at 0, 1, and 2 stars
DropAmountMultiplierPerStar Added quantity multiplier per star; 1.0 gives 1x, 2x, and 3x base amounts
DefaultDistributionMode Recipient rule for monsters without a JSON override
MaxParticipantDistance Maximum distance in metres from the monster to eligible players
DropOnGroundIfInventoryFull When true, excess monster and pouch rewards drop at the recipient's feet; when false, excess rewards are not collected
ShowLootNotification Local client preference. When true, show top-left messages for items deposited into inventory. When false, hide deposit messages and deposited amounts in pouch summaries; pouch opening messages and overflow warnings remain

Each player can change ShowLootNotification in their own ConfigurationManager while connected, without admin permissions. It takes effect immediately and saves locally. The server cannot override it. If editing the .cfg directly, edit the client's active profile file and restart the client to load the change.

The three float settings use numeric input fields in ConfigurationManager. They accept finite, non-negative values; invalid values are reset to zero.

Distribution modes:

  • LastHit: the player who dealt the final effective damage, if alive and in range. A finishing hit from the environment or a non-player gives no last-hit reward.
  • MostDamage: the living player in range who dealt the most damage.
  • EveryPlayer: every living connected player in range, including players who did not attack. Each receives the same rolled reward amounts; loot is not split.

The distance boundary is included. If nobody qualifies, no configured loot is awarded. Monsters missing from the JSON keep their normal vanilla behavior.

Configure monster and boss drops

Edit HarrisonCustomLootTable_MonsterDrops.json inside the configuration directory. Use the monster's exact prefab name as its key. For example:

{
  "Troll": {
    "Drops": [
      {
        "ItemPrefab": "Coins",
        "Chance": 1.0,
        "MinAmount": 20,
        "MaxAmount": 40
      },
      {
        "ItemPrefab": "HarrisonRewardPouch",
        "Chance": 0.5,
        "MinAmount": 1,
        "MaxAmount": 2
      }
    ],
    "DistributionMode": "MostDamage",
    "KeepVanillaDropsOnGround": false
  }
}

Chance uses values from 0 to 1: 0.25 means 25%. Each entry rolls independently. Amounts must be positive integers, with the minimum no greater than the maximum. The maximum is included in the random range.

DistributionMode is optional and inherits the global setting when omitted. KeepVanillaDropsOnGround defaults to true when omitted:

  • true: keep vanilla ground drops in addition to configured inventory rewards.
  • false: remove vanilla ground drops, including those produced through ragdolls.

Only configured rewards enter inventories. This flag does not control items spawned independently by other mods. Complete Greydwarf, Troll, and Eikthyr tables are in the monster drops sample.

Star scaling

One base table handles every star level. Do not add separate star-prefab keys.

Stars = max(0, Level - 1)
FinalChance = min(1, BaseChance * (1 + Stars * DropChanceMultiplierPerStar))
FinalMinAmount = floor(BaseMinAmount * (1 + Stars * DropAmountMultiplierPerStar))
FinalMaxAmount = floor(BaseMaxAmount * (1 + Stars * DropAmountMultiplierPerStar))

Using the default settings, the Troll example above produces:

Reward 0 stars 1 star 2 stars
Coins 100%, 20–40 100%, 40–80 100%, 60–120
HarrisonRewardPouch 50%, 1–2 75%, 2–4 100%, 3–6

Amounts are awarded only when that entry's chance succeeds. Chances stop at 100%, and scaled amounts round down to whole items. Star scaling applies to monster and boss drops, including pouch items; it does not change rewards inside a pouch.

Create reward pouches

Edit HarrisonCustomLootTable_PouchDefinitions.json:

[
  {
    "PrefabName": "HarrisonRewardPouch",
    "DisplayName": "Harrison's Reward Pouch",
    "Description": "A sealed pouch containing a collection of rewards.",
    "OpenMessage": "You opened Harrison's Reward Pouch!",
    "BasePrefabToClone": "chest_hildir1",
    "MaxStackSize": 20,
    "Weight": 0.1
  }
]

Add another object to the array for each additional pouch, using a unique PrefabName. Names are case-sensitive and must match the loot table keys. Keep prefab names stable once players have saved those items.

BasePrefabToClone supplies the pouch's model and icon. The default is chest_hildir1 (Hildir's Brass Chest). You can choose another existing networked item available on every peer. The other fields set its inventory name, description, maximum stack size, and weight.

Existing definitions are preserved: change BasePrefabToClone to chest_hildir1 in your installed JSON, copy it to every peer, and restart to update existing setups.

OpenMessage is optional. Missing, null, empty, or whitespace-only text uses You opened {DisplayName}!. The message appears above the reward summary after a successful opening, including an opening with no rewards. Use \n inside JSON strings for a new line. Messages accept up to 4096 characters; long HUD summaries are shortened on screen and logged in full.

Copy identical definitions to the server and every client, then restart them. All fields except OpenMessage are required.

Set pouch rewards

Edit HarrisonCustomLootTable_PouchLoot.json. The key must exactly match a pouch's PrefabName from the definitions file:

{
  "HarrisonRewardPouch": [
    {
      "ItemPrefab": "Coins",
      "Chance": 1.0,
      "MinAmount": 10,
      "MaxAmount": 30
    },
    {
      "ItemPrefab": "Amber",
      "Chance": 0.25,
      "MinAmount": 1,
      "MaxAmount": 2
    }
  ]
}

The example always gives 10–30 Coins and independently has a 25% chance to give 1–2 Amber. The complete pouch loot sample also includes a chance for Ruby.

To open a pouch, move it into your own inventory and right-click it. A successful opening consumes one pouch. Rewards go into your inventory, with excess handled by DropOnGroundIfInventoryFull. The center message reports what was gained, dropped at your feet, or not collected. Disable ShowLootNotification to hide deposited quantities while keeping the opening message and overflow details.

A missing/invalid table or canceled opening keeps the pouch. A valid opening with no successful rolls still consumes it. Empty reward arrays are allowed. Opening from a container is refused; only one opening can be pending at a time.

Example files

JSON must use the documented fields and valid syntax, without comments or trailing commas. Use prefab names rather than translated item names.

Check your setup

In a local test world started with -console, run devcommands, then spawn HarrisonRewardPouch 1. Open it and confirm one pouch is consumed, Coins are awarded, and your custom opening message appears. Check monster drops, star scaling, recipient modes, and full-inventory behavior on a dedicated test server before using a customized setup with players.

Problem What to check
Mod fails to load BepInEx/Jötunn are installed, the DLL is in the active profile's plugins folder, and dependency versions match
Pouch does not register Its base item exists, its prefab name is unique, and every peer has identical definitions; inspect the log for registration errors
No configured monster loot Exact monster/item prefab names, entry chances, recipient mode, player distance, and the server's JSON
Pouch opening is refused The pouch-loot key matches its definition, every reward prefab exists, and the server loot tables are ready
Server refuses connections after editing JSON Fix the configuration error reported in BepInEx/LogOutput.log, then restart
A file edit has no effect Edit the active server/host or profile folder, restart after JSON changes, and redistribute edited pouch definitions

Invalid files are preserved and logged. Keep reward quantities practical: the mod limits grants to 10,000 items and 256 full stacks. Over-limit monster entries are skipped; pouch tables exceeding worst-case limits are refused before consumption.

The server controls loot decisions and rolls. Inventory operations use Valheim's native client ownership, so this mod does not provide inventory anti-cheat or guaranteed recovery across crashes. Live game and multiplayer testing remain necessary before release.