Skip to main content
Duck Shot wiki

Wiki

Duck Shot Wiki

Public setup, weapon authoring, combat systems, particles, admin help, and troubleshooting for Duck Shot.

Getting Started

Start here for installation, first boot, and your first working Duck Shot weapon.

Example Library and Pack Planning

Separate the public starter pack, the deeper example library, and your own server-only content so the docs stay honest and useful.

Server Operations

Handle permissions, runtime tools, integrations, and real troubleshooting on live servers.

Weapon Authoring

Attachment Recipes, Conversions, and Upgrade Paths

Use attachment recipes to turn one weapon into another while preserving ammo, lore, and player-side continuity.

attachments.yml is the cleanest way to let a player upgrade a weapon without losing the feeling that they are still holding the same item family.

That is what makes attachments useful in Duck Shot:

  • the base weapon can stay recognizable
  • the result weapon can become a real new config
  • the transition can preserve ammo, lore, and identity

The core idea

An attachment recipe has three parts:

  • the base item
  • the attachment ingredient
  • the result weapon

That means an attachment is not just "apply a stat buff." It is a real item conversion pipeline.

The basic shape

YAML
attachments:
  enabled: true
  block_vanilla_crafting_for_duckshot_items: true
  messages:
    inventory_full: '<red>No inventory space for attachment result.</red>'
  recipes:
    - id: m4a1_acog
      enabled: true
      base:
        weapon_id: M4A1
      attachment:
        weapon_id: ACOG
      result:
        weapon_id: M4A1_ACOG
        transfer_magazine_ammo: true
        preserve_base_display_name: true
        preserve_base_lore: true
        attachment_lore_line: '<color:#66624e>Attachment:</color> <#5C78D6>ACOG Scope'
      consume:
        base: true
        attachment: true
      feedback:
        message: '<green>Installed ACOG</green>'
        sound:
          key: minecraft:item.armor.equip_chain
          volume: 1.0
          pitch: 1.08

What a recipe can match

The current file comments and implementation show that base and attachment matchers can use any combination of:

  • weapon_id
  • material
  • custom_model_data
  • name_contains

That gives you two clean patterns:

  • strict official upgrade items by weapon_id
  • looser content-pack matching by material or model data

The result flags that matter most

transfer_magazine_ammo

This carries the current magazine ammo from the base item into the result item and clamps it to the new mag size if needed.

Why it matters:

  • the player does not feel punished for upgrading mid-session
  • conversion feels premium instead of wasteful

preserve_base_display_name

Keeps the naming continuity from the original weapon.

Use this when the result should still feel like the player's existing item, just upgraded.

preserve_base_lore

Keeps lore continuity.

Use this when the original lore still makes sense after the upgrade.

attachment_lore_line

Adds a clear visible line describing the installed module.

This is one of the best public touches because it makes the conversion readable without flooding the player with stat text.

Why attachments feel different from ammo

Ammo changes the round.

Attachments change the weapon branch.

That sounds simple, but it is the most important mental model for this file.

An attachment recipe is the right tool when the player should feel like:

  • the rifle now has an optic package
  • the sidearm now has a flashlight module
  • the sniper now has a night-vision or thermal branch
  • the shotgun now has a special ammo conversion as a new item branch

The weapon still belongs to the same family, but it is now a distinct branch of that family.

Matchers are stricter or looser on purpose

The current matcher system lets you choose how official or flexible the recipe should be.

The source comments already document that base and attachment can use combinations of:

  • weapon_id
  • material
  • custom_model_data
  • name_contains

Use that intentionally:

  • weapon_id for official, selected ecosystem items
  • material + custom_model_data for pack-level items
  • name_contains as a soft fallback, not as your only safety rail

Keep the recipe id and result branch aligned

Name the recipe after the branch it actually produces.

Good public naming looks like this:

  • flashlight recipe -> flashlight result
  • thermal recipe -> thermal result
  • variable-scope recipe -> variable-scope result

If the recipe says thermal, the result should normally be a *_THERMAL weapon. If the recipe says variable_scope, the result should normally be a *_VARIABLE_SCOPE weapon.

That sounds small, but it keeps attachment packs readable once you have a lot of branches.

Copyable optic branch example

This is a strong pattern when one rifle should split into multiple clean optic results.

YAML
recipes:
  - id: scar_night_vision
    enabled: true
    base:
      weapon_id: SCAR
    attachment:
      weapon_id: NIGHT_VISION_SCOPE_ATTACHMENT
    result:
      weapon_id: SCAR_NIGHT_VISION
      transfer_magazine_ammo: true
      preserve_base_display_name: true
      preserve_base_lore: true
      attachment_lore_line: '<color:#66624e>Attachment:</color> <#8DFF7A>Night Vision Scope'
    consume:
      base: true
      attachment: true
    feedback:
      message: '<#8DFF7A>Installed Night Vision Scope</#8DFF7A>'
      sound:
        key: minecraft:item.armor.equip_chain
        volume: 1.0
        pitch: 1.06
 
  - id: scar_thermal
    enabled: true
    base:
      weapon_id: SCAR
    attachment:
      weapon_id: THERMAL_SCOPE_ATTACHMENT
    result:
      weapon_id: SCAR_THERMAL
      transfer_magazine_ammo: true
      preserve_base_display_name: true
      preserve_base_lore: true
      attachment_lore_line: '<color:#66624e>Attachment:</color> <#FF8A4A>Thermal Scope'
    consume:
      base: true
      attachment: true
    feedback:
      message: '<#FF8A4A>Installed Thermal Scope</#FF8A4A>'
      sound:
        key: minecraft:item.armor.equip_chain
        volume: 1.0
        pitch: 0.98

Why this is better than stuffing everything into one file:

  • both results are clearly named
  • both results can own their own optic behavior and event hooks
  • the player sees the upgrade path immediately

Copyable content-pack matcher example

This is the looser pattern for a pack that includes its own attachment item.

YAML
recipes:
  - id: fnfal_pack_variable_scope
    enabled: true
    base:
      weapon_id: FNFAL
    attachment:
      material: GOLD_NUGGET
      custom_model_data: 4207
      name_contains: Variable Scope
    result:
      weapon_id: FNFAL_VARIABLE_SCOPE
      transfer_magazine_ammo: true
      preserve_base_display_name: true
      preserve_base_lore: true
      attachment_lore_line: '<color:#66624e>Attachment:</color> <#7FDBFF>Variable Scope'
    consume:
      base: true
      attachment: true
    feedback:
      message: '<#7FDBFF>Installed Variable Scope</#7FDBFF>'
      sound:
        key: minecraft:item.armor.equip_chain
        volume: 1.0
        pitch: 1.0

This pattern is helpful when the attachment item comes from a larger content pack or shared asset system.

What the result weapon is allowed to change

Because the result points at a full weapon id, an attachment branch can change much more than a tiny buff:

  • scopes and zoom stages
  • thermal or night-vision behavior
  • sound staging
  • action bar behavior
  • particles and event wiring
  • held effects
  • conditions
  • recoil and handling

That is why attachments are the right answer for deep upgrades.

What attachment recipes are best at

Use attachments when you want:

  • a weapon with an ACOG or variable scope
  • a flashlight version of a sidearm
  • a thermal or night-vision optic branch
  • a silenced version of a weapon
  • a special upgrade kit that truly produces a different final weapon

Those are all strong examples from the default attachment set.

Copyable recipe patterns

Official attachment item by weapon id

YAML
recipes:
  - id: g17_flashlight
    enabled: true
    base:
      weapon_id: G17
    attachment:
      weapon_id: FLASHLIGHT_ATTACHMENT
    result:
      weapon_id: G17_FLASHLIGHT
      transfer_magazine_ammo: true
      preserve_base_display_name: true
      preserve_base_lore: true
      attachment_lore_line: '<color:#66624e>Attachment:</color> <#FFD84A>Flashlight Module'
    consume:
      base: true
      attachment: true
    feedback:
      message: '<yellow>Installed Flashlight Module</yellow>'
      sound:
        key: minecraft:item.armor.equip_chain
        volume: 1.0
        pitch: 1.02

This is the cleanest official pattern because both items are known Duck Shot items.

Mixed matcher example for a looser content pack

YAML
recipes:
  - id: barrett_pack_thermal
    enabled: true
    base:
      weapon_id: BARRETT
    attachment:
      material: GOLD_NUGGET
      custom_model_data: 4203
      name_contains: Thermal
    result:
      weapon_id: BARRETT_THERMAL
      transfer_magazine_ammo: true
      preserve_base_display_name: true
      preserve_base_lore: true
      attachment_lore_line: '<color:#66624e>Attachment:</color> <#FF8A4A>Thermal Module'
    consume:
      base: true
      attachment: true
    feedback:
      message: '<#FF8A4A>Installed Thermal Module</#FF8A4A>'
      sound:
        key: minecraft:item.armor.equip_chain
        volume: 1.0
        pitch: 0.98

Use this pattern when the attachment item is coming from a broader pack or shared item library.

Attachment authoring strategy

Use attachments for visible or permanent upgrades

If the player should visibly understand that the gun is now a new branch of itself, attachment recipes are usually the right answer.

Use ammo for behavior-only changes

If the player's thought should be "same gun, different round," do not turn that into an attachment unless you intentionally want the item to become a separate conversion branch.

Use a new weapon file behind the result

The upgrade result should still point at a real weapon config. That is what gives you freedom to change:

  • scopes
  • visuals
  • sounds
  • hold effects
  • recoil
  • optic behavior

without having to make the attachment system itself carry every stat knob.

Good upgrade path examples

Optic tree

  • base weapon
  • red dot branch
  • ACOG branch
  • variable scope branch
  • thermal branch

Utility tree

  • base sidearm
  • flashlight branch
  • laser or sight branch
  • stealth branch

Conversion tree for special ammunition branches

Use this when the server wants the player to visibly install a special branch rather than silently load a new round:

  • base shotgun
  • Dragon's Breath branch
  • slug branch
  • breaching branch

High-tier conversion

  • base weapon
  • rare kit or scrap upgrade
  • visibly different result weapon

Common mistakes

Treating attachments like raw stat buffs

If the result really is a new weapon personality, let it become a real result weapon id.

Forgetting ammo continuity

If the player loses their magazine state every time they install an attachment, the system feels clunky.

Hiding a full branch inside one overgrown weapon

If the upgraded weapon needs different sounds, optics, particles, or visual states, make it a real result weapon id. Do not keep all of that trapped inside one giant base file if the player is meant to understand it as an installed upgrade.

Hiding the upgrade from the player

Always give the player readable feedback:

  • message
  • sound
  • lore line

Suggested order

  1. build the base weapon first
  2. create the result weapon config
  3. wire the attachment recipe
  4. enable ammo transfer if the upgrade should feel smooth
  5. add a visible lore line so the item is readable in inventory