diff --git a/GServer.RC/GServer.RC.csproj b/GServer.RC/GServer.RC.csproj
new file mode 100644
index 0000000..f75632e
--- /dev/null
+++ b/GServer.RC/GServer.RC.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net8.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <PackageReference Include="GtkSharp" Version="3.24.24.95" />
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\GServer.Common\GServer.Common.csproj" />
+    </ItemGroup>
+
+</Project>
diff --git a/GServer.RC/Program.cs b/GServer.RC/Program.cs
new file mode 100644
index 0000000..08d27de
--- /dev/null
+++ b/GServer.RC/Program.cs
@@ -0,0 +1,41 @@
+using System.Net;
+using System.Net.Sockets;
+using GServer.RC.UI;
+using Gtk;
+
+namespace GServer.RC;
+
+internal static class Program
+{
+    private const int GameServerPort = 11000;
+
+    private static void Main(string[] args)
+    {
+        Application.Init();
+        
+        LoginWindow loginWindow = new();
+        loginWindow.Show();
+
+        // Handle game server connection and networking on a separate thread
+        Thread networkingThread = new(ConnectToGameServer);
+        networkingThread.Start();
+        
+        Application.Run();
+    }
+
+    private static void ConnectToGameServer()
+    {
+        try
+        {
+            IPEndPoint serverEp = new(IPAddress.Any, GameServerPort);
+
+            TcpClient tcpClient = new();
+            tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+            tcpClient.Connect(serverEp);
+        }
+        catch (Exception e)
+        {
+            Console.WriteLine($"Error connecting to game server: {e.Message}");
+        }
+    }
+}
\ No newline at end of file
diff --git a/GServer.RC/UI/LoginWindow.cs b/GServer.RC/UI/LoginWindow.cs
new file mode 100644
index 0000000..25b2752
--- /dev/null
+++ b/GServer.RC/UI/LoginWindow.cs
@@ -0,0 +1,70 @@
+using Cairo;
+using Gtk;
+
+namespace GServer.RC.UI;
+
+internal class LoginWindow : Window
+{
+    private Entry usernameEntry;
+    private Entry passwordEntry;
+    private Label errorLabel;
+    
+    public LoginWindow() : base("Login")
+    {
+        SetDefaultSize(400, 250);
+        DeleteEvent += (_, _) => Application.Quit();
+        SetPosition(WindowPosition.Center);
+        Resizable = false;
+        Present();
+        
+        // Controls
+        
+        // Create a vertical box to hold the widgets
+        VBox vbox = new VBox(true, 2);
+        vbox.BorderWidth = 10;
+
+        // Username label and entry
+        Label usernameLabel = new Label("Username:");
+        usernameEntry = new Entry();
+        
+        // Password label and entry
+        Label passwordLabel = new Label("Password:");
+        passwordEntry = new Entry { Visibility = false }; // Hide the password
+        passwordEntry.Text = ""; // Clear the text
+
+        // Login button
+        Button loginButton = new Button("Login");
+        loginButton.Clicked += (_, _) =>
+        {
+            ShowError("Hello!");
+        };
+        
+        loginButton.Halign = Align.End;
+        loginButton.WidthRequest = 80;
+        
+        // Error label
+        errorLabel = new Label();
+        // errorLabel.Hide();
+        // errorLabel.ModifyFg(StateType.Normal, new Gdk.Color(255, 0, 0));
+
+        // Add all widgets to the vertical box
+        vbox.PackStart(usernameLabel, false, false, 5);
+        vbox.PackStart(usernameEntry, false, false, 5);
+        vbox.PackStart(passwordLabel, false, false, 5);
+        vbox.PackStart(passwordEntry, false, false, 5);
+        vbox.PackStart(loginButton, false, false, 5);
+        vbox.PackStart(errorLabel, false, false, 5);
+
+        // Add the vertical box to the window
+        Add(vbox);
+        ShowAll();
+        
+        errorLabel.Hide();
+    }
+
+    public void ShowError(string error)
+    {
+        errorLabel.Text = error;
+        errorLabel.Show();
+    }
+}
\ No newline at end of file
diff --git a/GServer.sln b/GServer.sln
index e661656..f34ba04 100644
--- a/GServer.sln
+++ b/GServer.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.Server", "GServer.S
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.Client", "GServer.Client\GServer.Client.csproj", "{C105363D-E719-4296-94A2-01170E603889}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GServer.RC", "GServer.RC\GServer.RC.csproj", "{328FDAD6-F0DD-4094-882D-FAF9D563AD51}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
 		{C105363D-E719-4296-94A2-01170E603889}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C105363D-E719-4296-94A2-01170E603889}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C105363D-E719-4296-94A2-01170E603889}.Release|Any CPU.Build.0 = Release|Any CPU
+		{328FDAD6-F0DD-4094-882D-FAF9D563AD51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{328FDAD6-F0DD-4094-882D-FAF9D563AD51}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{328FDAD6-F0DD-4094-882D-FAF9D563AD51}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{328FDAD6-F0DD-4094-882D-FAF9D563AD51}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE