Download (559 KB)

How do I install this?

Adds purely (audio-)visual ghosts of players you have killed that will haunt you at midnight. Supports arbitrary player models and textures with a few limitations. Easter eggs included!

All code written by Lars Müller and licensed under the MIT license.

Media (sound files) use different licenses, of which the most restrictive is CC BY 3.0:


There are three mechanisms to display things in Minetest:

  • Entities, significant overhead per entity, disallowed per the inspirational challenge
  • Nodes, fast but fairly limited (only one node per position)
  • HUD
  • Particles

Projecting everything onto the HUD would mean more work for the server and would look pretty bad with lag; besides, this isn't needed here, so particles are used.

Overally, Minetest imposes the following limitations:

  • Each particle gets it's own packet. Some packets might be delayed, resulting in a partially "separated" ghost.
  • Particle performance is rather poor, as each particle also gets it's own drawcall. This might affect client performance.
  • Texture pack provided skins must ideally have the same dimensions as the mod textures (or at the very least, a multiple of it) because the "sheet" modifier, which requires image dimensions, is used.
  • As multithreading isn't possible currently, ghosts have to be spawned rather fast as to not block the server step.
  • This fills up your memory.

Other limitations are specific to the implementation:

  • Only the B3D file format for models (ghosts using a different model file format won't appear) and PNG for images (otherwise, it resizes the texture to fallback dimensions, leading to even more client lag) are supported
  • If image dimensions can't be determined easily (non-PNG image or complex texture modifier), it will fall back to resizing the ghost texture to the specified fallback resolution, further hurting client performance due to cached parts not being taken advantage of.

Server-side texture packs

Server-side texture packs aren't supported, as there's no proper API for getting their paths yet. You can however use a "texture pack mod" to override textures (and other media) - all you have to do is add all mods as (optional) dependencies of that mod, ensuring it loads last. You may want to have your mod rewrite it's mod.conf to achieve that:

local current_mod_name = minetest.get_current_modname()
local mod_conf = Settings(minetest.get_modpath(current_mod_name))
local mod_names = minetest.get_modnames()
for index, mod_name in pairs(mod_names) do
    if mod_name == current_mod_name then
        -- Remove the mod itself so we don't get a circular dependency
        table.remove(mod_names, index)
local depends = table.concat(modnames, ", ")
if mod_conf:get"optional_depends" ~= depends then
    mod_conf:set("optional_depends", depends)
    minetest.request_shutdown"Server-side resource pack mod: Updated dependencies, please restart"



Decrease in chance of ghost spawning per night

  • Type: number
  • Default: 0.5



Fallback resolution width

  • Type: number
  • Default: 64


Fallback resolution height

  • Type: number
  • Default: 64


Whether to always resize textures to the given fallback dimensions. Guarantees support for arbitrary resolution texture packs. If this is not set, texture packs with a resolution lower than the server texture resolution won't work at all; texture packs with a multiple of said resolution will work well, however. A resolution of 64x64 or lower is usually acceptable performance-wise.

  • Type: boolean
  • Default: false


How many nights it takes for a ghost to forget their victim

  • Type: number
  • Default: 10


Particles per one metre (= node size)

  • Type: number
  • Default: 10


Chance of a ghost spawning the first night

  • Type: number
  • Default: 1



Spawns a ghost. Returns success: nil if spawning the ghost failed, true if it succeeded. params is a table with the following mandatory fields:

  • expiration_time: In seconds. Time it takes for the ghost to disappear.
  • pos: Minetest vector: Ghost spawn position
  • velocity: Minetest vector.
  • implode: Number, how much the ghost particles go towards their center during expiration time. Value of 1 will collapse the ghost to a point, -10 will explode it to 10x it's size.
  • model: String. B3D model filename. Example: "character.b3d".
  • textures: List (table) of model textures (strings). Example: {"character.png"}.

Optional fields:

  • playername: String. Ghost will be visible (and audible) to all players if not given.
  • sound: No ghost sound is played if sound is falsey.
  • disperse: Number. How fast the ghost should disperse. Default is 0.

victim_player:set_hp(hp, reason)

If reason.object is set to a player (the "killer_player") and victim_player dies, killer_player will be haunted by victim_player. If you use victim_player:punch, this is already the case.



Do you recommend this mod?

  • No reviews, yet.