diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index a91da6cd147..90cdae5a88e 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -67,6 +67,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define PARALLAX_SPACE 0x1
#define PARALLAX_DUST 0x2
#define PROGRESS_BARS 0x4
+#define PARALLAX_IS_STATIC 0x8
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm
index 6ba065620b0..9438f997d60 100644
--- a/code/_onclick/hud/parallax.dm
+++ b/code/_onclick/hud/parallax.dm
@@ -111,6 +111,9 @@
var/client/C = mymob.client
if(!SSparallax.parallax_initialized)
return
+
+ if (C.prefs.parallax_togs & PARALLAX_IS_STATIC)
+ return
//ACTUALLY MOVING THE PARALLAX
var/turf/posobj = C.eye ? C.eye:loc : C.mob:loc
diff --git a/code/datums/observation/moved.dm b/code/datums/observation/moved.dm
index e2123e3e4ad..627e7c93bac 100644
--- a/code/datums/observation/moved.dm
+++ b/code/datums/observation/moved.dm
@@ -18,12 +18,6 @@ var/datum/observ/moved/moved_event = new()
* Movement Handling *
********************/
-/atom/movable/Move()
- var/old_loc = loc
- . = ..()
- if(.)
- moved_event.raise_event(src, old_loc, loc)
-
/atom/movable/proc/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc)
var/turf/T = get_turf(new_loc)
if(T && T != loc)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 6d86074cf17..2200b2dca38 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -281,3 +281,27 @@ var/list/accessible_z_levels = list("8" = 5, "9" = 10, "7" = 15, "2" = 60)
. = ..()
if (. && hud_used && client && get_turf(client.eye) == destination)
hud_used.update_parallax_values()
+
+
+// Movement hooks.
+/atom/movable/Move()
+ var/old_loc = loc
+ . = ..()
+ if (.)
+ // Events.
+ moved_event.raise_event(src, old_loc, loc)
+
+ // Parallax.
+ update_client_hook()
+
+ // Lighting.
+ var/datum/light_source/L
+ var/thing
+ for (thing in light_sources)
+ L = thing
+ L.source_atom.update_light()
+
+ // Openturf.
+ if (bound_overlay)
+ // The overlay will handle cleaning itself up on non-openspace turfs.
+ bound_overlay.forceMove(get_step(src, UP))
diff --git a/code/modules/client/preference_setup/global/02_settings.dm b/code/modules/client/preference_setup/global/02_settings.dm
index 78aa025b77e..ba0f8c48991 100644
--- a/code/modules/client/preference_setup/global/02_settings.dm
+++ b/code/modules/client/preference_setup/global/02_settings.dm
@@ -64,6 +64,7 @@
. += "Space Parallax: [(pref.parallax_togs & PARALLAX_SPACE) ? "Yes" : "No"]
"
. += "Space Dust: [(pref.parallax_togs & PARALLAX_DUST) ? "Yes" : "No"]
"
. += "Progress Bars: [(pref.parallax_togs & PROGRESS_BARS) ? "Yes" : "No"]
"
+ . += "Static Space: [(pref.parallax_togs & PARALLAX_IS_STATIC) ? "Yes" : "No"]
"
/datum/category_item/player_setup_item/player_global/settings/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["toggle"])
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index 1ca3dbd2201..0b5b458316f 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -201,3 +201,16 @@
src << "You will now see progress bars on delayed actions."
else
src << "You will no longer see progress bars on delayed actions."
+
+/client/verb/toggle_static_spess()
+ set name = "Toggle Parallax Movement"
+ set category = "Preferences"
+ set desc = "Toggles movement of parallax space."
+
+ prefs.parallax_togs ^= PARALLAX_IS_STATIC
+ prefs.save_preferences()
+
+ if (prefs.parallax_togs & PARALLAX_IS_STATIC)
+ src << "Space will no longer move."
+ else
+ src << "Space will now move."
diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm
index b5aae3c2788..ce81f5e2d55 100644
--- a/code/modules/lighting/lighting_atom.dm
+++ b/code/modules/lighting/lighting_atom.dm
@@ -110,16 +110,6 @@
if (old_has_opaque_atom != T.has_opaque_atom)
T.reconsider_lights()
-/atom/movable/Move()
- . = ..()
-
- var/datum/light_source/L
- var/thing
- for (thing in light_sources)
- L = thing
- L.source_atom.update_light()
-
-
/atom/movable/forceMove()
. = ..()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 485c609f2cc..56f094634e9 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -167,7 +167,6 @@
src.m_flag = 1
if ((A != src.loc && A && A.z == src.z))
src.last_move = get_dir(A, src.loc)
- return
/client/proc/Move_object(direct)
if(mob && mob.control_object)
diff --git a/code/modules/multiz/openspace.dm b/code/modules/multiz/openspace.dm
index e129edbf36d..1796754d389 100644
--- a/code/modules/multiz/openspace.dm
+++ b/code/modules/multiz/openspace.dm
@@ -26,12 +26,6 @@
. = ..()
QDEL_NULL(bound_overlay)
-/atom/movable/Move()
- . = ..()
- if (bound_overlay)
- // The overlay will handle cleaning itself up on non-openspace turfs.
- bound_overlay.forceMove(get_step(src, UP))
-
/atom/movable/forceMove(atom/dest)
. = ..(dest)
if (bound_overlay)
diff --git a/html/changelogs/lohikar-parallax.yml b/html/changelogs/lohikar-parallax.yml
new file mode 100644
index 00000000000..28b02c8c694
--- /dev/null
+++ b/html/changelogs/lohikar-parallax.yml
@@ -0,0 +1,5 @@
+author: Lohikar
+delete-after: True
+changes:
+ - bugfix: "Parallax now actually moves like it was intended to."
+ - rscadd: "Parallax can now be made static in your preferences to get an immobile star background effect."