diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUi.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUi.cs
new file mode 100644
index 0000000000..a8e12191db
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUi.cs
@@ -0,0 +1,27 @@
+using Content.Client.UserInterface.Fragments;
+using Content.Shared._DEN.CartridgeLoader.Cartridges;
+using Robust.Client.UserInterface;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges;
+
+public sealed partial class NanoChatUi : UIFragment
+{
+ private NanoChatUiFragment? _fragment;
+ public override Control GetUIFragmentRoot()
+ {
+ return _fragment!;
+ }
+
+ public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
+ {
+ _fragment = new();
+ }
+
+ public override void UpdateState(BoundUserInterfaceState state)
+ {
+ if (state is not NanoChatUiState castState)
+ return;
+
+ _fragment?.UpdateState(castState);
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml
new file mode 100644
index 0000000000..462c74c27a
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml.cs
new file mode 100644
index 0000000000..b7a3513c60
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/NanoChatUiFragment.xaml.cs
@@ -0,0 +1,42 @@
+using Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+using Content.Shared._DEN.CartridgeLoader.Cartridges;
+using Content.Shared._DEN.NanoChat;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatUiFragment : BoxContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private Dictionary _conversations = new();
+ private Dictionary _messages = new();
+ private Dictionary _users = new();
+ private Dictionary _messageIdToUi = new();
+ private ISawmill _sawmill;
+
+ public NanoChatUiFragment()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ _sawmill = _logManager.GetSawmill("nanochat.ui");
+ }
+
+ public void UpdateState(NanoChatUiState state)
+ {
+ _conversations = state.Conversations;
+ _messages = state.Messages;
+ _users = state.RelevantUsers;
+
+ ChatsContainer.SetConversations(state.Conversations, state.CurrentConversationId);
+ }
+
+ private void AddMessageEntry(Guid messageId, NanoChatMessageEntry messageEntry)
+ {
+ _messageIdToUi.Add(messageId, messageEntry);
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml
new file mode 100644
index 0000000000..0a331677be
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml.cs
new file mode 100644
index 0000000000..fc3a85f831
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatChatsContainer.xaml.cs
@@ -0,0 +1,44 @@
+using Content.Shared._DEN.NanoChat;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatChatsContainer : BoxContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private readonly ISawmill _sawmill;
+
+ public event Action? OnChatClicked;
+
+ public NanoChatChatsContainer()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ _sawmill = _logManager.GetSawmill("nanochat.ui.chatscontainer");
+ }
+
+ public void SetConversations(Dictionary conversations,
+ Guid? currentConversationId = null)
+ {
+ foreach (var pair in conversations)
+ {
+ BuildConversation(pair.Value, currentConversationId == pair.Key);
+ }
+ }
+
+ private void BuildConversation(NanoChatConversation conversation, bool pressed)
+ {
+ var userEntry = new NanoChatConversationEntry();
+
+ userEntry.SetConversationTitle(conversation.Title);
+ userEntry.SetConversationSubtitle(conversation.Subtitle);
+ userEntry.SetPressed(pressed);
+
+ userEntry.OnConversationClicked += () => OnChatClicked?.Invoke(conversation.Id);
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml
new file mode 100644
index 0000000000..c2b84f1476
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml.cs
new file mode 100644
index 0000000000..1ab626dbc1
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatConversationEntry.xaml.cs
@@ -0,0 +1,45 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatConversationEntry : BoxContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private const string ConversationTitleColor = "#d9d9d9";
+ private ISawmill _sawmill = default!;
+
+ public event Action? OnConversationClicked;
+
+ public NanoChatConversationEntry()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ ConversationButton.OnPressed += _ => OnConversationClicked?.Invoke();
+ _sawmill = _logManager.GetSawmill("nanochat.ui.entry");
+ }
+
+ public void SetConversationTitle(string title)
+ {
+ TitleLabel.Text = $"[color={ConversationTitleColor}][bold]{title}[/bold][/color]";
+ }
+
+ public void SetConversationSubtitle(string subtitle)
+ {
+ SubtitleLabel.Text = $"[color=white][font size=10]{subtitle}[/font][/color]";
+ }
+
+ public void SetPressed(bool pressed)
+ {
+ ConversationButton.Pressed = pressed;
+ }
+
+ public void SetVisible(bool visibility)
+ {
+ Visible = visibility;
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml
new file mode 100644
index 0000000000..d86961c5cc
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml.cs
new file mode 100644
index 0000000000..940c0a676b
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageBox.xaml.cs
@@ -0,0 +1,21 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatMessageBox : PanelContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private ISawmill _sawmill = default!;
+
+ public NanoChatMessageBox()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ _sawmill = _logManager.GetSawmill("nanochat.ui.messagebox");
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml
new file mode 100644
index 0000000000..a93b4705f4
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml.cs
new file mode 100644
index 0000000000..6441d9804b
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatMessageEntry.xaml.cs
@@ -0,0 +1,21 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatMessageEntry : PanelContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private ISawmill _sawmill = default!;
+
+ public NanoChatMessageEntry()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ _sawmill = _logManager.GetSawmill("nanochat.ui.messageentry");
+ }
+}
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml
new file mode 100644
index 0000000000..c5636aaab6
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml.cs b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml.cs
new file mode 100644
index 0000000000..443a30513c
--- /dev/null
+++ b/Content.Client/_DEN/CartridgeLoader/Cartridges/Widgets/NanoChatTopBar.xaml.cs
@@ -0,0 +1,21 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client._DEN.CartridgeLoader.Cartridges.Widgets;
+
+[GenerateTypedNameReferences]
+public sealed partial class NanoChatTopBar : BoxContainer
+{
+ [Dependency] private readonly ILogManager _logManager = default!;
+
+ private ISawmill _sawmill = default!;
+
+ public NanoChatTopBar()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+
+ _sawmill = _logManager.GetSawmill("nanochat.ui.topbar");
+ }
+}
diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj
index e2b65b873c..28a7301563 100644
--- a/Content.Server/Content.Server.csproj
+++ b/Content.Server/Content.Server.csproj
@@ -27,5 +27,8 @@
+
+
+
diff --git a/Content.Shared/Access/Systems/SharedIdCardSystem.cs b/Content.Shared/Access/Systems/SharedIdCardSystem.cs
index 513abb20ee..4ead643c3e 100644
--- a/Content.Shared/Access/Systems/SharedIdCardSystem.cs
+++ b/Content.Shared/Access/Systems/SharedIdCardSystem.cs
@@ -1,4 +1,5 @@
using System.Globalization;
+using Content.Shared._DEN.Access.Systems;
using Content.Shared.Access.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.CCVar;
@@ -155,6 +156,11 @@ public bool TryChangeJobTitle(EntityUid uid, string? jobTitle, IdCardComponent?
Dirty(uid, id);
UpdateEntityName(uid, id);
+ // Start DEN: raise an event on ID card updating
+ var ev = new IdCardJobTitleUpdatedEvent(jobTitle);
+ RaiseLocalEvent(ev);
+ // End DEN
+
if (player != null)
{
_adminLogger.Add(LogType.Identity, LogImpact.Low,
@@ -249,6 +255,11 @@ public bool TryChangeFullName(EntityUid uid, string? fullName, IdCardComponent?
Dirty(uid, id);
UpdateEntityName(uid, id);
+ // Start DEN: raise an event on ID card updating
+ var ev = new IdCardNameUpdatedEvent(fullName);
+ RaiseLocalEvent(ev);
+ // End DEN
+
if (player != null)
{
_adminLogger.Add(LogType.Identity, LogImpact.Low,
diff --git a/Content.Shared/_DEN/Access/Systems/IdCardUpdatedEvent.cs b/Content.Shared/_DEN/Access/Systems/IdCardUpdatedEvent.cs
new file mode 100644
index 0000000000..79579e336c
--- /dev/null
+++ b/Content.Shared/_DEN/Access/Systems/IdCardUpdatedEvent.cs
@@ -0,0 +1,11 @@
+namespace Content.Shared._DEN.Access.Systems;
+
+public sealed class IdCardNameUpdatedEvent(string? newName) : EntityEventArgs
+{
+ public string? NewName { get; set; } = newName;
+}
+
+public sealed class IdCardJobTitleUpdatedEvent(string? newJobTitle) : EntityEventArgs
+{
+ public string? NewJobTitle { get; set; } = newJobTitle;
+}
diff --git a/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCardComponent.cs b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCardComponent.cs
new file mode 100644
index 0000000000..b096dbccf9
--- /dev/null
+++ b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCardComponent.cs
@@ -0,0 +1,16 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DEN.CartridgeLoader.Cartridges;
+
+[RegisterComponent]
+public sealed partial class NanoChatCardComponent : Component
+{
+ [ViewVariables]
+ public EntityUid? LoaderUid { get; set; }
+
+ [ViewVariables]
+ public uint? PersonalNumber { get; set; }
+
+ [DataField]
+ public bool ListNumber { get; set; } = true;
+}
diff --git a/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCartridgeComponent.cs b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCartridgeComponent.cs
new file mode 100644
index 0000000000..c3bb5b5175
--- /dev/null
+++ b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatCartridgeComponent.cs
@@ -0,0 +1,14 @@
+using Content.Shared.Radio;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared._DEN.CartridgeLoader.Cartridges;
+
+[RegisterComponent]
+public sealed partial class NanoChatCartridgeComponent : Component
+{
+ [DataField]
+ public EntityUid? Card;
+
+ [DataField]
+ public ProtoId RadioChannel = "Common";
+}
diff --git a/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiMessageEvents.cs b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiMessageEvents.cs
new file mode 100644
index 0000000000..36d1105fc2
--- /dev/null
+++ b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiMessageEvents.cs
@@ -0,0 +1,72 @@
+using Content.Shared._DEN.NanoChat;
+using Content.Shared.CartridgeLoader;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DEN.CartridgeLoader.Cartridges;
+
+public interface INanoChatUiMessageEvent;
+
+[Serializable, NetSerializable]
+public sealed class NanoChatUiMessageEvent(INanoChatUiMessageEvent payload) : CartridgeMessageEvent
+{
+ public readonly INanoChatUiMessageEvent Payload = payload;
+}
+
+///
+/// An event called by trying to create a group chat or message someone new.
+///
+/// The members in the conversation.
+[Serializable, NetSerializable]
+public sealed class NanoChatUiConversationCreatedEvent(HashSet members) : INanoChatUiMessageEvent
+{
+ [ViewVariables]
+ public HashSet Members = members;
+}
+
+[Serializable, NetSerializable]
+public sealed class NanoChatUiMessageSentEvent(
+ Guid conversationId,
+ NanoChatMessageType messageType,
+ TimeSpan sentAt,
+ string content) : INanoChatUiMessageEvent
+{
+ [ViewVariables]
+ public Guid ConversationId = conversationId;
+
+ [ViewVariables]
+ public NanoChatMessageType MessageType = messageType;
+
+ [ViewVariables]
+ public TimeSpan SentAt = sentAt;
+
+ [ViewVariables]
+ public string Content = content;
+}
+
+[Serializable, NetSerializable]
+public sealed class NanoChatUiMessageEditedEvent(
+ Guid messageId,
+ string newContent) : INanoChatUiMessageEvent
+{
+ [ViewVariables]
+ public Guid MessageId = messageId;
+
+ [ViewVariables]
+ public string NewContent = newContent;
+}
+
+[Serializable, NetSerializable]
+public sealed class NanoChatUiMessageDeletedEvent(
+ Guid messageId) : INanoChatUiMessageEvent
+{
+ [ViewVariables]
+ public Guid MessageId = messageId;
+}
+
+[Serializable, NetSerializable]
+public sealed class NanoChatUiSetCurrentConversationEvent(
+ Guid? conversationId) : INanoChatUiMessageEvent
+{
+ [ViewVariables]
+ public Guid? ConversationId = conversationId;
+}
diff --git a/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiState.cs b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiState.cs
new file mode 100644
index 0000000000..0ec100ce73
--- /dev/null
+++ b/Content.Shared/_DEN/CartridgeLoader/Cartridges/NanoChatUiState.cs
@@ -0,0 +1,14 @@
+using Content.Shared._DEN.NanoChat;
+
+namespace Content.Shared._DEN.CartridgeLoader.Cartridges;
+
+public sealed class NanoChatUiState : BoundUserInterfaceState
+{
+ public uint PersonalNumber;
+ public Guid? CurrentConversationId;
+
+ public HashSet UnreadMessages = new();
+ public Dictionary Conversations = new();
+ public Dictionary RelevantUsers = new();
+ public Dictionary Messages = new();
+}
diff --git a/Content.Shared/_DEN/NanoChat/NanoChat.cs b/Content.Shared/_DEN/NanoChat/NanoChat.cs
new file mode 100644
index 0000000000..37b3b508fa
--- /dev/null
+++ b/Content.Shared/_DEN/NanoChat/NanoChat.cs
@@ -0,0 +1,70 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DEN.NanoChat;
+
+[Serializable, NetSerializable]
+public record struct NanoChatConversation(
+ Guid Id,
+ string Title,
+ string Subtitle,
+ NanoChatConversationFlags Flags,
+ HashSet Members,
+ HashSet Messages,
+ NanoChatConversationType ConversationType)
+{
+ public Guid Id { get; init; } = Id;
+ public string Title { get; init; } = Title;
+ public string Subtitle { get; init; } = Subtitle;
+ public NanoChatConversationFlags Flags { get; init; } = Flags;
+ public HashSet Members { get; init; } = Members;
+ public HashSet Messages { get; init; } = Messages;
+}
+
+[Serializable, NetSerializable]
+public record struct NanoChatUser(uint Id, string LastRecordedName, string LastRecordedJobTitle)
+{
+ public uint Id { get; init; } = Id;
+ public string LastRecordedName { get; init; } = LastRecordedName;
+ public string LastRecordedJobTitle { get; init; } = LastRecordedJobTitle;
+}
+
+[Serializable, NetSerializable]
+public record struct NanoChatMessage(
+ Guid MessageId,
+ uint Sender,
+ Guid ConversationId,
+ NanoChatMessageFlags Flags,
+ NanoChatMessageType MessageType,
+ HashSet SeenByUsers,
+ TimeSpan SentAt,
+ string Content);
+
+public enum NanoChatConversationFlags
+{
+ None = 0,
+ Silenced = 1 << 0
+}
+
+public enum NanoChatMessageFlags
+{
+ None = 0,
+ FailedToSend = 1 << 0
+}
+
+public enum NanoChatUserFlags
+{
+ None = 0,
+ Silenced = 1 << 0
+}
+
+public enum NanoChatMessageType
+{
+ Embed,
+ Text
+}
+
+public enum NanoChatConversationType
+{
+ DirectMessage,
+ GroupChat
+}
diff --git a/Resources/Locale/en-US/_DEN/nanochat/nanochat.ftl b/Resources/Locale/en-US/_DEN/nanochat/nanochat.ftl
new file mode 100644
index 0000000000..6bca67688c
--- /dev/null
+++ b/Resources/Locale/en-US/_DEN/nanochat/nanochat.ftl
@@ -0,0 +1,2 @@
+nanochat-card-examine-no-number = This card has no number.
+nanochat-card-examine-has-number = Number: [color=white]{$number}[/color]
\ No newline at end of file
diff --git a/Resources/Prototypes/_DEN/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/_DEN/Entities/Objects/Devices/cartridges.yml
new file mode 100644
index 0000000000..af52410a6d
--- /dev/null
+++ b/Resources/Prototypes/_DEN/Entities/Objects/Devices/cartridges.yml
@@ -0,0 +1,17 @@
+- type: entity
+ parent: BaseItem
+ id: NanoChatCartridge
+ name: NanoChat cartridge
+ description: A social program for your PDA.
+ components:
+ - type: Sprite
+ sprite: Objects/Devices/cartridge.rsi
+ state: cart-nav
+ - type: Cartridge
+ programName: nano-task-program-name
+ icon:
+ sprite: Interface/Misc/program_icons.rsi
+ state: nano_task
+ - type: UIFragment
+ ui: !type:NanoChatUi
+ - type: NanoChatCartridge
\ No newline at end of file
diff --git a/Resources/Prototypes/_DEN/name_identifier_groups.yml b/Resources/Prototypes/_DEN/name_identifier_groups.yml
new file mode 100644
index 0000000000..81a83990de
--- /dev/null
+++ b/Resources/Prototypes/_DEN/name_identifier_groups.yml
@@ -0,0 +1,3 @@
+- type: nameIdentifierGroup
+ id: NanoChatIds
+ maxValue: 9999
\ No newline at end of file