diff --git a/code/game/objects/items/weapons/grenades/confetti.dm b/code/game/objects/items/weapons/grenades/confetti.dm
new file mode 100644
index 00000000000..a2e5559d911
--- /dev/null
+++ b/code/game/objects/items/weapons/grenades/confetti.dm
@@ -0,0 +1,51 @@
+/obj/item/weapon/grenade/confetti
+ desc = "It is set to detonate in 2 seconds. These party grenades will make everyone jump with joy (or fright)!"
+ name = "grenatti"
+ icon = 'icons/obj/grenade.dmi'
+ icon_state = "grenade"
+ det_time = 20
+ item_state = "grenade"
+ slot_flags = SLOT_BELT
+ var/datum/effect/effect/system/confetti_spread
+ var/confetti_strength = 8
+
+/obj/item/weapon/grenade/confetti/New()
+ ..()
+ src.confetti_spread = new /datum/effect/effect/system/confetti_spread()
+ src.confetti_spread.attach(src)
+
+/obj/item/weapon/grenade/confetti/Destroy()
+ qdel(confetti_spread)
+ confetti_spread = null
+ return ..()
+
+/obj/item/weapon/grenade/confetti/detonate() //Find a good confetti firework or pop sound effect later
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1, -3)
+ src.confetti_spread.set_up(10, 0, usr.loc)
+ spawn(0)
+ for(var/i = 1 to confetti_strength)
+ src.confetti_spread.start()
+ sleep(10)
+ qdel(src)
+
+ return
+
+/obj/item/weapon/grenade/confetti/party_ball //Intended to be used only with the confetti cannon.
+ name = "party ball"
+ desc = "Full of !!FUN!!"
+ icon = 'icons/obj/grenade.dmi'
+ icon_state = "party_ball"
+ confetti_strength = 2
+ det_time = 1
+ throwforce = 0 //Confetti cannon is only fun to shoot at people if it deals no damage.
+
+/obj/item/weapon/grenade/confetti/party_ball/detonate() //Could condense this by making the sound a variable in the parent but I'm lazy.
+ playsound(src.loc, 'sound/effects/confetti_ball.ogg', 50, 1, -3)
+ src.confetti_spread.set_up(10, 0, usr.loc)
+ spawn(0)
+ for(var/i = 1 to confetti_strength)
+ src.confetti_spread.start()
+ sleep(10)
+ qdel(src)
+
+ return
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/launcher/confetti.dm b/code/modules/projectiles/guns/launcher/confetti.dm
new file mode 100644
index 00000000000..3d23b193859
--- /dev/null
+++ b/code/modules/projectiles/guns/launcher/confetti.dm
@@ -0,0 +1,105 @@
+//The confetti cannon is a simple weapon meant to be a toy. You shoot confetti at people and it makes a funny sound. Don't give this any combat use.
+/obj/item/weapon/gun/launcher/confetti_cannon
+ name = "confetti cannon"
+ desc = "For those times when you absolutely need colored paper everywhere."
+ icon = 'icons/obj/weapons_vr.dmi'
+ icon_state = "confetti_cannon"
+ item_state = "confetti_cannon"
+ w_class = ITEMSIZE_NORMAL
+ origin_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 2)
+ throw_distance = 7
+ release_force = 5
+ var/obj/item/weapon/grenade/confetti/party_ball/chambered = null
+
+ var/confetti_charge = 0
+ var/max_confetti = 20
+
+/obj/item/weapon/gun/launcher/confetti_cannon/examine(mob/user)
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "It's loaded with [confetti_charge] ball\s of confetti."
+
+/obj/item/weapon/gun/launcher/confetti_cannon/attackby(obj/item/I as obj, mob/user as mob)
+ if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/shreddedp))
+ if(confetti_charge < max_confetti)
+ user.drop_item()
+ ++confetti_charge
+ to_chat(usr, "You put the paper in the [src].")
+ qdel(I)
+ else
+ to_chat(usr, "[src] cannot hold more paper.")
+
+/obj/item/weapon/gun/launcher/confetti_cannon/proc/pump(mob/M as mob)
+ playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
+ if(!chambered)
+ if(confetti_charge)
+ chambered = new /obj/item/weapon/grenade/confetti/party_ball
+ --confetti_charge
+ to_chat(usr, "You compress a new confetti ball.")
+ else
+ to_chat(usr, "The [src] is out of confetti!")
+ else
+ to_chat(usr, "The [src] is already loaded!")
+
+/obj/item/weapon/gun/launcher/confetti_cannon/attack_self(mob/user)
+ pump(user)
+
+/obj/item/weapon/gun/launcher/confetti_cannon/consume_next_projectile()
+ if(chambered)
+ chambered.activate(null)
+ return chambered
+
+/obj/item/weapon/gun/launcher/confetti_cannon/handle_post_fire(mob/user)
+ chambered = null
+
+/obj/item/weapon/gun/launcher/confetti_cannon/overdrive
+ name = "overdrive confetti cannon"
+ desc = "For those times when you absolutely need colored paper everywhere, EVERYWHERE."
+ confetti_charge = 100
+ max_confetti = 100
+
+/obj/item/weapon/gun/launcher/confetti_cannon/fake_shottie
+ name = "horror movie shotgun"
+ desc = "The one necessary for survival of any Final Girl."
+ icon = 'icons/obj/gun2.dmi'
+ icon_state = "ithaca"
+ item_state = "ithaca"
+ confetti_charge = 20
+
+/obj/item/weapon/gun/launcher/confetti_cannon/robot
+ name = "Party Cannon"
+ desc = "Confetti, pies, banana peels, chaos!"
+
+/obj/item/weapon/gun/launcher/confetti_cannon/robot/pump(mob/M as mob)
+ playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
+ if(!chambered)
+ var/choice = tgui_alert(usr, "Load the Party Canon with?", "Change What?", list("Confetti","Banana Peel","Cream Pie"))
+ if(!choice)
+ return
+ playsound(src, 'sound/effects/pop.ogg', 50, 0)
+ switch(choice)
+ if("Confetti")
+ chambered = new /obj/item/weapon/grenade/confetti/party_ball
+ to_chat(usr, "Confetti loaded.")
+ if(istype(usr,/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = usr
+ R.cell.charge -= 200
+ if("Banana Peel")
+ chambered = new /obj/item/weapon/bananapeel
+ to_chat(usr, "Banana peel loaded.")
+ if(istype(usr,/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = usr
+ R.cell.charge -= 200
+ if("Cream Pie")
+ chambered = new /obj/item/weapon/reagent_containers/food/snacks/pie
+ to_chat(usr, "Banana cream pie loaded.")
+ if(istype(usr,/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = usr
+ R.cell.charge -= 200
+ else
+ to_chat(usr, "The [src] is already loaded!")
+
+/obj/item/weapon/gun/launcher/confetti_cannon/robot/consume_next_projectile()
+ if(istype(chambered,/obj/item/weapon/grenade/confetti/party_ball))
+ chambered.activate(null)
+ return chambered
\ No newline at end of file
diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi
index 8f2ed0d8bb6..f55e4af9105 100644
Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ
diff --git a/icons/obj/weapons_vr.dmi b/icons/obj/weapons_vr.dmi
index 968c6e8ef27..06274f9cf72 100644
Binary files a/icons/obj/weapons_vr.dmi and b/icons/obj/weapons_vr.dmi differ
diff --git a/sound/effects/confetti_ball.ogg b/sound/effects/confetti_ball.ogg
new file mode 100644
index 00000000000..8db31be0741
Binary files /dev/null and b/sound/effects/confetti_ball.ogg differ
diff --git a/vorestation.dme b/vorestation.dme
index 21e534b3a8c..448e910772c 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1368,6 +1368,7 @@
#include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm"
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
#include "code\game\objects\items\weapons\grenades\concussion.dm"
+#include "code\game\objects\items\weapons\grenades\confetti.dm"
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
#include "code\game\objects\items\weapons\grenades\explosive.dm"
#include "code\game\objects\items\weapons\grenades\flashbang.dm"
@@ -3670,6 +3671,7 @@
#include "code\modules\projectiles\guns\energy\cell_loaded_vr\nsfw.dm"
#include "code\modules\projectiles\guns\energy\cell_loaded_vr\nsfw_cells.dm"
#include "code\modules\projectiles\guns\launcher\bows.dm"
+#include "code\modules\projectiles\guns\launcher\confetti.dm"
#include "code\modules\projectiles\guns\launcher\crossbow.dm"
#include "code\modules\projectiles\guns\launcher\grenade_launcher.dm"
#include "code\modules\projectiles\guns\launcher\pneumatic.dm"