diff --git a/Content.Shared/_Arcadis/Computer/ComputerDiskComponent.cs b/Content.Shared/_Arcadis/Computer/ComputerDiskComponent.cs
new file mode 100644
index 00000000000..5813c0342a8
--- /dev/null
+++ b/Content.Shared/_Arcadis/Computer/ComputerDiskComponent.cs
@@ -0,0 +1,23 @@
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared._Arcadis.Computer;
+
+///
+/// Main component for the ComputerDisk system
+///
+[RegisterComponent, NetworkedComponent]
+//[Access(typeof(ComputerDiskSystem))]
+public sealed partial class ComputerDiskComponent : Component
+{
+ ///
+ /// The prototype of the computer that will be used
+ ///
+ [DataField]
+ public EntProtoId ProgramPrototype;
+ public EntityUid? ProgramPrototypeEntity;
+
+ [DataField]
+ public bool PersistState;
+}
diff --git a/Content.Shared/_Arcadis/Computer/ModularComputerComponent.cs b/Content.Shared/_Arcadis/Computer/ModularComputerComponent.cs
new file mode 100644
index 00000000000..de4fe5f2d24
--- /dev/null
+++ b/Content.Shared/_Arcadis/Computer/ModularComputerComponent.cs
@@ -0,0 +1,20 @@
+using Content.Shared.Containers.ItemSlots;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared._Arcadis.Computer;
+
+///
+/// Main component for the ComputerDisk system
+///
+[RegisterComponent, NetworkedComponent]
+//[Access(typeof(ComputerDiskSystem))]
+public sealed partial class ModularComputerComponent : Component
+{
+ [DataField]
+ public string DiskSlot = "modularComputerDiskSlot";
+
+ [DataField]
+ public SoundSpecifier? DiskInsertSound = new SoundPathSpecifier("/Audio/_Arcadis/computer_startup.ogg");
+}
diff --git a/Content.Shared/_Arcadis/Computer/ModularComputerSystem.cs b/Content.Shared/_Arcadis/Computer/ModularComputerSystem.cs
new file mode 100644
index 00000000000..7a6d7742d11
--- /dev/null
+++ b/Content.Shared/_Arcadis/Computer/ModularComputerSystem.cs
@@ -0,0 +1,131 @@
+using Content.Shared.Containers.ItemSlots;
+using Content.Shared.Coordinates;
+using Robust.Shared.Audio;
+using Content.Shared.Audio;
+using Robust.Shared.Network;
+using Robust.Shared.Containers;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Audio.Systems;
+using Content.Shared.Popups;
+using Content.Shared.Examine;
+using Content.Shared.Interaction;
+using Robust.Shared.Timing;
+
+namespace Content.Shared._Arcadis.Computer;
+
+public sealed class ModularComputerSystem : EntitySystem
+{
+ [Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
+
+ [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
+
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+
+ [Dependency] private readonly INetManager _netMan = default!;
+
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+
+ public string BlankDiskPrototype = "UnburnedDiskPrototype";
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(InsertDisk);
+ SubscribeLocalEvent(OnActivate);
+ SubscribeLocalEvent(OnExamined);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ }
+
+ private void OnExamined(EntityUid uid, ModularComputerComponent component, ExaminedEvent args)
+ {
+ if (!TryComp(uid, out ItemSlotsComponent? slots)
+ || !_itemSlots.TryGetSlot(uid, component.DiskSlot, out var diskSlot, slots))
+ return;
+
+ if (diskSlot.Item == null || !TryComp(diskSlot.Item, out ComputerDiskComponent? diskComp))
+ {
+ args.PushMarkup(Loc.GetString("modular-computer-examine-no-disk"));
+ return;
+ }
+
+ if (diskComp.ProgramPrototypeEntity == null)
+ {
+ args.PushMarkup(Loc.GetString("modular-computer-examine-disk-error"));
+ return;
+ }
+
+ args.PushMarkup(Loc.GetString("modular-computer-examine-has-program", ("program", EntityManager.GetComponent(diskComp.ProgramPrototypeEntity.Value).EntityName)));
+ }
+ private void OnActivate(EntityUid uid, ModularComputerComponent component, ActivateInWorldEvent args)
+ {
+ // go figure it out yourself
+ if (!TryComp(uid, out ItemSlotsComponent? slots)
+ || !_itemSlots.TryGetSlot(uid, component.DiskSlot, out var diskSlot, slots))
+ return;
+
+ if (diskSlot.Item == null || !TryComp(diskSlot.Item, out ComputerDiskComponent? diskComp))
+ {
+ _popupSystem.PopupPredicted(Loc.GetString("modular-computer-no-program"), uid, args.User);
+ return;
+ }
+
+ if (diskComp.ProgramPrototypeEntity == null)
+ {
+ _popupSystem.PopupPredicted(Loc.GetString("modular-computer-no-program-on-disk"), uid, args.User);
+ return;
+ }
+
+ if (_gameTiming.IsFirstTimePredicted || _netMan.IsServer) {
+ var activateMsg = new ActivateInWorldEvent(args.User, diskComp.ProgramPrototypeEntity.Value, true);
+ RaiseLocalEvent(diskComp.ProgramPrototypeEntity.Value, activateMsg);
+ }
+ }
+
+ private void InsertDisk(EntityUid uid, ModularComputerComponent component, EntInsertedIntoContainerMessage args)
+ {
+ if (args.Container.ID != component.DiskSlot
+ || !TryComp(uid, out ItemSlotsComponent? slots)
+ || !_itemSlots.TryGetSlot(uid, component.DiskSlot, out var diskSlot, slots)
+ || diskSlot.Item is null
+ || !TryComp(diskSlot.Item, out ComputerDiskComponent? diskComp))
+ return;
+
+ UpdateComputer((uid, component), diskComp, diskSlot);
+
+ if (diskComp.ProgramPrototypeEntity is null
+ || _netMan.IsClient)
+ return;
+
+ _audioSystem.PlayPvs(component.DiskInsertSound, uid, AudioParams.Default.WithVolume(+4f));
+ }
+
+
+ private void UpdateComputer(Entity computer, ComputerDiskComponent diskComp, ItemSlot diskSlot)
+ {
+ if (diskSlot.Item is null
+ || diskComp.ProgramPrototype == BlankDiskPrototype)
+ return;
+
+ EntityUid magicComputerEntity;
+
+ if (diskComp.ProgramPrototypeEntity == null || diskComp.PersistState != true)
+ {
+ if (diskComp.ProgramPrototypeEntity != null)
+ QueueDel(diskComp.ProgramPrototypeEntity.Value);
+
+ magicComputerEntity = Spawn(diskComp.ProgramPrototype, computer.Owner.ToCoordinates());
+ diskComp.ProgramPrototypeEntity = magicComputerEntity;
+ }
+ else
+ magicComputerEntity = diskComp.ProgramPrototypeEntity.Value;
+
+ _transform.SetParent(magicComputerEntity, diskSlot.Item.Value);
+ }
+}
diff --git a/Resources/Audio/_Arcadis/computer_startup.ogg b/Resources/Audio/_Arcadis/computer_startup.ogg
new file mode 100644
index 00000000000..53cfb4c4e57
Binary files /dev/null and b/Resources/Audio/_Arcadis/computer_startup.ogg differ
diff --git a/Resources/Locale/en-US/_Arcadis/modularComputer.ftl b/Resources/Locale/en-US/_Arcadis/modularComputer.ftl
new file mode 100644
index 00000000000..c3c60f3bb84
--- /dev/null
+++ b/Resources/Locale/en-US/_Arcadis/modularComputer.ftl
@@ -0,0 +1,5 @@
+modular-computer-no-program = ERROR: No program loaded!
+modular-computer-no-program-on-disk = ERROR: No program on disk!
+modular-computer-examine-no-disk = This computer doesn't have a program loaded.
+modular-computer-examine-disk-error = This computer doesn't have a program loaded. An error on the display reports that the loaded disk has no program.
+modular-computer-examine-has-program = This computer has the {$program} program loaded.
diff --git a/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/baseComputerModular.yml b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/baseComputerModular.yml
new file mode 100644
index 00000000000..24c2f57d128
--- /dev/null
+++ b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/baseComputerModular.yml
@@ -0,0 +1,19 @@
+- type: entity
+ parent: BaseComputer
+ id: BaseComputerModular
+ name: modular computer
+ description: Part of a recent initiative to make computers less static. Comes with a disk slot for various "program disks".
+ components:
+ - type: ModularComputer
+ # I plan to make modular itemslots a thing in the future for stuff like the fax machine. Coming Soon:tm:
+ - type: ItemSlots
+ slots:
+ modularComputerDiskSlot:
+ name: Disk
+ insertSound:
+ path: /Audio/Machines/terminal_insert_disc.ogg
+ ejectSound:
+ path: /Audio/Machines/terminal_insert_disc.ogg
+
+
+
diff --git a/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDiskPrototypes.yml b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDiskPrototypes.yml
new file mode 100644
index 00000000000..d6df15c1dc2
--- /dev/null
+++ b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDiskPrototypes.yml
@@ -0,0 +1,40 @@
+- type: entity
+ id: UnburnedDiskPrototype
+ name: unburned disk dummy prototype
+ categories: [HideSpawnMenu]
+
+- type: entity
+ id: CrewMonitorDiskPrototype
+ name: Crew Monitor
+ categories: [HideSpawnMenu]
+ components:
+ - type: ActivatableUI
+ key: enum.CrewMonitoringUIKey.Key
+ - type: UserInterface
+ interfaces:
+ enum.CrewMonitoringUIKey.Key:
+ type: CrewMonitoringBoundUserInterface
+ - type: CrewMonitoringConsole
+ - type: DeviceNetwork
+ deviceNetId: Wireless
+ receiveFrequencyId: CrewMonitor
+ - type: WirelessNetworkConnection
+ range: 1200
+
+- type: entity
+ id: CommunicationsConsoleDiskPrototype
+ name: Communications Console
+ categories: [HideSpawnMenu]
+ components:
+ - type: AccessReader
+ access: [["Command"]]
+ - type: CommunicationsConsole
+ title: comms-console-announcement-title-station
+ - type: DeviceNetwork
+ transmitFrequencyId: ShuttleTimer
+ - type: ActivatableUI
+ key: enum.CommunicationsConsoleUiKey.Key
+ - type: UserInterface
+ interfaces:
+ enum.CommunicationsConsoleUiKey.Key:
+ type: CommunicationsConsoleBoundUserInterface
diff --git a/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDisks.yml b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDisks.yml
new file mode 100644
index 00000000000..f742f46dc99
--- /dev/null
+++ b/Resources/Prototypes/_Arcadis/Entities/Objects/Computers/computerDisks.yml
@@ -0,0 +1,40 @@
+- type: entity
+ parent: BaseItem
+ id: BaseProgramDisk
+ abstract: true
+ name: program disk
+ components:
+ - type: Sprite
+ sprite: Objects/Misc/cd.rsi
+ state: icon
+ - type: ComputerDisk
+ saveData: false
+
+- type: entity
+ parent: BaseProgramDisk
+ id: ProgramDiskCrewMonitor
+ name: program disk (crew monitor)
+ description: A diskette for usage in a computer. This one has the "Crew Monitor" program burnt to it.
+ components:
+ - type: ComputerDisk
+ programPrototype: CrewMonitorDiskPrototype
+ persistState: true
+
+- type: entity
+ parent: BaseProgramDisk
+ id: ProgramDiskCommunicationsConsole
+ name: program disk (communications console)
+ description: A diskette for usage in a computer. This one has the "Communications Console" program burnt to it.
+ components:
+ - type: ComputerDisk
+ programPrototype: CommunicationsConsoleDiskPrototype
+ persistState: true
+
+- type: entity
+ parent: BaseProgramDisk
+ id: ProgramDiskUnburnt
+ name: program disk
+ description: A diskette for usage in a computer. This one has no program burnt to it.
+ components:
+ - type: ComputerDisk
+ programPrototype: UnburnedDiskPrototype