diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi.meta
new file mode 100644
index 00000000..df632aea
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4094856a5db24f142a14fda03f1215a2
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs
new file mode 100644
index 00000000..648bbd62
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs
@@ -0,0 +1,39 @@
+#if UNITY_SWITCH
+using nn.account;
+#endif
+
+public class AxiNS
+{
+	static AxiNS _instance;
+	public static AxiNS instance
+	{
+		get
+		{
+			if (_instance == null)
+				_instance = new AxiNS();
+			return _instance;
+		}
+	}
+
+	public AxiNSUser user;
+	public AxiNSMount mount;
+	public AxiNSIO io;
+	AxiNS()
+	{
+		user = new AxiNSUser();
+		mount = new AxiNSMount();
+		io = new AxiNSIO();
+	}
+
+	/// <summary>
+	/// ��ʼ�����������Ŀ��һʱ���ʼ������֤�ȳ�ʼ����ʹ��ijЩ�������Ų����ˣ�
+	/// </summary>
+	public void Init()
+	{
+#if UNITY_SWITCH
+		if (!user.GetUserID(out Uid uid))
+			return;
+		mount.MountSave(uid);
+#endif
+	}
+}
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs.meta
new file mode 100644
index 00000000..4b945141
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNS.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 52541c757d45c4c488726bcc39f73ba6
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs
new file mode 100644
index 00000000..b4c4af29
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs
@@ -0,0 +1,367 @@
+public static class AxiNSErrCode
+{
+#if UNITY_SWITCH
+	public static string GetErrorInfo(this nn.Result result)
+	{
+		if (result.IsSuccess())
+			return "NoErr";
+		return GetErrorDetails(result.GetModule(), result.GetDescription());
+	}
+#endif
+	/// <summary>
+	/// ����ģ�� ID ������ ID ���������� Switch ������ĺ��塢����ԭ�򼰽���취��
+	/// </summary>
+	/// <param name="moduleId">� ID</param>
+	/// <param name="descriptionId">���� ID</param>
+	/// <returns>���������롢���塢����ԭ�򼰽���취���ַ���</returns>
+	public static string GetErrorDetails(int moduleId, int descriptionId)
+	{
+		string errorCode = $"2{moduleId:D3}-{descriptionId:D4}"; // ��ʽ��Ϊ 2XXX-YYYY
+		string meaning = "δ֪����";
+		string causeAndSolution = "δ֪����������־����ϵ������֧�֡�";
+
+		switch (moduleId)
+		{
+			case 2: // nn::fs (�ļ�ϵͳ)
+				switch (descriptionId)
+				{
+					case 1:
+						meaning = "ResultPathNotFound";
+						causeAndSolution = "·��δ�ҵ������·���Ƿ���ȷ��ȷ����Ŀ¼���ڡ�ʹ�� nn.fs.Directory.Create ������Ŀ¼��";
+						break;
+					case 2:
+						meaning = "ResultPermissionDenied";
+						causeAndSolution = "Ȩ�ޱ��ܾ��������� Atmosphere ������ save:/ ��дȨ�ޡ����Ե��� Atmosphere ���û�ʹ�� sd:/ ���ص㡣";
+						break;
+					case 3:
+						meaning = "ResultPathAlreadyExists";
+						causeAndSolution = "·���Ѵ��ڡ����·���Ƿ�ռ�ã�ɾ���������������ļ�/Ŀ¼��";
+						break;
+					case 5:
+						meaning = "ResultTargetLocked";
+						causeAndSolution = "Ŀ�걻�������������ļ�����ʹ���У��ر���س�������ԡ�";
+						break;
+					case 7:
+						meaning = "ResultTargetNotFound";
+						causeAndSolution = "Ŀ��δ�ҵ���ȷ��Ŀ���ļ�/Ŀ¼�Ƿ���ڣ����·��ƴд��";
+						break;
+				}
+				break;
+
+			case 5: // nn::err (������)
+				switch (descriptionId)
+				{
+					case 3:
+						meaning = "microSD ����ش���";
+						causeAndSolution = "�޷����������������� microSD ���𻵡��Ƴ� microSD �������²��룬���������";
+						break;
+				}
+				break;
+
+			case 16: // nn::oe (����ϵͳ����)
+				switch (descriptionId)
+				{
+					case 247:
+						meaning = "microSD ���洢����";
+						causeAndSolution = "microSD ���𻵻򲻼��ݡ����� microSD ������Ĭ�ϴ洢λ������Ϊϵͳ�ڴ档";
+						break;
+					case 390:
+						meaning = "��֧�ֵ� microSD ��";
+						causeAndSolution = "microSD ����ʽ����֧�֡���ʽ��Ϊ exFAT �� FAT32 �����ԡ�";
+						break;
+					case 601:
+						meaning = "microSD ��������";
+						causeAndSolution = "microSD �������𻵡��������ݺ��ʽ������������¿���";
+						break;
+				}
+				break;
+
+			case 21: // nn::settings (����)
+				switch (descriptionId)
+				{
+					case 3:
+						meaning = "ϵͳ����δ���»���";
+						causeAndSolution = "ϵͳ�̼��汾���ɻ��𻵡�����ϵͳ�̼��������°�װϵͳ��";
+						break;
+				}
+				break;
+
+			case 101: // nn::fssrv (�ļ�ϵͳ����)
+				switch (descriptionId)
+				{
+					case 1:
+						meaning = "ϵͳ����";
+						causeAndSolution = "ͨ��ϵͳ�������� Switch���������������ϵ������֧�֡�";
+						break;
+					case 2:
+						meaning = "�̼���";
+						causeAndSolution = "ϵͳ�̼��𻵡����Ը���ϵͳ����ָ��������ã�ע�ⱸ�����ݣ���";
+						break;
+				}
+				break;
+
+			case 107: // nn::nim (���簲װ����)
+				switch (descriptionId)
+				{
+					case 427:
+						meaning = "�̼���";
+						causeAndSolution = "ϵͳ�̼��𻵡�����ϵͳ�̼��������°�װϵͳ��";
+						break;
+					case 445:
+						meaning = "Ӳ���𻵻��������";
+						causeAndSolution = "������Ӳ���𻵻���ڵ������ݡ�ɾ���������ݣ����� Switch������Ч��ϵ������֧�֡�";
+						break;
+				}
+				break;
+
+			case 110: // nn::socket (�����׽���)
+				switch (descriptionId)
+				{
+					case 1000:
+						meaning = "��������ʧ��";
+						causeAndSolution = "�޷����ӵ����硣����������ӣ�����·�����������л�����������Ƶ�Σ�2.4GHz/5GHz����";
+						break;
+					case 2003:
+						meaning = "������������ʧ��";
+						causeAndSolution = "�����ź������ȶ�������·�������Ƴ������������·������";
+						break;
+					case 2004:
+						meaning = "�������ò�֧��";
+						causeAndSolution = "���簲ȫ���Ͳ���֧�֡�Switch ֧�� WEP/WPA/WPA2������·�������ú����ԡ�";
+						break;
+					case 2091:
+						meaning = "������������ʧ��";
+						causeAndSolution = "�����������⡣��������Ƿ��ã����� Switch ��·������";
+						break;
+					case 3127:
+						meaning = "��������ʧ��";
+						causeAndSolution = "���粻�ȶ��������������ӣ�����·����������ϵ�����ṩ�̡�";
+						break;
+				}
+				break;
+
+			case 115: // nn::mii (Mii ���)
+				switch (descriptionId)
+				{
+					case 96:
+						meaning = "Mii ���ݴ���";
+						causeAndSolution = "Mii �����𻵡�ɾ�������´��� Mii�������ϵͳ��";
+						break;
+				}
+				break;
+
+			case 139: // nn::nfp (NFC/Amiibo)
+				switch (descriptionId)
+				{
+					case 6:
+						meaning = "Amiibo ��ȡ����";
+						causeAndSolution = "Amiibo ��ȡʧ�ܡ���� Amiibo �Ƿ��𻵣�����ϵͳ���������� Amiibo��";
+						break;
+				}
+				break;
+
+			case 153: // nn::ir (��������ͷ)
+				switch (descriptionId)
+				{
+					case 321:
+						meaning = "��������ͷ��ȡ����";
+						causeAndSolution = "��������ͷ�޷���ȡ���������ͷ�Ƿ��ڵ�����ྵͷ������ϵ������֧�֡�";
+						break;
+					case 1540:
+						meaning = "��������ͷӲ������";
+						causeAndSolution = "��������ͷӲ�����ϡ���ϵ������֧�ֽ���ά�ޡ�";
+						break;
+				}
+				break;
+
+			case 155: // nn::account (�˻�����)
+				switch (descriptionId)
+				{
+					case 8006:
+						meaning = "�޷������������˻�";
+						causeAndSolution = "�������������жϡ�����������ӣ��Ժ����ԣ���鿴����������״̬ҳ�档";
+						break;
+				}
+				break;
+
+			case 160: // nn::online (���߷���)
+				switch (descriptionId)
+				{
+					case 103:
+						meaning = "�޷���������ƥ��";
+						causeAndSolution = "���粻�ȶ������� Switch������������ӣ����Ժ����ԡ�";
+						break;
+					case 202:
+						meaning = "�޷����ӵ����߷���";
+						causeAndSolution = "�����������ά�����鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+					case 8006:
+						meaning = "���Ӳ���ʧ��";
+						causeAndSolution = "�������⡣����·����������������ã������������硣";
+						break;
+				}
+				break;
+
+			case 162: // nn::application (Ӧ�ó���)
+				switch (descriptionId)
+				{
+					case 2:
+						meaning = "��������";
+						causeAndSolution = "���������������ǵ������ݻ�̼����⡣ɾ���������ݣ�����ϵͳ�������°�װ������";
+						break;
+					case 101:
+						meaning = "������Ҫ����";
+						causeAndSolution = "��Ϸ��������Ҫ���¡�����������²���װ��";
+						break;
+				}
+				break;
+
+			case 168: // nn::sys (ϵͳ)
+				switch (descriptionId)
+				{
+					case 0:
+						meaning = "��Ҫ��������";
+						causeAndSolution = "������Ҫ���¡�������Ϸ��ϵͳ�̼���";
+						break;
+					case 2:
+						meaning = "ϵͳ����";
+						causeAndSolution = "ϵͳ������������Ӳ�����⡣���� Switch������Ч��ϵ������֧�֡�";
+						break;
+				}
+				break;
+
+			case 205: // nn::camera (����ͷ)
+				switch (descriptionId)
+				{
+					case 123:
+						meaning = "����ͷ��ȡ����";
+						causeAndSolution = "����ͷ�޷���ȡ���������ͷ�Ƿ��ڵ�����ྵͷ������ϵ������֧�֡�";
+						break;
+				}
+				break;
+
+			case 306: // nn::ngc (������Ϸ����)
+				switch (descriptionId)
+				{
+					case 501:
+						meaning = "�޷���������ƥ��";
+						causeAndSolution = "���������жϡ����� Switch������������ӣ����Ժ����ԡ�";
+						break;
+					case 502:
+						meaning = "ƥ�����ʧ��";
+						causeAndSolution = "���粻�ȶ��������������ӣ�����·����������ϵ�����ṩ�̡�";
+						break;
+					case 820:
+						meaning = "���߷��񲻿���";
+						causeAndSolution = "�����������ά�����鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 613: // nn::eShop (eShop)
+				switch (descriptionId)
+				{
+					case 1400:
+						meaning = "�޷�ʹ�����ÿ�����";
+						causeAndSolution = "���ÿ���Ϣ����� eShop �������⡣������ÿ���Ϣ���Ժ����ԣ�����ϵ������֧�֡�";
+						break;
+					case 6838:
+						meaning = "eShop ����ʧ��";
+						causeAndSolution = "��������� eShop ά��������������ӣ��鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 618: // nn::ngc (������Ϸ����)
+				switch (descriptionId)
+				{
+					case 6:
+						meaning = "�޷���������ƥ��";
+						causeAndSolution = "���粻�ȶ������� Switch������������ӣ����Ժ����ԡ�";
+						break;
+					case 201:
+						meaning = "ƥ������";
+						causeAndSolution = "���Լ����ƥ���������Ժ����ԣ����������ƥ�䡣";
+						break;
+					case 501:
+						meaning = "ƥ�����ʧ��";
+						causeAndSolution = "���������жϡ����� Switch������������ӣ����Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 801: // nn::sns (�罻�������)
+				switch (descriptionId)
+				{
+					case 7002:
+						meaning = "�޷��ϴ���ͼ�� Twitter";
+						causeAndSolution = "�����������ά�����鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+					case 7199:
+						meaning = "�޷��ϴ���Ƭ�� Facebook";
+						causeAndSolution = "�����������ά�����鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 810: // nn::account (�˻�����)
+				switch (descriptionId)
+				{
+					case 1224:
+						meaning = "�޷���¼�������˻�";
+						causeAndSolution = "�������������жϡ�����������ӣ��Ժ����ԣ���鿴����������״̬ҳ�档";
+						break;
+					case 1500:
+						meaning = "�޷���¼ Facebook �˻�";
+						causeAndSolution = "�����������ά�������� Switch���Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 811: // nn::account (�˻�����)
+				switch (descriptionId)
+				{
+					case 1006:
+						meaning = "�޷������������˻�";
+						causeAndSolution = "��������� DNS ���󡣼���������ӣ����Ը��� DNS���� 8.8.8.8�������Ժ����ԡ�";
+						break;
+					case 5001:
+						meaning = "�޷����� eShop";
+						causeAndSolution = "eShop �����жϡ��鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+				}
+				break;
+
+			case 813: // nn::eShop (eShop)
+				switch (descriptionId)
+				{
+					case 0:
+						meaning = "eShop ����ʧ��";
+						causeAndSolution = "eShop �����жϡ��鿴����������״̬ҳ�棬�Ժ����ԡ�";
+						break;
+					case 2470:
+						meaning = "���״���ʧ��";
+						causeAndSolution = "���ÿ���Ϣ����� eShop �������⡣������ÿ���Ϣ���Ժ����ԣ�����ϵ������֧�֡�";
+						break;
+				}
+				break;
+
+			case 819: // nn::online (���߷���)
+				switch (descriptionId)
+				{
+					case 3:
+						meaning = "��������ͣ";
+						causeAndSolution = "ͬһ�˻�����һ̨�豸��ʹ�á��ر������豸�ϵ���������ʹ�ò�ͬ�˻���";
+						break;
+				}
+				break;
+
+			default:
+				meaning = "δ֪ģ��";
+				causeAndSolution = "δʶ���ģ�� ID��������־����ϵ������֧�֡�";
+				break;
+		}
+
+		return $"������: {errorCode}\n����: {meaning}\n����ԭ�򼰽���취: {causeAndSolution}";
+	}
+}
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs.meta
new file mode 100644
index 00000000..d734ad71
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSErrCode.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0e28b69692cb1bb4a9d8ddb91274fa50
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs
new file mode 100644
index 00000000..8edbe405
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs
@@ -0,0 +1,394 @@
+#if UNITY_SWITCH
+using nn.fs;
+#endif
+
+public class AxiNSIO
+{
+    string save_name => AxiNS.instance.mount.SaveMountName;
+    public string save_path => $"{save_name}:/";
+#if UNITY_SWITCH
+	private FileHandle fileHandle = new nn.fs.FileHandle();
+#endif
+    /// <summary>
+    /// ���Path�Ƿ����
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <returns></returns>
+    public bool CheckPathExists(string filePath)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+        nn.fs.EntryType entryType = 0;
+		nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath);
+		//result.abortUnlessSuccess();
+		//����쳣������ı�Ť
+		return nn.fs.FileSystem.ResultPathAlreadyExists.Includes(result);
+#endif
+    }
+    /// <summary>
+    /// ���Path�Ƿ񲻴���
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <returns></returns>
+    public bool CheckPathNotFound(string filePath)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+        nn.fs.EntryType entryType = 0;
+		nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath);
+		//����쳣������ı�Ť
+		return nn.fs.FileSystem.ResultPathNotFound.Includes(result);
+#endif
+    }
+    /// <summary>
+    /// ����Ŀ¼��Ŀ¼����Ҳ�᷵��true
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <returns></returns>
+    public bool CreateDir(string filePath)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+        // ʹ�÷�װ�������ʹ�����Ŀ¼
+        if (!EnsureParentDirectory(filePath, true))
+        {
+            UnityEngine.Debug.LogError($"�޷�ȷ����Ŀ¼���ļ�д��ȡ��: {filePath}");
+            return false;
+        }
+		return true;
+#endif
+    }
+    /// <summary>
+    /// ���沢�����ļ������Ŀ¼�����ڻ����Զ�����Ŀ¼��
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <param name="bw"></param>
+    /// <returns></returns>
+    public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms)
+    {
+        return FileToSaveWithCreate(filePath, ms.ToArray());
+    }
+    /// <summary>
+    /// ���沢�����ļ������Ŀ¼�����ڻ����Զ�����Ŀ¼��
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <param name="data"></param>
+    /// <returns></returns>
+    public bool FileToSaveWithCreate(string filePath, byte[] data)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+		if (!AxiNS.instance.mount.SaveIsMount)
+		{
+			UnityEngine.Debug.LogError($"Save ��δ���أ��޷��洢 {filePath}");
+			return false;
+		}
+
+		nn.Result result;
+#if UNITY_SWITCH && !UNITY_EDITOR
+        // ��ֹ�û��ڱ���ʱ���˳���Ϸ
+        // Switch ���� 0080
+        UnityEngine.Switch.Notification.EnterExitRequestHandlingSection();
+#endif
+		// ʹ�÷�װ�������ʹ�����Ŀ¼
+		if (!EnsureParentDirectory(filePath, true))
+		{
+			UnityEngine.Debug.LogError($"�޷�ȷ����Ŀ¼���ļ�д��ȡ��: {filePath}");
+			return false;
+		}
+
+		//string directoryPath = System.IO.Path.GetDirectoryName(filePath.Replace(save_path, ""));
+		//string fullDirectoryPath = $"{save_path}{directoryPath}";
+		//UnityEngine.Debug.Log($"��鸸Ŀ¼: {fullDirectoryPath}");
+
+		//nn.fs.EntryType entryType = 0;
+		//result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath);
+		//if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result))
+		//{
+		//	UnityEngine.Debug.Log($"��Ŀ¼ {fullDirectoryPath} �����ڣ����Դ��� (�ж����� result=>{result.ToString()})");
+		//	result = nn.fs.Directory.Create(fullDirectoryPath);
+		//	if (!result.IsSuccess())
+		//	{
+		//		UnityEngine.Debug.LogError($"������Ŀ¼ʧ��: {result.GetErrorInfo()}");
+		//		return false;
+		//	}
+		//	UnityEngine.Debug.Log($"��Ŀ¼ {fullDirectoryPath} �����ɹ�");
+		//}
+		//else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory)
+		//{
+		//	UnityEngine.Debug.LogError($"·�� {fullDirectoryPath} �Ѵ��ڣ�������Ŀ¼");
+		//	return false;
+		//}
+		//else if (!result.IsSuccess())
+		//{
+		//	UnityEngine.Debug.LogError($"��鸸Ŀ¼ʧ��: {result.GetErrorInfo()}");
+		//	return false;
+		//}
+
+		if (CheckPathNotFound(filePath))
+		{
+			UnityEngine.Debug.Log($"�ļ�({filePath})��������Ҫ����");
+			result = nn.fs.File.Create(filePath, data.Length); //this makes a file the size of your save journal. You may want to make a file smaller than this.
+															   //result.abortUnlessSuccess();
+			if (!result.IsSuccess())
+			{
+				UnityEngine.Debug.LogError($"�����ļ�ʧ�� {filePath} : " + result.GetErrorInfo());
+				return false;
+			}
+		}
+		else
+			UnityEngine.Debug.Log($"�ļ�({filePath})���ڣ����ش���");
+
+		result = File.Open(ref fileHandle, filePath, OpenFileMode.Write);
+		//result.abortUnlessSuccess();
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError($"ʧ�� File.Open(ref filehandle, {filePath}, OpenFileMode.Write): " + result.GetErrorInfo());
+			return false;
+		}
+		UnityEngine.Debug.Log($"�ɹ� File.Open(ref filehandle, {filePath}, OpenFileMode.Write)");
+
+		//nn.fs.WriteOption.Flush Ӧ�þ��Ǹ���д��
+		result = nn.fs.File.Write(fileHandle, 0, data, data.Length, nn.fs.WriteOption.Flush); // Writes and flushes the write at the same time
+																							  //result.abortUnlessSuccess();
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError("д���ļ�ʧ��: " + result.GetErrorInfo());
+			return false;
+		}
+		UnityEngine.Debug.Log("д���ļ��ɹ�: " + filePath);
+
+		nn.fs.File.Close(fileHandle);
+
+		//������ύ������û����ʵд��
+		result = FileSystem.Commit(save_name);
+		//result.abortUnlessSuccess();
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) ʧ��: " + result.GetErrorInfo());
+			return false;
+		}
+		UnityEngine.Debug.Log($"FileSystem.Commit({save_name}) �ɹ�: ");
+
+
+#if UNITY_SWITCH && !UNITY_EDITOR
+        // ֹͣ��ֹ�û��˳���Ϸ
+        UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection();
+#endif
+
+		return true;
+#endif
+    }
+    /// <summary>
+    /// ���沢�����ļ������Ŀ¼�����ڻ����Զ�����Ŀ¼��
+    /// </summary>
+    /// <param name="filePath"></param>
+    /// <param name="bw"></param>
+    /// <returns></returns>
+    public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms)
+    {
+        if (LoadSwitchDataFile(filename, out byte[] outputData))
+        {
+            System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms);
+            writer.Write(outputData);
+			return true;
+        }
+		return false;
+    }
+    public bool LoadSwitchDataFile(string filename, out byte[] outputData)
+    {
+#if !UNITY_SWITCH
+        outputData = null;
+        return false;
+#else
+		outputData = null;
+		if (!AxiNS.instance.mount.SaveIsMount)
+		{
+			UnityEngine.Debug.LogError($"Save ��δ���أ��޷���ȡ {filename}");
+			return false;
+		}
+		if (CheckPathNotFound(filename))
+			return false;
+
+		nn.Result result;
+		result = nn.fs.File.Open(ref fileHandle, filename, nn.fs.OpenFileMode.Read);
+		if (result.IsSuccess() == false)
+		{
+			UnityEngine.Debug.LogError($"nn.fs.File.Open ʧ�� {filename} : result=>{result.GetErrorInfo()}");
+			return false;   // Could not open file. This can be used to detect if this is the first time a user has launched your game. 
+							// (However, be sure you are not getting this error due to your file being locked by another process, etc.)
+		}
+		UnityEngine.Debug.Log($"nn.fs.File.Open �ɹ� {filename}");
+		long iFileSize = 0;
+		result = nn.fs.File.GetSize(ref iFileSize, fileHandle);
+		if (result.IsSuccess() == false)
+		{
+			UnityEngine.Debug.LogError($"nn.fs.File.GetSize ʧ�� {filename} : result=>{result.GetErrorInfo()}");
+			return false;
+		}
+		UnityEngine.Debug.Log($"nn.fs.File.GetSize �ɹ� {filename},size=>{iFileSize}");
+
+		byte[] loadedData = new byte[iFileSize];
+		result = nn.fs.File.Read(fileHandle, 0, loadedData, iFileSize);
+		if (result.IsSuccess() == false)
+		{
+			UnityEngine.Debug.LogError($"nn.fs.File.Read ʧ�� {filename} : result=>{result.GetErrorInfo()}");
+			return false;
+		}
+		UnityEngine.Debug.Log($"nn.fs.File.Read �ɹ� {filename}");
+
+		nn.fs.File.Close(fileHandle);
+
+		//for (int i = 0; i < loadedData.Length; i++)
+		//{
+		//	UnityEngine.Debug.Log($"data[{i}]:{loadedData[i]}");
+		//}
+
+		outputData = loadedData;
+		return true;
+#endif
+    }
+    public bool DeletePathFile(string filename)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+		//TODO
+#endif
+    }
+    public bool DeletePathDir(string filename)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+		//TODO
+#endif
+    }
+    bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+		// ������
+		if (string.IsNullOrEmpty(filePath))
+		{
+			UnityEngine.Debug.LogError($"��������filePath={filePath}");
+			return false;
+		}
+
+		// ��ȡ·��ǰ׺���� save:/��sd:/��
+		int prefixEndIndex = filePath.IndexOf(":/");
+		if (prefixEndIndex == -1)
+		{
+			UnityEngine.Debug.LogError($"�ļ�·�� {filePath} ��ʽ��Ч��δ�ҵ� ':/' ǰ׺");
+			return false;
+		}
+		string pathPrefix = filePath.Substring(0, prefixEndIndex + 2); // ��ȡǰ׺������ "save:/"
+		string relativePath = filePath.Substring(prefixEndIndex + 2); // �Ƴ�ǰ׺���õ����·��
+
+		// ������״̬
+		if (!IsMountPointAccessible(pathPrefix))
+		{
+			UnityEngine.Debug.LogError($"���ص� {pathPrefix} δ���أ��޷�����·�� {filePath}");
+			return false;
+		}
+
+		// ��ȡ��Ŀ¼·��
+		string directoryPath = System.IO.Path.GetDirectoryName(relativePath); // ��ȡ��Ŀ¼���·��
+		if (string.IsNullOrEmpty(directoryPath))
+		{
+			UnityEngine.Debug.Log($"�ļ�·�� {filePath} ���贴����Ŀ¼��λ�ڸ�Ŀ¼��");
+			return true; // ��Ŀ¼���贴��
+		}
+
+		string fullDirectoryPath = $"{pathPrefix}{directoryPath}"; // ƴ��������Ŀ¼·��
+		UnityEngine.Debug.Log($"��鸸Ŀ¼: {fullDirectoryPath}");
+
+		// ���·���Ƿ���ڼ�������
+		nn.fs.EntryType entryType = 0;
+		nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath);
+		if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result))
+		{
+			if (bAutoCreateDir)
+			{
+				// ·�������ڣ����Դ���
+				UnityEngine.Debug.Log($"��Ŀ¼ {fullDirectoryPath} �����ڣ����Դ��� (�ж����� result=>{result.ToString()})");
+				result = nn.fs.Directory.Create(fullDirectoryPath);
+				if (!result.IsSuccess())
+				{
+					UnityEngine.Debug.LogError($"������Ŀ¼ʧ��: {result.GetErrorInfo()}");
+					return false;
+				}
+				UnityEngine.Debug.Log($"��Ŀ¼ {fullDirectoryPath} �����ɹ�");
+				return true;
+			}
+			return false;
+		}
+		else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory)
+		{
+			// ·�����ڣ�������Ŀ¼
+			UnityEngine.Debug.LogError($"·�� {fullDirectoryPath} �Ѵ��ڣ�������Ŀ¼");
+			return false;
+		}
+		else if (!result.IsSuccess())
+		{
+			// ��������
+			UnityEngine.Debug.LogError($"��鸸Ŀ¼ʧ��: {result.GetErrorInfo()}");
+			return false;
+		}
+		// ·����������Ŀ¼
+		UnityEngine.Debug.Log($"��Ŀ¼ {fullDirectoryPath} �Ѵ�������Ч");
+		return true;
+		
+#endif
+    }
+    /// <summary>
+    /// ���ָ�����ص��Ƿ�ɷ���
+    /// </summary>
+    /// <param name="pathPrefix">·��ǰ׺������ "save:/" �� "sd:/"</param>
+    /// <returns>���ص��Ƿ�ɷ���</returns>
+    bool IsMountPointAccessible(string pathPrefix)
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+		if (string.IsNullOrEmpty(pathPrefix))
+		{
+			UnityEngine.Debug.LogError($"��Ч���ص�: {pathPrefix}");
+			return false;
+		}
+
+		// ����ǰ׺�жϹ��ص����Ͳ�������״̬
+		if (pathPrefix == $"{save_name}:/")
+		{
+			if (!AxiNS.instance.mount.SaveIsMount)
+			{
+				UnityEngine.Debug.LogError($"{save_name}:/ ���");
+				return false;
+			}
+			return true;
+		}
+		else if (pathPrefix == "sd:/")
+		{
+			long freeSpace = 0;
+			// ��� SD ������״̬��ʾ���������ʵ��ʵ�ֵ�����
+			nn.Result result = nn.fs.FileSystem.GetFreeSpaceSize(ref freeSpace, "sd:/");
+			if (!result.IsSuccess())
+			{
+				UnityEngine.Debug.LogError($"sd:/ δ���ػ��޷�����: {result.GetErrorInfo()}");
+				return false;
+			}
+			return true;
+		}
+		else
+		{
+			UnityEngine.Debug.LogWarning($"δ֪���ص� {pathPrefix}���ٶ��ѹ���");
+			return true; // �������ص������ʵ������ʵ��
+		}
+#endif
+    }
+}
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs.meta
new file mode 100644
index 00000000..7fb9bc07
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d910a015a6b6561418bdff7f2c48cffa
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs
new file mode 100644
index 00000000..0d1bae7c
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs
@@ -0,0 +1,124 @@
+#if UNITY_SWITCH
+using nn.account;
+#endif
+public class AxiNSMount
+{
+    static bool bInMount = false;
+    internal static string m_SaveMountName;
+    static bool bInMountForDebug = false;
+    internal static string m_SaveMountForDebugName;
+
+    public bool SaveIsMount => bInMount;
+    public string SaveMountName
+    {
+        get
+        {
+            if (!bInMount)
+                return string.Empty;
+            else
+                return m_SaveMountName;
+        }
+    }
+
+#if UNITY_SWITCH
+	public bool MountSave(Uid userId, string mountName = "save")
+	{
+		if (bInMount)
+			return true;
+
+		if (!nn.fs.SaveData.IsExisting(userId))
+		{
+			UnityEngine.Debug.LogError($"{userId.ToString()}�浵�����ڣ�");
+			return false;
+		}
+		UnityEngine.Debug.Log($"{userId.ToString()}�浵ȷ�����ڣ�");
+
+		nn.Result result;
+		result = nn.fs.SaveData.Mount(mountName, userId);
+		//result.abortUnlessSuccess();
+
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError($"MountSave->����{mountName}:/ ʧ��: " + result.ToString());
+			return false;
+		}
+		UnityEngine.Debug.Log($"MountSave->����{mountName}:/ �ɹ� ");
+		m_SaveMountName = mountName;
+		bInMount = true;
+		return true;
+	}
+    #endif
+
+    public bool MountSDForDebug(string mountName = "sd")
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+        if (bInMountForDebug)
+            return true;
+        nn.Result result;
+        result = nn.fs.SdCard.MountForDebug(mountName);
+        //result.abortUnlessSuccess();
+        if (!result.IsSuccess())
+        {
+            UnityEngine.Debug.LogError($"nn_fs_MountSdCardForDebug->����{mountName}:/ ʧ��: " + result.ToString());
+            return false;
+        }
+        UnityEngine.Debug.Log($"nn_fs_MountSdCardForDebug->����{mountName}:/ �ɹ� ");
+        m_SaveMountForDebugName = mountName;
+        bInMountForDebug = true;
+        return true;
+#endif
+    }
+
+    public bool MountSD(string mountName = "sd")
+    {
+#if !UNITY_SWITCH
+        return false;
+#else
+        if (bInMountForDebug)
+            return true;
+        nn.Result result;
+        result = nn.fs.SdCard.Mount(mountName);
+        //result.abortUnlessSuccess();
+        if (!result.IsSuccess())
+        {
+            UnityEngine.Debug.LogError($"nn_fs_MountSdCard->����{mountName}:/ ʧ��: " + result.ToString());
+            return false;
+        }
+        UnityEngine.Debug.Log($"nn_fs_MountSdCard->����{mountName}:/ �ɹ� ");
+        m_SaveMountForDebugName = mountName;
+        bInMountForDebug = true;
+        return true;
+#endif
+    }
+
+
+    public void UnmountSave()
+    {
+#if UNITY_SWITCH
+        if (!bInMount)
+        {
+            UnityEngine.Debug.LogError($"{m_SaveMountName}:/ û�б����أ�����ж��");
+            return;
+        }
+        nn.fs.FileSystem.Unmount(m_SaveMountName);
+        UnityEngine.Debug.LogError($"UnmountSaveForDebufa->���{m_SaveMountName}:/ ");
+        bInMount = false;
+#endif
+    }
+
+    public void UnmountSaveForDebug()
+    {
+#if UNITY_SWITCH
+        if (!bInMountForDebug)
+        {
+            UnityEngine.Debug.LogError($"{m_SaveMountForDebugName}:/ û�б����أ�����ж��");
+            return;
+        }
+        nn.fs.FileSystem.Unmount(m_SaveMountForDebugName);
+        UnityEngine.Debug.LogError($"UnmountSaveForDebufa->���{m_SaveMountForDebugName}:/ ");
+        bInMountForDebug = false;
+#endif
+    }
+}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs.meta
new file mode 100644
index 00000000..6af050fc
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 48826c5dc8959ff4db8c6a51b6568bb7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs
new file mode 100644
index 00000000..2deaf883
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs
@@ -0,0 +1,106 @@
+#if UNITY_SWITCH
+using nn.account;
+#endif
+
+public class AxiNSUser
+{
+	bool m_bInit = false;
+	bool m_bGotOpenPreselectedUser = false;
+
+#if UNITY_SWITCH
+	Uid m_UserId;
+	nn.account.UserHandle mUserHandle;
+	nn.account.Nickname m_NickName;
+#endif
+
+	#region ���⹫���ӿڣ�ȷ���ڲ���ȫ�������������
+
+#if UNITY_SWITCH
+	public bool GetUserID(out Uid uid)
+	{
+		InitPreselectedUserInfo();
+		if (!m_bGotOpenPreselectedUser)
+		{
+			uid = Uid.Invalid;
+			return false;
+		}
+		uid = m_UserId;
+		return true;
+	}
+#endif
+	public bool GetNickName(out string NickName)
+	{
+#if !UNITY_SWITCH
+		NickName = "";
+		return true;
+#else
+		InitPreselectedUserInfo();
+		if (!m_bGotOpenPreselectedUser)
+		{
+			NickName = string.Empty;
+			return false;
+		}
+		NickName = m_NickName.ToString();
+		return true;
+#endif
+	}
+#endregion
+	/// <summary>
+	/// ��ʼ��Accountģ���
+	/// </summary>
+	void InitNSAccount()
+    {
+#if UNITY_SWITCH
+		if (m_bInit)
+			return;
+		//�����ȳ�ʼ��NS��Account ��Ȼ���ü���
+		nn.account.Account.Initialize();
+		m_bInit = true;
+#endif
+	}
+
+	/// <summary>
+	/// ��ȡԤѡ�û�
+	/// </summary>
+	void InitPreselectedUserInfo()
+    {
+#if UNITY_SWITCH
+		if (m_bGotOpenPreselectedUser)
+			return;
+
+		InitNSAccount();
+		nn.Result result;
+		mUserHandle = new nn.account.UserHandle();
+		if (!nn.account.Account.TryOpenPreselectedUser(ref mUserHandle))
+		{
+			UnityEngine.Debug.LogError("��Ԥѡ���û�ʧ��.");
+			return;
+		}
+		UnityEngine.Debug.Log("��Ԥѡ�û��ɹ�.");
+		result = nn.account.Account.GetUserId(ref m_UserId, mUserHandle);
+		//result.abortUnlessSuccess();
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError($"GetUserIdʧ��: {result.ToString()}");
+			return;
+		}
+
+		if (m_UserId == Uid.Invalid)
+		{
+			UnityEngine.Debug.LogError("�޷���ȡ�û� ID");
+			return;
+		}
+		UnityEngine.Debug.Log($"��ȡ�û� ID:{m_UserId.ToString()}");
+
+		result = nn.account.Account.GetNickname(ref m_NickName, m_UserId);
+		//result.abortUnlessSuccess();
+		if (!result.IsSuccess())
+		{
+			UnityEngine.Debug.LogError($"GetNicknameʧ��: {result.ToString()}");
+			return;
+		}
+		UnityEngine.Debug.Log($"��ȡ�û� NickName ID:{m_NickName.ToString()}");
+		m_bGotOpenPreselectedUser = true;
+#endif
+	}
+}
diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs.meta b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs.meta
new file mode 100644
index 00000000..af807677
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSUser.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 95c2e164c69c6cc4887a194d6eba0cc2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: