Spooky season is here. Happy Halloween from Lattice!
Lattice
Docs/LatGhostHunt

LatGhostHunt

Ghosts drift near players at night. A spirit lantern ticks faster the closer one is - catch them for rewards.

Overview

Module id
ghost-hunt
Version
1.0.0
Platforms
paper
Price
Paid
Authors
Atlantis Services

Install

  1. Install Lattice on a Paper or Folia server, if it is not there yet.
  2. Drop the LatGhostHunt jar into plugins/Lattice/modules/. It loads straight away.
  3. Put your license key in lattice.yml, then run /lat license refresh.
  4. Edit config/global/ghost-hunt/ and apply it with /lat reload ghost-hunt.

Commands

Command names and aliases are set in config.yml, so yours may differ. <required> [optional]

Command Description Permission
/ghosthunt
also /gh
Ghosts you have caught today ghosthunt.use
/ghosthunt lantern <player> [amount]
ghosthunt.admin

Permissions

Permission Lets a player use
ghosthunt.use
/ghosthunt
ghosthunt.admin
/ghosthunt lantern

Placeholders

Filled in Lattice's own messages, and in any plugin that reads PlaceholderAPI when it is installed.

Placeholder Notes
%ghosthunt_today%
%ghosthunt_left%
%ghosthunt_total%

config.yml

Written to config/global/ghost-hunt/config.yml on first start. Edit it, then /lat reload ghost-hunt.

# Ghost hunt: at night, ghosts drift near players. A spirit lantern ticks faster the closer one is.
# Right-click a ghost with the lantern to catch it. Give lanterns with /ghosthunt lantern.
# Ghosts are real entities, so everyone nearby sees them, not only the player they spawned for.

# Generated from GhostHuntSettings. Keys you delete return to their default;
# keys that are not in the schema are ignored and reported on load.

command:
  # Command for catches today, and for staff to give lanterns. Takes effect on restart.
  name: "ghosthunt"
  aliases:
    - "gh"
  permission: "ghosthunt.use"
  # Permission for /ghosthunt lantern.
  admin-permission: "ghosthunt.admin"
# Timezone for start, end and the daily reset of catches, e.g. Europe/London.
timezone: "UTC"
# First day, as MM-DD, repeating every year. Leave start and end empty to run all year.
# An end before the start runs over the new year.
start: "10-01"
# Last day, inclusive, as MM-DD.
end: "11-01"
# Worlds ghosts appear in, by name. Empty for every world.
worlds: []
# World time (0 to 24000) at which ghosts start to appear. 13000 is dusk.
night-start: 13000
# World time at which they stop spawning. Must be after nightStart. 23000 is just before dawn.
night-end: 23000
# Ghosts only spawn near players carrying a spirit lantern. False spawns them near anyone.
require-lantern: true
# Most ghosts alive in one world at once.
max-ghosts: 40
# Most ghosts near one player (within nearbyRadius) before more stop spawning for them.
max-ghosts-per-player: 2
# Chance, from 0 to 1, each second that an eligible player gets a new ghost.
spawn-chance-per-second: 0.08
# Ghosts spawn at least this many blocks from the player...
min-distance: 12
# ...and at most this many.
max-distance: 28
# Blocks around the spawn point a ghost drifts. Its hitbox moves with it.
drift-radius: 6.0
# How fast a ghost drifts, in blocks per second.
drift-speed: 0.8
# Seconds before an uncaught ghost fades away.
lifetime-seconds: 90
# Ghosts within this many blocks of a player count towards maxGhostsPerPlayer. At least maxDistance.
nearby-radius: 48
# A ghost with no player this close fades away at once. More than maxDistance.
despawn-distance: 64
# Seconds between the eerie sound each ghost makes.
ambient-seconds: 6
# How far the lantern can sense a ghost, in blocks.
sense-radius: 24
# Ticks between lantern ticks when a ghost is right beside you. Twenty ticks to a second.
tick-fast-ticks: 3
# Ticks between lantern ticks when a ghost is at the edge of senseRadius.
tick-slow-ticks: 30
# Ghosts each player can catch per day. At the limit ghosts stop appearing for them
# and the lantern says so once. Counted across the network.
max-catches-per-day: 15
# How a ghost looks. It is a display entity, so no resource pack is needed.
ghost:
  # Item the ghost is shown as.
  item: "GHAST_TEAR"
  # Item model, as namespace:key, so a resource pack can give ghosts a real model. Empty for the item's own.
  model: ""
  # Size of the ghost, 0.1 to 8. The click hitbox follows it.
  size: 1.4
# How the spirit lantern looks. It is never placed, whatever its model.
lantern:
  name: "<gradient:#7df9ff:#b14cff><bold>Spirit Lantern</bold></gradient>"
  lore:
    - "<gray>Hold it and it ticks faster"
    - "<gray>the closer a ghost drifts."
    - ""
    - "<aqua>Right-click a ghost to catch it."
  # Item model, as namespace:key. A resource pack can supply its own.
  model: "minecraft:soul_lantern"
sounds:
  # Played where a ghost appears. Empty for none, here and below.
  spawn: "particle.soul_escape"
  # Played at each ghost every ambientSeconds.
  ambient: "entity.vex.ambient"
  # The lantern's tick, to the holder only. Its pitch rises as a ghost gets closer.
  tick: "block.note_block.hat"
  # Played where a ghost is caught.
  caught: "entity.allay.item_given"
# Rewards for a catch, picked by weight.
rewards:
  - # Relative chance against the other rewards.
    weight: 50
    reward:
      # Console commands. {player} is the player's name.
      commands:
        - "minecraft:give {player} glowstone_dust 4"
      # Sent to the player as a success line in the server theme. Empty for none.
      message: "<body>The ghost left a pinch of glowstone."
      # Sound key, e.g. entity.player.levelup. Empty for none.
      sound: null
  - # Relative chance against the other rewards.
    weight: 30
    reward:
      # Console commands. {player} is the player's name.
      commands:
        - "minecraft:give {player} experience_bottle 3"
      # Sent to the player as a success line in the server theme. Empty for none.
      message: "<body>The ghost left some bottled spirit."
      # Sound key, e.g. entity.player.levelup. Empty for none.
      sound: null
  - # Relative chance against the other rewards.
    weight: 15
    reward:
      # Console commands. {player} is the player's name.
      commands:
        - "minecraft:give {player} ender_pearl 2"
      # Sent to the player as a success line in the server theme. Empty for none.
      message: "<body>The ghost left a pair of pearls."
      # Sound key, e.g. entity.player.levelup. Empty for none.
      sound: null
  - # Relative chance against the other rewards.
    weight: 5
    reward:
      # Console commands. {player} is the player's name.
      commands:
        - "minecraft:give {player} diamond 2"
      # Sent to the player as a success line in the server theme. Empty for none.
      message: "<accent>A rare ghost! It left a pair of diamonds."
      # Sound key, e.g. entity.player.levelup. Empty for none.
      sound: "ui.toast.challenge_complete"

Messages

Every line players see, in config/global/ghost-hunt/messages.yml. Uses MiniMessage formatting.

Show messages.yml (16 lines)
# Player-facing text for ghost-hunt.
# Placeholders in {braces} are filled in by the module.
# A key you delete falls back to its built-in default.

bad-amount: '''{amount}'' is not a number from 1 to 64.'
busy: Your catches are still loading. Try again in a moment.
capped: You have caught enough ghosts for today. They will be back tomorrow!
capped-lantern: <muted>You have caught enough ghosts for today. The lantern goes dark.
closed: Ghost hunting is closed right now.
lantern-given: <body>Gave <accent>{amount}</accent> spirit lantern(s) to <accent>{player}</accent>.
lost: The ghost slipped away before you could claim it.
players-only: Only a player can do that.
sense: <aqua>A spirit stirs <accent>{distance}</accent><aqua> blocks away
sense-quiet: <muted>The lantern is quiet.
status: '<body>Ghosts caught today: <accent>{caught}</accent><muted>/</muted><accent>{total}</accent>'
unknown-player: <emphasis>{player}</emphasis> is not online.