diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm
new file mode 100644
index 00000000000..bcf7d80f5c5
--- /dev/null
+++ b/code/game/objects/items/weapons/chrono_eraser.dm
@@ -0,0 +1,264 @@
+#define CHRONO_BEAM_RANGE 3
+#define CHRONO_FRAME_COUNT 22
+/obj/item/weapon/chrono_eraser
+ name = "Timestream Eradication Device"
+ desc = "The result of outlawed time-bluespace research, this device is capable of wiping a being from the timestream. They never are, they never were, they never will be."
+ icon = 'icons/obj/chronos.dmi'
+ icon_state = "chronobackpack"
+ item_state = "backpack"
+ w_class = 4.0
+ slot_flags = SLOT_BACK
+ slowdown = 1
+ action_button_name = "Equip/Unequip TED Gun"
+ var/obj/item/weapon/gun/energy/chrono_gun/PA = null
+ var/list/erased_minds = list() //a collection of minds from the dead
+
+/obj/item/weapon/chrono_eraser/proc/pass_mind(var/datum/mind/M)
+ erased_minds += M
+
+/obj/item/weapon/chrono_eraser/dropped()
+ if(PA)
+ qdel(PA)
+
+/obj/item/weapon/chrono_eraser/Destroy()
+ dropped()
+ ..()
+
+/obj/item/weapon/chrono_eraser/ui_action_click()
+ var/mob/living/carbon/user = src.loc
+ if(iscarbon(user) && (user.back == src))
+ if(PA)
+ qdel(PA)
+ else
+ PA = new(src)
+ user.put_in_hands(PA)
+
+
+
+/obj/item/weapon/gun/energy/chrono_gun
+ name = "T.E.D. Projection Apparatus"
+ desc = "It's as if they never existed in the first place."
+ icon = 'icons/obj/chronos.dmi'
+ icon_state = "chronogun"
+ item_state = "chronogun"
+ w_class = 3.0
+ flags = NODROP
+ ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam)
+ fire_delay = 50
+ var/obj/item/weapon/chrono_eraser/TED = null
+ var/obj/effect/chrono_field/field = null
+ var/turf/startpos = null
+
+/obj/item/weapon/gun/energy/chrono_gun/New(var/obj/item/weapon/chrono_eraser/T)
+ . = ..()
+ if(istype(T))
+ TED = T
+ else //admin must have spawned it
+ TED = new(src.loc)
+ qdel(src)
+
+/obj/item/weapon/gun/energy/chrono_gun/dropped()
+ qdel(src)
+
+/obj/item/weapon/gun/energy/chrono_gun/update_icon()
+ return
+
+/obj/item/weapon/gun/energy/chrono_gun/process_fire()
+ if(field)
+ field_disconnect(field)
+ ..()
+
+/obj/item/weapon/gun/energy/chrono_gun/Destroy()
+ if(TED)
+ TED.PA = null
+ TED = null
+ if(field)
+ field_disconnect(field)
+ ..()
+
+/obj/item/weapon/gun/energy/chrono_gun/proc/field_connect(var/obj/effect/chrono_field/F)
+ var/mob/living/user = src.loc
+ if(F.gun)
+ if(isliving(user) && F.captured)
+ user << "FAIL: [F.captured] already has an existing connection."
+ src.field_disconnect(F)
+ else
+ startpos = get_turf(src)
+ field = F
+ F.gun = src
+ if(isliving(user) && F.captured)
+ user << "Connection established with target: [F.captured]"
+
+
+/obj/item/weapon/gun/energy/chrono_gun/proc/field_disconnect(var/obj/effect/chrono_field/F)
+ if(F && field == F)
+ var/mob/living/user = src.loc
+ if(F.gun == src)
+ F.gun = null
+ if(isliving(user) && F.captured)
+ user << "Disconnected from target: [F.captured]"
+ field = null
+ startpos = null
+
+/obj/item/weapon/gun/energy/chrono_gun/proc/field_check(var/obj/effect/chrono_field/F)
+ if(F)
+ if(field == F)
+ var/turf/currentpos = get_turf(src)
+ var/mob/living/user = src.loc
+ if((currentpos == startpos) && (field in view(CHRONO_BEAM_RANGE, currentpos)) && !user.lying && (user.stat == CONSCIOUS))
+ return 1
+ field_disconnect(F)
+ return 0
+
+/obj/item/weapon/gun/energy/chrono_gun/proc/pass_mind(var/datum/mind/M)
+ if(TED)
+ TED.pass_mind(M)
+
+
+/obj/item/projectile/energy/chrono_beam
+ name = "eradication beam"
+ icon_state = "chronobolt"
+ range = CHRONO_BEAM_RANGE
+ color = null
+ nodamage = 1
+ var/obj/item/weapon/gun/energy/chrono_gun/gun = null
+
+/obj/item/projectile/energy/chrono_beam/fire()
+ gun = firer.get_active_hand()
+ if(istype(gun))
+ return ..()
+ else
+ return 0
+
+/obj/item/projectile/energy/chrono_beam/on_hit(var/atom/target)
+ if(target && gun && isliving(target))
+ var/obj/effect/chrono_field/F = new(target.loc, target, gun)
+ gun.field_connect(F)
+
+
+/obj/item/ammo_casing/energy/chrono_beam
+ name = "eradication beam"
+ projectile_type = /obj/item/projectile/energy/chrono_beam
+ icon_state = "chronobolt"
+ e_cost = 0
+
+
+/obj/effect/chrono_field
+ name = "eradication field"
+ desc = "An aura of time-bluespace energy."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "chronofield"
+ density = 1
+ anchored = 1
+ unacidable = 1
+ blend_mode = BLEND_MULTIPLY
+ var/mob/living/captured = null
+ var/obj/item/weapon/gun/energy/chrono_gun/gun = null
+ var/tickstokill = 30
+ var/image/mob_underlay = null
+ var/preloaded = 0
+ var/RPpos = null
+
+/obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/weapon/gun/energy/chrono_gun/G)
+ if(target && isliving(target) && G)
+ target.loc = src
+ src.captured = target
+ var/icon/mob_snapshot = getFlatIcon(target)
+ var/icon/cached_icon = new()
+
+ for(var/i=1, i<=CHRONO_FRAME_COUNT, i++)
+ var/icon/removing_frame = icon('icons/obj/chronos.dmi', "erasing", SOUTH, i)
+ var/icon/mob_icon = icon(mob_snapshot)
+ mob_icon.Blend(removing_frame, ICON_MULTIPLY)
+ cached_icon.Insert(mob_icon, "frame[i]")
+
+ mob_underlay = new(cached_icon, "frame1")
+ update_icon()
+
+ desc = initial(desc) + "
It appears to contain [target.name]."
+ SSobj.processing.Add(src)
+
+/obj/effect/chrono_field/Destroy()
+ if(gun && gun.field_check(src))
+ gun.field_disconnect(src)
+ ..()
+
+/obj/effect/chrono_field/update_icon()
+ var/ttk_frame = 1 - (tickstokill / initial(tickstokill))
+ ttk_frame = Clamp(Ceiling(ttk_frame * CHRONO_FRAME_COUNT), 1, CHRONO_FRAME_COUNT)
+ if(ttk_frame != RPpos)
+ RPpos = ttk_frame
+ mob_underlay.icon_state = "frame[RPpos]"
+ underlays = list() //hack: BYOND refuses to update the underlay to match the icon_state otherwise
+ underlays += mob_underlay
+
+/obj/effect/chrono_field/process()
+ if(captured)
+ if(tickstokill > initial(tickstokill))
+ for(var/atom/movable/AM in contents)
+ AM.loc = loc
+ qdel(src)
+ else if(tickstokill <= 0)
+ captured << "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy..."
+ var/mob/dead/observer/ghost = captured.ghostize(1)
+ if(captured.mind)
+ if(ghost)
+ ghost.mind = null
+ if(gun)
+ gun.pass_mind(captured.mind)
+ qdel(captured)
+ qdel(src)
+ else
+ captured.Paralyse(4)
+ if(captured.reagents)
+ captured.reagents.del_reagent("synaptizine") //you pesky thing you
+ if(captured.loc != src) //If they manage to escape, immediately kill them, this is so that even if there IS a way to get out, they won't use it
+ captured.loc = src
+ tickstokill = 0
+ return .()
+ update_icon()
+ if(gun)
+ if(gun.field_check(src))
+ tickstokill--
+ else
+ gun = null
+ return .()
+ else
+ tickstokill++
+ else
+ qdel(src)
+
+/obj/effect/chrono_field/bullet_act(var/obj/item/projectile/P)
+ if(istype(P, /obj/item/projectile/energy/chrono_beam))
+ var/obj/item/projectile/energy/chrono_beam/beam = P
+ var/obj/item/weapon/gun/energy/chrono_gun/Pgun = beam.gun
+ if(Pgun && istype(Pgun))
+ Pgun.field_connect(src)
+ else
+ return 0
+
+/obj/effect/chrono_field/assume_air()
+ return 0
+
+/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
+ var/datum/gas_mixture/GM = new
+ GM.oxygen = MOLES_O2STANDARD
+ GM.nitrogen = MOLES_N2STANDARD
+ GM.temperature = T20C
+ return GM
+
+/obj/effect/chrono_field/Move()
+ return
+
+/obj/effect/chrono_field/singularity_act()
+ return
+
+/obj/effect/chrono_field/ex_act()
+ return
+
+/obj/effect/chrono_field/blob_act()
+ return
+
+
+#undef CHRONO_BEAM_RANGE
+#undef CHRONO_FRAME_COUNT
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
new file mode 100644
index 00000000000..7876f61368c
--- /dev/null
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -0,0 +1,213 @@
+/obj/item/clothing/head/helmet/space/chronos
+ name = "Chronosuit Helmet"
+ desc = "A white helmet with an opaque blue visor."
+ icon_state = "chronohelmet"
+ item_state = "chronohelmet"
+ slowdown = 1
+ armor = list(melee = 60, bullet = 30/*bullet through the visor*/, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90)
+ var/obj/item/clothing/suit/space/chronos/suit = null
+
+/obj/item/clothing/head/helmet/space/chronos/dropped()
+ if(suit)
+ suit.deactivate()
+ ..()
+
+/obj/item/clothing/head/helmet/space/chronos/Destroy()
+ dropped()
+ ..()
+
+
+/obj/item/clothing/suit/space/chronos
+ name = "Chronosuit"
+ desc = "An advanced spacesuit equipped with teleportation and anti-compression technology"
+ icon_state = "chronosuit"
+ item_state = "chronosuit"
+ action_button_name = "Toggle Chronosuit"
+ slowdown = 2
+ armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90)
+ var/obj/item/clothing/head/helmet/space/chronos/helmet = null
+ var/obj/effect/chronos_cam/camera = null
+ var/activating = 0
+ var/activated = 0
+ var/cooldowntime = 50 //deciseconds
+ var/cooldown = 0
+ var/teleporting = 0
+
+
+/obj/item/clothing/suit/space/chronos/proc/new_camera(var/mob/user)
+ if(camera)
+ qdel(camera)
+ camera = new /obj/effect/chronos_cam(get_turf(user))
+ camera.holder = user
+ user.remote_control = camera
+
+/obj/item/clothing/suit/space/chronos/ui_action_click()
+ if((cooldown <= world.time) && !teleporting && !activating)
+ if(!activated)
+ activate()
+ else
+ deactivate()
+
+/obj/item/clothing/suit/space/chronos/dropped()
+ if(activated)
+ deactivate()
+ ..()
+
+/obj/item/clothing/suit/space/chronos/Destroy()
+ dropped()
+ ..()
+
+/obj/item/clothing/suit/space/chronos/emp_act(severity)
+ var/mob/living/carbon/human/user = src.loc
+ switch(severity)
+ if(1)
+ if(user && ishuman(user) && (user.wear_suit == src))
+ user << "Elecrtromagnetic pulse detected, shutting down systems to preserve integrity..."
+ deactivate()
+
+/obj/item/clothing/suit/space/chronos/proc/chronowalk(var/mob/living/carbon/human/user)
+ if(!teleporting && user && (user.stat == CONSCIOUS))
+ teleporting = 1
+ var/turf/from_turf = get_turf(user)
+ if(!from_turf) //sanity, things happen
+ teleporting = 0
+ return
+ var/turf/to_turf = from_turf
+ var/atom/movable/overlay/phaseanim = new(from_turf)
+ var/obj/holder = new(camera)
+ phaseanim.name = "phasing [user.name]"
+ phaseanim.icon = 'icons/mob/mob.dmi'
+ phaseanim.icon_state = "chronostuck"
+ phaseanim.density = 1
+ phaseanim.layer = FLY_LAYER
+ phaseanim.master = user
+ user.ExtinguishMob()
+ if(user.buckled)
+ user.buckled.unbuckle()
+ user.loc = holder
+ flick("chronophase", phaseanim)
+ spawn(7)
+ if(user)
+ if(phaseanim)
+ if(camera && camera.loc)
+ to_turf = camera.loc
+ flick("chronounphase", phaseanim)
+ else
+ flick("chronostuck", phaseanim)
+ phaseanim.loc = to_turf
+ sleep(7)
+ if(holder)
+ if(user && user in holder.contents)
+ user.loc = to_turf
+ if(user.client)
+ if(camera)
+ user.client.eye = camera
+ else
+ user.client.eye = user
+ qdel(holder)
+ else if(user)
+ user.loc = from_turf
+ if(phaseanim)
+ qdel(phaseanim)
+ teleporting = 0
+ if(user && !user.loc) //ubersanity
+ user.loc = locate(0,0,1)
+ user.gib()
+
+/obj/item/clothing/suit/space/chronos/process()
+ if(activated)
+ var/mob/living/carbon/human/user = src.loc
+ if(user && ishuman(user) && (user.wear_suit == src))
+ if(camera && (user.remote_control == camera))
+ if(!teleporting && !((camera.x == user.x) && (camera.y == user.y) && (camera.z == user.z))) //cheaper than a couple get_turf calls???
+ chronowalk(user)
+ else
+ new_camera(user)
+ else
+ SSobj.processing.Remove(src)
+
+/obj/item/clothing/suit/space/chronos/proc/activate()
+ if(!activating && !activated && !teleporting)
+ activating = 1
+ var/mob/living/carbon/human/user = src.loc
+ if(user && ishuman(user))
+ if(user.wear_suit == src)
+ user << "\nChronosuitMK4 login: root"
+ user << "Password:\n"
+ user << "root@ChronosuitMK4# chronowalk4 --start\n"
+ if(user.head && istype(user.head, /obj/item/clothing/head/helmet/space/chronos))
+ user << "\[ ok \] Mounting /dev/helmet"
+ helmet = user.head
+ helmet.flags |= NODROP
+ helmet.suit = src
+ src.flags |= NODROP
+ user << "\[ ok \] Starting brainwave scanner"
+ user << "\[ ok \] Starting ui display driver"
+ user << "\[ ok \] Initializing chronowalk4-view"
+ new_camera(user)
+ SSobj.processing.Add(src)
+ activated = 1
+ else
+ user << "\[ fail \] Mounting /dev/helmet"
+ user << "FATAL: Unable to locate /dev/helmet. Aborting..."
+ cooldown = world.time + cooldowntime
+ activating = 0
+ return 0
+
+/obj/item/clothing/suit/space/chronos/proc/deactivate()
+ if(activated)
+ activating = 1
+ var/mob/living/carbon/human/user = src.loc
+ if(user && ishuman(user))
+ if(user.wear_suit == src)
+ user << "\nroot@ChronosuitMK4# chronowalk4 --stop\n"
+ if(camera)
+ user << "\[ ok \] Sending TERM signal to chronowalk4-view" //yes I know they aren't a different color when shutting down, but they were too similar at a glance
+ qdel(camera)
+ if(helmet)
+ user << "\[ ok \] Stopping ui display driver"
+ user << "\[ ok \] Stopping brainwave scanner"
+ user << "\[ ok \] Unmounting /dev/helmet"
+ helmet.flags &= ~NODROP
+ helmet.suit = null
+ helmet = null
+ user << "logout"
+ src.flags &= ~NODROP
+ cooldown = world.time + cooldowntime * 1.5
+ activated = 0
+ activating = 0
+
+
+/obj/effect/chronos_cam
+ name = "Chronosuit View"
+ density = 0
+ anchored = 1
+ invisibility = 101
+ opacity = 0
+ mouse_opacity = 0
+ var/mob/holder = null
+
+/obj/effect/chronos_cam/relaymove(var/mob/user, direction)
+ if(holder)
+ if(user == holder)
+ if(user.client && user.client.eye != src)
+ src.loc = get_turf(user)
+ user.client.eye = src
+ var/step = get_step(src, direction)
+ if(step)
+ if(istype(step, /turf/space))
+ if(!src.Move(step))
+ src.loc = step
+ else
+ src.loc = step
+ else
+ qdel(src)
+
+/obj/effect/chronos_cam/Destroy()
+ if(holder)
+ if(holder.remote_control == src)
+ holder.remote_control = null
+ if(holder.client && (holder.client.eye == src))
+ holder.client.eye = holder
+ ..()
+
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index d48d0456900..7a18315e8cb 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -157,5 +157,6 @@
var/force_compose = 0 //If this is nonzero, the mob will always compose it's own hear message instead of using the one given in the arguments.
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
+ var/atom/movable/remote_control //Calls relaymove() to whatever it is
var/turf/listed_turf = null //the current turf being examined in the stat panel
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 0c26dc9a84b..7c542c14e3e 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -116,6 +116,9 @@
if(mob.buckled) //if we're buckled to something, tell it we moved.
return mob.buckled.relaymove(mob, direct)
+ if(mob.remote_control) //we're controlling something, our movement is relayed to it
+ return mob.remote_control.relaymove(mob, direct)
+
if(!mob.canmove)
return 0
diff --git a/icons/Chrono_Legionairre.dmi b/icons/Chrono_Legionairre.dmi
new file mode 100644
index 00000000000..77f8bdfeeeb
Binary files /dev/null and b/icons/Chrono_Legionairre.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 7bf76901789..f1a60e810d8 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index d613dedcefe..e8d4b61b58b 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 5c3f4f14fa1..4474ee9dee8 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index 19c313fbf4c..b8f19bf080c 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index cb7b5a8acfe..d8b02e4e920 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 390f3f00953..99d27ba25c6 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index c0b2de054c7..e83029f9fe5 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/chronos.dmi b/icons/obj/chronos.dmi
new file mode 100644
index 00000000000..dcc3984fd02
Binary files /dev/null and b/icons/obj/chronos.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 7e6dcb6a65d..774e2c7f9c1 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 1767a121202..21b71bf0c87 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 598999653f8..d723b6d6286 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index a0ecfa42024..e0d96f0935e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -579,6 +579,7 @@
#include "code\game\objects\items\weapons\AI_modules.dm"
#include "code\game\objects\items\weapons\airlock_painter.dm"
#include "code\game\objects\items\weapons\cards_ids.dm"
+#include "code\game\objects\items\weapons\chrono_eraser.dm"
#include "code\game\objects\items\weapons\cigs_lighters.dm"
#include "code\game\objects\items\weapons\clown_items.dm"
#include "code\game\objects\items\weapons\cosmetics.dm"
@@ -843,6 +844,7 @@
#include "code\modules\clothing\shoes\colour.dm"
#include "code\modules\clothing\shoes\magboots.dm"
#include "code\modules\clothing\shoes\miscellaneous.dm"
+#include "code\modules\clothing\spacesuits\chronosuit.dm"
#include "code\modules\clothing\spacesuits\hardsuit.dm"
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\ninja.dm"