diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 704f2ff7f5e..3e13021c4ae 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -1483,6 +1483,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Prevents items from being speed potion-ed, but allows their speed to be altered in other ways
#define TRAIT_NO_SPEED_POTION "no_speed_potion"
+/// Prevents observers from being able to observe (seeing their UI and such)
+#define TRAIT_NO_OBSERVE "no_observe"
+
/// Demolition modifier when hitting this object is inverted (ie, 1 / demolition)
#define TRAIT_INVERTED_DEMOLITION "demolition_inverted"
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 9962833befc..0efd4461634 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -605,6 +605,9 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_PREVENT_BLINK_LOOPS" = TRAIT_PREVENT_BLINK_LOOPS,
"TRAIT_NO_EYELIDS" = TRAIT_NO_EYELIDS,
),
+ /mob/dead/observer = list(
+ "TRAIT_NO_OBSERVE" = TRAIT_NO_OBSERVE,
+ ),
/obj/item = list(
"TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING,
"TRAIT_AQUARIUM_CONTENT" = TRAIT_AQUARIUM_CONTENT,
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index b8a18782c3d..ceadd254044 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -967,10 +967,6 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0)
var/ghost_limit = 3
var/ghosts = 0
-/obj/effect/rune/manifest/Initialize(mapload)
- . = ..()
-
-
/obj/effect/rune/manifest/can_invoke(mob/living/user)
if(!(user in get_turf(src)))
to_chat(user, span_cult_italic("You must be standing on [src]!"))
@@ -1062,6 +1058,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0)
affecting.visible_message(span_warning("[affecting] freezes statue-still, glowing an unearthly red."), \
span_cult("You see what lies beyond. All is revealed. In this form you find that your voice booms louder and you can mark targets for the entire cult"))
var/mob/dead/observer/G = affecting.ghostize(TRUE)
+ ADD_TRAIT(G, TRAIT_NO_OBSERVE, CULT_TRAIT)
var/datum/action/innate/cult/comm/spirit/CM = new
var/datum/action/innate/cult/ghostmark/GM = new
G.name = "Dark Spirit of [G.name]"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index a1994137ad3..fcd61a3205c 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -902,7 +902,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Observe"
set category = "Ghost"
- if(!isobserver(usr)) //Make sure they're an observer!
+ if(!isobserver(usr) || HAS_TRAIT(src, TRAIT_NO_OBSERVE)) //Make sure they're an observer!
return
reset_perspective(null)
@@ -941,6 +941,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
this is a bug (and a past exploit) and should be investigated.")
return
+ if(HAS_TRAIT(src, TRAIT_NO_OBSERVE))
+ return
+
//Istype so we filter out points of interest that are not mobs
if(client && mob_eye && istype(mob_eye))
client.set_eye(mob_eye)
diff --git a/code/modules/mob/dead/observer/orbit.dm b/code/modules/mob/dead/observer/orbit.dm
index d564fd69eb8..4312386b27b 100644
--- a/code/modules/mob/dead/observer/orbit.dm
+++ b/code/modules/mob/dead/observer/orbit.dm
@@ -147,6 +147,7 @@ GLOBAL_DATUM_INIT(orbit_menu, /datum/orbit_menu, new)
"ghosts" = ghosts,
"misc" = misc,
"npcs" = npcs,
+ "can_observe" = !HAS_TRAIT(user, TRAIT_NO_OBSERVE),
)
diff --git a/tgui/packages/tgui/interfaces/Orbit/OrbitSearchBar.tsx b/tgui/packages/tgui/interfaces/Orbit/OrbitSearchBar.tsx
index d4663b63781..7f52bd58821 100644
--- a/tgui/packages/tgui/interfaces/Orbit/OrbitSearchBar.tsx
+++ b/tgui/packages/tgui/interfaces/Orbit/OrbitSearchBar.tsx
@@ -86,16 +86,18 @@ export function OrbitSearchBar(props) {
tooltipPosition="bottom-start"
/>
-
-
+ )}