diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm
index bf7e44ae0f0..76debd5d612 100644
--- a/code/modules/holiday/halloween.dm
+++ b/code/modules/holiday/halloween.dm
@@ -27,3 +27,307 @@
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
+///HALLOWEEN CONTENT
+
+//spooky foods
+/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull
+ name = "skull cookie"
+ desc = "Spooky! It's got delicious calcium flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "skeletoncookie"
+
+/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin
+ name = "coffin cookie"
+ desc = "Spooky! It's got delicious coffee flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "coffincookie"
+
+//spooky recipes
+
+/datum/recipe/sugarcookie/spookyskull
+ reagents = list("flour" = 5, "sugar" = 5, "milk" = 5)
+ items = list(
+ /obj/item/weapon/reagent_containers/food/snacks/egg,
+ )
+ result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull
+
+/datum/recipe/sugarcookie/spookycoffin
+ reagents = list("flour" = 5, "sugar" = 5, "coffee" = 5)
+ items = list(
+ /obj/item/weapon/reagent_containers/food/snacks/egg,
+ )
+ result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin
+
+//spooky items
+
+/obj/item/weapon/storage/spooky
+ name = "trick-o-treat bag"
+ desc = "A Pumpkin shaped bag that holds all sorts of goodies!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "treatbag"
+
+/obj/item/weapon/storage/spooky/New()
+ ..()
+ for(var/distrobuteinbag=0 to 6)
+ var/type = pick(/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull,
+ /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin,
+ /obj/item/weapon/reagent_containers/food/snacks/candy_corn,
+ /obj/item/weapon/reagent_containers/food/snacks/candy,
+ /obj/item/weapon/reagent_containers/food/snacks/chocolatebar)
+ new type(src)
+
+////////////////////////////
+//Spookoween trapped closets
+////////////////////////////
+#define SPOOKY_SKELETON 1
+#define ANGRY_FAITHLESS 2
+#define SCARY_BATS 3
+#define INSANE_CLOWN 4
+#define HOWLING_GHOST 5
+
+//Spookoween variables
+/obj/structure/closet
+ var/trapped = 0
+ var/mob/trapped_mob
+
+/obj/structure/closet/initialize()
+ ..()
+ if(prob(30))
+ set_spooky_trap()
+
+/obj/structure/closet/dump_contents()
+ ..()
+ trigger_spooky_trap()
+
+/obj/structure/closet/proc/set_spooky_trap()
+ if(prob(0.1))
+ trapped = INSANE_CLOWN
+ return
+ if(prob(1))
+ trapped = ANGRY_FAITHLESS
+ return
+ if(prob(15))
+ trapped = SCARY_BATS
+ return
+ if(prob(20))
+ trapped = HOWLING_GHOST
+ return
+ else
+ var/mob/living/carbon/human/H = new (loc)
+ H.makeSkeleton()
+ H.health = 1e5
+ insert(H)
+ trapped_mob = H
+ trapped = SPOOKY_SKELETON
+ return
+
+/obj/structure/closet/proc/trigger_spooky_trap()
+ if(!trapped)
+ return
+
+ if(trapped == SPOOKY_SKELETON)
+ src.visible_message("BOO!");
+ playsound(src.loc, pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg','sound/spookoween/girlscream.ogg'), 300, 1)
+ trapped = 0
+ spawn(60)
+ if(trapped_mob.loc != loc)
+ var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
+ smoke.set_up(1,0, trapped_mob.loc, 0)
+ smoke.start()
+ trapped_mob.loc = loc
+ src.close()
+ trapped = SPOOKY_SKELETON
+ return
+
+ if(trapped == ANGRY_FAITHLESS)
+ src.visible_message("The closet bursts open!");
+ src.visible_message("THIS BEING RADIATES PURE EVIL! YOU BETTER RUN !!!");
+ playsound(src.loc, 'sound/hallucinations/wail.ogg', 300, 1)
+ var/mob/living/simple_animal/hostile/faithless/F = new (loc)
+ F.health =1e5
+ F.stance = HOSTILE_STANCE_ATTACK
+ F.GiveTarget(usr)
+ trapped = 0
+ qdel(src)
+ spawn(120)
+ var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
+ smoke.set_up(1,0, F.loc, 0)
+ smoke.start()
+ qdel(F)
+ return
+
+ if(trapped == SCARY_BATS)
+ src.visible_message("Protect your hairs !!!");
+ playsound(src.loc, 'sound/spookoween/bats.ogg', 300, 1)
+ var/number = rand(1,4)
+ for(var/i=0,i < number,i++)
+ new /mob/living/simple_animal/hostile/retaliate/bat (loc)
+ trapped = 0
+ return
+
+
+ if(trapped == INSANE_CLOWN)
+ src.visible_message("...");
+ playsound(src.loc, 'sound/spookoween/scary_clown_appear.ogg', 300, 1)
+ var/mob/living/simple_animal/hostile/retaliate/clown/insane/IC = new (loc)
+ IC.GiveTarget(usr)
+ trapped = 0
+ return
+
+ if(trapped == HOWLING_GHOST)
+ src.visible_message("Woo Woo");
+ playsound(src.loc, 'sound/spookoween/ghosty_wind.ogg', 300, 1)
+ new /mob/living/simple_animal/shade/howling_ghost (loc)
+ trapped = 0
+ return
+
+//don't spawn in crates
+/obj/structure/closet/crate/trigger_spooky_trap()
+ return 0
+
+/obj/structure/closet/crate/set_spooky_trap()
+ return 0
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////
+//Spookoween Ghost
+///////////////////////////
+
+/mob/living/simple_animal/shade/howling_ghost
+ name ="Ghost"
+ real_name = "Ghost"
+ icon = 'icons/mob/mob.dmi'
+ maxHealth = 1e6
+ health = 1e6
+ speak_emote = list("howls")
+ emote_hear = list("wails","screeches")
+ density = 0
+ anchored = 1
+ incorporeal_move = 1
+ layer = 4
+ var/timer = 0
+
+/mob/living/simple_animal/shade/howling_ghost/New()
+ ..()
+ icon_state = pick("ghost","ghostian","ghostian2","ghostking","ghost1","ghost2")
+ icon_living = icon_state
+ status_flags |= GODMODE
+ timer = rand(1,15)
+
+/mob/living/simple_animal/shade/howling_ghost/Life()
+ ..()
+ timer--
+ if(timer == 0)
+ roam()
+ spooky_ghosty()
+ timer = rand(1,15)
+
+/mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction)
+ loc = get_step(src, direction)
+ dir = direction
+
+/mob/living/simple_animal/shade/howling_ghost/proc/roam()
+ if(prob(80))
+ var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST)
+ EtherealMove(direction)
+
+/mob/living/simple_animal/shade/howling_ghost/proc/spooky_ghosty()
+ if(prob(20))//haunt
+ playsound(src.loc, pick('sound/spookoween/ghosty_wind.ogg','sound/spookoween/ghost_whisper.ogg','sound/spookoween/chain_rattling.ogg'), 300, 1)
+ if(prob(10))//flickers
+ var/obj/machinery/light/L = locate(/obj/machinery/light) in view(5, src)
+ if(L)
+ L.flicker()
+ if(prob(5))//poltergeist
+ var/obj/item/I = locate(/obj/item) in view(3, src)
+ if(I)
+ var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST)
+ step(I,direction)
+ return
+
+/mob/living/simple_animal/shade/howling_ghost/adjustBruteLoss()
+ return
+
+/mob/living/simple_animal/shade/howling_ghost/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ return 1
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////
+//Spookoween Insane Clown
+/////////////////////////
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane
+ name = "Insane Clown"
+ desc = "May the HonkMother have mercy..."
+ icon_state = "scary_clown"
+ icon_living = "scary_clown"
+ icon_dead = "scary_clown"
+ icon_gib = "scary_clown"
+ speak = list("...", ". . .")
+ maxHealth = 1e6
+ health = 1e6
+ emote_see = list("silently stares")
+ heat_damage_per_tick = 0
+ cold_damage_per_tick = 0
+ unsuitable_atmos_damage = 0
+
+ var/timer
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/New()
+ ..()
+ //timer = rand(10,180)
+ timer = rand(5,15)
+ status_flags = (status_flags | GODMODE)
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/Retaliate()
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/ex_act()
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/Life()
+ timer--
+ if(target)
+ stalk()
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/proc/stalk()
+ var/mob/living/M = target
+ if(M.stat == DEAD)
+ playsound(M.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
+ qdel(src)
+ if(timer == 0)
+ //timer = rand(10,180)
+ timer = rand(5,15)
+ playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1)
+ spawn(12)
+ loc = M.loc
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget()
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/AttackTarget()
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/adjustBruteLoss()
+ if(prob(5))
+ playsound(src.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
+ return
+
+/mob/living/simple_animal/hostile/retaliate/clown/insane/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(istype(O,/obj/item/weapon/nullrod))
+ if(prob(5))
+ visible_message("[src] finally found the peace it deserves. HONK for the HonkMother !");
+ playsound(src.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
+ qdel(src)
+ return
+ else
+ visible_message("It seems to be resisting the effect!!!");
+ return
+ ..()
+
+//////////////////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 38baa0e2e0b..0547d648086 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/sound/spookoween/bats.ogg b/sound/spookoween/bats.ogg
new file mode 100644
index 00000000000..fb428debcb3
Binary files /dev/null and b/sound/spookoween/bats.ogg differ
diff --git a/sound/spookoween/chain_rattling.ogg b/sound/spookoween/chain_rattling.ogg
new file mode 100644
index 00000000000..9ff9913b2b2
Binary files /dev/null and b/sound/spookoween/chain_rattling.ogg differ
diff --git a/sound/spookoween/ghost_whisper.ogg b/sound/spookoween/ghost_whisper.ogg
new file mode 100644
index 00000000000..660b04c786d
Binary files /dev/null and b/sound/spookoween/ghost_whisper.ogg differ
diff --git a/sound/spookoween/ghosty_wind.ogg b/sound/spookoween/ghosty_wind.ogg
new file mode 100644
index 00000000000..b1c8c2f3a8c
Binary files /dev/null and b/sound/spookoween/ghosty_wind.ogg differ
diff --git a/sound/spookoween/girlscream.ogg b/sound/spookoween/girlscream.ogg
new file mode 100644
index 00000000000..8ded518f47f
Binary files /dev/null and b/sound/spookoween/girlscream.ogg differ
diff --git a/sound/spookoween/insane_low_laugh.ogg b/sound/spookoween/insane_low_laugh.ogg
new file mode 100644
index 00000000000..6f1ba277783
Binary files /dev/null and b/sound/spookoween/insane_low_laugh.ogg differ
diff --git a/sound/spookoween/scary_clown_appear.ogg b/sound/spookoween/scary_clown_appear.ogg
new file mode 100644
index 00000000000..05ab18f70b0
Binary files /dev/null and b/sound/spookoween/scary_clown_appear.ogg differ
diff --git a/sound/spookoween/scary_horn.ogg b/sound/spookoween/scary_horn.ogg
new file mode 100644
index 00000000000..a0b05821bb2
Binary files /dev/null and b/sound/spookoween/scary_horn.ogg differ
diff --git a/sound/spookoween/scary_horn2.ogg b/sound/spookoween/scary_horn2.ogg
new file mode 100644
index 00000000000..fb2805bd2cd
Binary files /dev/null and b/sound/spookoween/scary_horn2.ogg differ
diff --git a/sound/spookoween/scary_horn3.ogg b/sound/spookoween/scary_horn3.ogg
new file mode 100644
index 00000000000..0aaefe1583a
Binary files /dev/null and b/sound/spookoween/scary_horn3.ogg differ