diff --git a/code/datums/components/crafting/robot.dm b/code/datums/components/crafting/robot.dm
index 8a6a014d5a4..94c1aa979d1 100644
--- a/code/datums/components/crafting/robot.dm
+++ b/code/datums/components/crafting/robot.dm
@@ -201,3 +201,18 @@
/obj/item/reagent_containers/syringe = 1,
)
category = CAT_ROBOT
+
+/datum/crafting_recipe/mod_core_soul
+ name = "MOD core (Soul)"
+ result = /obj/item/mod/core/soul
+ tool_behaviors = list(TOOL_SCREWDRIVER)
+ time = 10 SECONDS
+ reqs = list(
+ /obj/item/stack/cable_coil = 5,
+ /obj/item/stack/rods = 2,
+ /obj/item/stack/sheet/glass = 1,
+ /obj/item/soulstone = 1,
+ )
+ parts = list(/obj/item/soulstone = 1)
+ category = CAT_ROBOT
+ crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED
diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm
index 62f30855abb..1c7fd0523b0 100644
--- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm
+++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm
@@ -355,3 +355,8 @@
name = "Piggy Bank"
icon_file = 'icons/obj/fluff/general.dmi'
json_config = 'code/datums/greyscale/json_configs/piggy_bank.json'
+
+/datum/greyscale_config/mod_core_soul
+ name = "MOD Soul Core"
+ icon_file = 'icons/obj/clothing/modsuit/mod_construction.dmi'
+ json_config = 'code/datums/greyscale/json_configs/mod_core_soul.json'
diff --git a/code/datums/greyscale/json_configs/mod_core_soul.json b/code/datums/greyscale/json_configs/mod_core_soul.json
new file mode 100644
index 00000000000..fbdd965ac6c
--- /dev/null
+++ b/code/datums/greyscale/json_configs/mod_core_soul.json
@@ -0,0 +1,15 @@
+{
+ "mod-core-soul": [
+ {
+ "type": "icon_state",
+ "icon_state": "mod-core-soul-base",
+ "blend_mode": "overlay"
+ },
+ {
+ "type": "icon_state",
+ "icon_state": "mod-core-soul-shard",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm
index 6c31a2fcab5..a828415a1d9 100644
--- a/code/modules/antagonists/wizard/equipment/soulstone.dm
+++ b/code/modules/antagonists/wizard/equipment/soulstone.dm
@@ -152,6 +152,48 @@
if(spent)
. += span_cult("This shard is spent; it is now just a creepy rock.")
+/obj/item/soulstone/examine_more(mob/user)
+ . = ..()
+ if(!isliving(user) || isnull(user.mind))
+ return
+ if(!user.mind.has_crafting_recipe(/datum/crafting_recipe/mod_core_soul))
+ . += span_notice("You know... there might be alternate uses for something like this.")
+
+/obj/item/soulstone/Topic(href, list/href_list)
+ . = ..()
+
+ if(href_list["learn_soul_core_recipe"])
+ learn_soul_core_recipe(usr)
+
+/obj/item/soulstone/proc/learn_soul_core_recipe(mob/user)
+ if(user.mind?.has_crafting_recipe(/datum/crafting_recipe/mod_core_soul))
+ return
+ if(!soul_core_learning_check(user))
+ return
+ var/list/remarks = list(
+ "You begin brainstorming...",
+ "Are constructs powered by souls?",
+ "Then wouldn't that mean...",
+ "Can that energy be turned into electricity?",
+ "You have an idea...",
+ )
+ for(var/remark in remarks)
+ to_chat(user, span_notice("[remark]"))
+ if(!do_after(
+ user,
+ 5 SECONDS,
+ timed_action_flags = IGNORE_USER_LOC_CHANGE | IGNORE_HELD_ITEM,
+ extra_checks = CALLBACK(src, PROC_REF(soul_core_learning_check), user),
+ interaction_key = "soul_core_learn",
+ max_interact_count = 1
+ ))
+ return
+ user.mind?.teach_crafting_recipe(/datum/crafting_recipe/mod_core_soul)
+ to_chat(user, span_notice("You learned to craft [/obj/item/mod/core/soul::name]."))
+
+/obj/item/soulstone/proc/soul_core_learning_check(mob/user)
+ return user.is_holding(src) || (user.loc == loc) || (isturf(loc) && user.Adjacent(loc))
+
/obj/item/soulstone/Destroy() //Stops the shade from being qdel'd immediately and their ghost being sent back to the arrival shuttle.
for(var/mob/living/basic/shade/shade in src)
INVOKE_ASYNC(shade, TYPE_PROC_REF(/mob/living, death))
diff --git a/code/modules/mod/mod_core.dm b/code/modules/mod/mod_core.dm
index 01e0902b6b0..657b6838394 100644
--- a/code/modules/mod/mod_core.dm
+++ b/code/modules/mod/mod_core.dm
@@ -509,3 +509,168 @@
var/flower_boots = new chosen_type(get_turf(mod.wearer))
animate(flower_boots, alpha = 0, 1 SECONDS)
QDEL_IN(flower_boots, 1 SECONDS)
+
+/obj/item/mod/core/soul
+ name = "MOD soul shard core"
+ desc = "A soul shard haphazardly jammed into a hand-crafted MOD core frame."
+ icon_state = "mod-core-soul"
+ icon_state_preview = "mod-core-soul-preview"
+ var/base_desc
+ var/theme = THEME_CULT
+ greyscale_config = /datum/greyscale_config/mod_core_soul
+ greyscale_colors = "#ff0000"
+
+/obj/item/mod/core/soul/Initialize(mapload)
+ . = ..()
+ base_desc = desc
+ update_appearance(UPDATE_DESC)
+
+/obj/item/mod/core/soul/update_desc(updates)
+ . = ..()
+ desc = base_desc
+ switch(theme)
+ if(THEME_CULT)
+ desc += " You can feel unholy energies trying to tear something away from you."
+ if(THEME_HOLY)
+ desc += " It emanates a divine aura that defies souls tainted by darker forces."
+ if(THEME_WIZARD)
+ desc += " Yet another foray by the Wizard Federation into the dangerous field of soul magic."
+ if(THEME_HERETIC)
+ desc += " The surface of the shard shines with glimpses of things which never were, yet have always been."
+ else
+ desc += " Or at least, that's what it should be. Somebody must have set a variable incorrectly."
+
+/obj/item/mod/core/soul/update_greyscale()
+ switch(theme)
+ if(THEME_CULT)
+ greyscale_colors = "#ff0000"
+ if(THEME_HOLY)
+ greyscale_colors = "#0000ff"
+ if(THEME_WIZARD)
+ greyscale_colors = "#ff00ff"
+ if(THEME_HERETIC)
+ greyscale_colors = "#00ff00"
+ return ..()
+
+/obj/item/mod/core/soul/CheckParts(list/parts_list, datum/crafting_recipe/current_recipe)
+ var/obj/item/soulstone/stone = locate() in parts_list
+ set_theme(stone.theme)
+ for(var/mob/living/basic/shade/shade in stone)
+ shade.forceMove(get_turf(src))
+ shade.visible_message(span_warning("[shade] is ejected from [stone] as it is inserted into [src]!"), span_warning("You are ejected from [stone] as it is inserted into [src]!"))
+ parts_list -= stone
+ qdel(stone)
+ return ..()
+
+/obj/item/mod/core/soul/proc/set_theme(new_theme)
+ theme = new_theme
+ update_appearance(UPDATE_DESC)
+ update_greyscale()
+
+/obj/item/mod/core/soul/charge_source()
+ return CONFIG_GET(flag/disable_human_mood) ? src : mod.wearer?.mob_mood
+
+/obj/item/mod/core/soul/max_charge_amount()
+ return CONFIG_GET(flag/disable_human_mood) ? INFINITY : SANITY_MAXIMUM
+
+/obj/item/mod/core/soul/charge_amount()
+ var/mob/living/wearer = mod.wearer
+ if(!wearer)
+ return 0
+ if(HAS_TRAIT(wearer, TRAIT_NO_SOUL))
+ return 0 // Can't draw from something that isn't there.
+ if(CONFIG_GET(flag/disable_human_mood))
+ return INFINITY
+ var/datum/mood/source = charge_source()
+ return source?.sanity
+
+/obj/item/mod/core/soul/check_charge(amount)
+ if(CONFIG_GET(flag/disable_human_mood))
+ return !!mod.wearer
+ return charge_amount() >= amount * 10 / STANDARD_CELL_CHARGE
+
+/obj/item/mod/core/soul/subtract_charge(amount)
+ var/mob/living/wearer = mod.wearer
+ if(CONFIG_GET(flag/disable_human_mood))
+ return !!wearer
+ var/datum/mood/source = charge_source()
+ source.adjust_sanity(-amount * 10 / STANDARD_CELL_CHARGE)
+ var/backlash_type = get_backlash_type(wearer)
+ if(backlash_type)
+ wearer.add_mood_event("soul_core", backlash_type)
+ else
+ wearer.add_mood_event("soul_core", /datum/mood_event/soul_core_warning)
+ return TRUE
+
+/obj/item/mod/core/soul/get_chargebar_string()
+ var/mob/living/wearer = mod.wearer
+ if(wearer || HAS_TRAIT(wearer, TRAIT_NO_SOUL))
+ return "No power source detected."
+ if(CONFIG_GET(flag/disable_human_mood))
+ return "Infinite"
+ return "[round(charge_amount() / max_charge_amount() * 100, 0.1)]%"
+
+/obj/item/mod/core/soul/get_chargebar_color()
+ switch(theme)
+ if(THEME_CULT)
+ return "red"
+ if(THEME_HOLY)
+ return "blue"
+ if(THEME_WIZARD)
+ return "purple"
+ if(THEME_HERETIC)
+ return "green"
+
+/obj/item/mod/core/soul/proc/get_backlash_type(mob/living/checked)
+ switch(theme)
+ if(THEME_CULT)
+ if(!(IS_CULTIST(checked) || IS_HERETIC(checked) || HAS_MIND_TRAIT(checked, TRAIT_MAGICALLY_GIFTED)))
+ return /datum/mood_event/soul_core_torment
+ if(THEME_HERETIC)
+ if(!(IS_CULTIST(checked) || IS_HERETIC(checked) || HAS_MIND_TRAIT(checked, TRAIT_MAGICALLY_GIFTED)))
+ return /datum/mood_event/soul_core_torment/heretic
+ if(THEME_HOLY)
+ if(IS_CULTIST(checked) || IS_HERETIC(checked))
+ return /datum/mood_event/soul_core_torment
+ if(IS_WIZARD(checked))
+ return /datum/mood_event/soul_core_discomfort
+
+/obj/item/mod/core/soul/get_charge_icon_state()
+ switch(round(charge_amount() / max_charge_amount(), 0.01))
+ if(0.75 to INFINITY)
+ return "high"
+ if(0.5 to 0.75)
+ return "mid"
+ if(0.25 to 0.5)
+ return "low"
+ if(0.02 to 0.25)
+ return "very_low"
+
+ return "empty"
+
+/obj/item/mod/core/soul/vv_edit_var(vname, vval)
+ . = ..()
+ if(vname == NAMEOF(src, theme))
+ update_appearance(UPDATE_DESC)
+ update_greyscale()
+
+/datum/mood_event/soul_core_torment
+ description = "IT BURNS!! IT BURNS!! THE DEEPEST DEPTHS OF MY BEING!! IT BURNS!!"
+ mood_change = -20
+ timeout = 10 SECONDS
+
+/datum/mood_event/soul_core_torment/heretic
+ description = "GET OUT OF MY HEAD GET OUT OF MY HEAD GET OUT OF MY HEAD!!"
+
+/datum/mood_event/soul_core_discomfort
+ description = "I'm no fan of these divine powers breathing down my neck."
+ mood_change = -3
+ timeout = 10 SECONDS
+
+/datum/mood_event/soul_core_warning
+ description = "I can feel my modsuit siphoning my energy. I'd better keep my spirits high."
+ mood_change = 0
+ timeout = 10 SECONDS
+
+/obj/item/mod/core/soul/wizard
+ theme = THEME_WIZARD
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index 08f104a95a0..1b442ed9619 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -390,7 +390,7 @@
/obj/item/mod/control/pre_equipped/enchanted
theme = /datum/mod_theme/enchanted
starting_frequency = null
- applied_core = /obj/item/mod/core/infinite
+ applied_core = /obj/item/mod/core/soul/wizard
applied_modules = list(
/obj/item/mod/module/storage/large_capacity,
/obj/item/mod/module/energy_shield/wizard,
diff --git a/icons/obj/clothing/modsuit/mod_construction.dmi b/icons/obj/clothing/modsuit/mod_construction.dmi
index 1080b896507..b2b5c1f5ceb 100644
Binary files a/icons/obj/clothing/modsuit/mod_construction.dmi and b/icons/obj/clothing/modsuit/mod_construction.dmi differ