diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 66cdff69b3f..0a1340d885b 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -469,6 +469,24 @@
dat += "Already cast!
"
return dat
+/datum/spellbook_entry/summon/ghosts
+ name = "Summon Ghosts"
+ desc = "Spook the crew out by making them see dead people. Be warned, ghosts are capricious and occasionally vindicative, and some will use their incredibly minor abilities to frustrate you."
+ cost = 0
+
+/datum/spellbook_entry/summon/ghosts/IsAvailible()
+ if(!ticker.mode)
+ return FALSE
+ else
+ return TRUE
+
+/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
+ new /datum/event/wizard/ghost()
+ active = TRUE
+ to_chat(user, "You have cast summon ghosts!")
+ playsound(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1)
+ return TRUE
+
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
category = "Rituals"
diff --git a/code/modules/events/wizard/ghost.dm b/code/modules/events/wizard/ghost.dm
new file mode 100644
index 00000000000..11529e3080d
--- /dev/null
+++ b/code/modules/events/wizard/ghost.dm
@@ -0,0 +1,5 @@
+/datum/event/wizard/ghost //The spook is real
+
+/datum/event/wizard/ghost/start()
+ var/msg = "You suddenly feel extremely obvious..."
+ set_observer_default_invisibility(0, msg)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 923c81c53b1..46ef4f54190 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -3,6 +3,8 @@
var/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness
+GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
+
/mob/dead/observer
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
@@ -28,6 +30,8 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
var/data_hud_seen = FALSE //this should one of the defines in __DEFINES/hud.dm
/mob/dead/observer/New(var/mob/body=null, var/flags=1)
+ set_invisibility(GLOB.observer_default_invisibility)
+
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER_AI_EYE
see_in_dark = 100
@@ -729,6 +733,26 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/is_literate()
return TRUE
+
+/mob/dead/observer/proc/set_invisibility(value)
+ invisibility = value
+ if(!value)
+ set_light(1, 2)
+ else
+ set_light(0, 0)
+
+/mob/dead/observer/vv_edit_var(var_name, var_value)
+ . = ..()
+ if(var_name == "invisibility")
+ set_invisibility(invisibility) // updates light
+
+/proc/set_observer_default_invisibility(amount, message=null)
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ G.set_invisibility(amount)
+ if(message)
+ to_chat(G, message)
+ GLOB.observer_default_invisibility = amount
+
/mob/dead/observer/proc/open_spawners_menu()
set name = "Mob spawners menu"
set desc = "See all currently available ghost spawners"
diff --git a/paradise.dme b/paradise.dme
index 866048ed844..94689e147fa 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1450,6 +1450,7 @@
#include "code\modules\events\vent_clog.dm"
#include "code\modules\events\wallrot.dm"
#include "code\modules\events\wormholes.dm"
+#include "code\modules\events\wizard\ghost.dm"
#include "code\modules\examine\examine.dm"
#include "code\modules\examine\descriptions\atmospherics.dm"
#include "code\modules\examine\descriptions\engineering.dm"