diff --git a/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerComponent.cs b/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerComponent.cs
new file mode 100644
index 0000000000..ccaa681dce
--- /dev/null
+++ b/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerComponent.cs
@@ -0,0 +1,21 @@
+using Content.Shared.Procedural;
+using Content.Shared.Random;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server._CP14.Procedural.RoomSpawner;
+
+///
+///
+///
+[RegisterComponent, Access(typeof(CP14RoomSpawnerSystem))]
+public sealed partial class CP14RoomSpawnerComponent : Component
+{
+ [DataField(required: true)]
+ public ProtoId RoomsRandom = new();
+
+ [DataField]
+ public bool Rotation = true;
+
+ [DataField]
+ public bool ClearExisting = true;
+}
diff --git a/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerSystem.cs b/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerSystem.cs
new file mode 100644
index 0000000000..ecf272a641
--- /dev/null
+++ b/Content.Server/_CP14/Procedural/RoomSpawner/CP14RoomSpawnerSystem.cs
@@ -0,0 +1,53 @@
+using Content.Server.Procedural;
+using Content.Shared.Procedural;
+using Content.Shared.Random.Helpers;
+using Robust.Server.GameObjects;
+using Robust.Shared.Map.Components;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Server._CP14.Procedural.RoomSpawner;
+
+public sealed class CP14RoomSpawnerSystem : EntitySystem
+{
+ [Dependency] private readonly IPrototypeManager _proto = default!;
+ [Dependency] private readonly DungeonSystem _dungeon = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly TransformSystem _transform = default!;
+ [Dependency] private readonly SharedMapSystem _maps = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnMapInit);
+ }
+
+ private void OnMapInit(Entity spawner, ref MapInitEvent args)
+ {
+ if (!_proto.TryIndex(spawner.Comp.RoomsRandom, out var rooms))
+ return;
+
+ var roomProto = rooms.Pick(_random);
+
+ if (!_proto.TryIndex(roomProto, out var room))
+ return;
+
+ var gridUid = Transform(spawner).GridUid;
+
+ if (!TryComp(gridUid, out var gridComp))
+ return;
+
+ var random = new Random();
+
+ _dungeon.SpawnRoom(
+ gridUid.Value,
+ gridComp,
+ _maps.LocalToTile(gridUid.Value, gridComp, Transform(spawner).Coordinates),
+ room,
+ random,
+ null,
+ spawner.Comp.ClearExisting,
+ spawner.Comp.Rotation);
+ }
+}
diff --git a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Rooms/test.yml b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Rooms/test.yml
new file mode 100644
index 0000000000..3f571ff1a7
--- /dev/null
+++ b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Rooms/test.yml
@@ -0,0 +1,27 @@
+- type: weightedRandom
+ id: CP14RoomSpawnerCaelid
+ weights:
+ LavaBrig17x5a: 1
+ LavaBrig17x5b: 1
+ LavaBrig7x7a: 1
+ LavaBrig7x7b: 1
+ LavaBrig7x7c: 1
+ LavaBrig7x7d: 1
+ LavaBrig11x5a: 1
+
+- type: entity
+ id: CP14BaseRoomSpawner
+ name: room spawner
+ parent: MarkerBase
+ placement:
+ mode: SnapgridCenter
+ components:
+ - type: Transform
+ anchored: true
+ - type: Clickable
+ - type: InteractionOutline
+ - type: Sprite
+ layers:
+ - state: green
+ - type: CP14RoomSpawner
+ roomsRandom: CP14RoomSpawnerCaelid
\ No newline at end of file