diff --git a/cmd/server/main.go b/cmd/server/main.go
index a44eb77..ec66ff0 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -2,9 +2,11 @@ package main
 
 import (
 	"fmt"
+	"sshpong/internal/netwrk"
 )
 
 func main() {
-	fmt.Println("Starting sshpong server")
+	fmt.Println("Starting sshpong server!")
 
+	netwrk.Listen()
 }
diff --git a/genprotos.sh b/genprotos.sh
new file mode 100644
index 0000000..04f4cb5
--- /dev/null
+++ b/genprotos.sh
@@ -0,0 +1 @@
+protoc --go_out=. *.proto
diff --git a/go.mod b/go.mod
index ec11306..ea8f265 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module sshpong
 
 go 1.22.2
 
-require github.com/google/uuid v1.6.0
+require (
+	github.com/google/uuid v1.6.0
+	google.golang.org/protobuf v1.34.2
+)
diff --git a/go.sum b/go.sum
index 7790d7c..5d8aaa7 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,4 @@
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
diff --git a/internal/netwrk/lobby_messages.pb.go b/internal/netwrk/lobby_messages.pb.go
new file mode 100644
index 0000000..249de01
--- /dev/null
+++ b/internal/netwrk/lobby_messages.pb.go
@@ -0,0 +1,152 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.34.2
+// 	protoc        v5.27.3
+// source: lobby_messages.proto
+
+package netwrk
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type LobbyMessage struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type    string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
+}
+
+func (x *LobbyMessage) Reset() {
+	*x = LobbyMessage{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_lobby_messages_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LobbyMessage) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LobbyMessage) ProtoMessage() {}
+
+func (x *LobbyMessage) ProtoReflect() protoreflect.Message {
+	mi := &file_lobby_messages_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LobbyMessage.ProtoReflect.Descriptor instead.
+func (*LobbyMessage) Descriptor() ([]byte, []int) {
+	return file_lobby_messages_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *LobbyMessage) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *LobbyMessage) GetContent() string {
+	if x != nil {
+		return x.Content
+	}
+	return ""
+}
+
+var File_lobby_messages_proto protoreflect.FileDescriptor
+
+var file_lobby_messages_proto_rawDesc = []byte{
+	0x0a, 0x14, 0x6c, 0x6f, 0x62, 0x62, 0x79, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3c, 0x0a, 0x0c,
+	0x4c, 0x6f, 0x62, 0x62, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04,
+	0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
+	0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x14, 0x5a, 0x12, 0x2e, 0x2e,
+	0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x72, 0x6b,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_lobby_messages_proto_rawDescOnce sync.Once
+	file_lobby_messages_proto_rawDescData = file_lobby_messages_proto_rawDesc
+)
+
+func file_lobby_messages_proto_rawDescGZIP() []byte {
+	file_lobby_messages_proto_rawDescOnce.Do(func() {
+		file_lobby_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_lobby_messages_proto_rawDescData)
+	})
+	return file_lobby_messages_proto_rawDescData
+}
+
+var file_lobby_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_lobby_messages_proto_goTypes = []any{
+	(*LobbyMessage)(nil), // 0: main.LobbyMessage
+}
+var file_lobby_messages_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_lobby_messages_proto_init() }
+func file_lobby_messages_proto_init() {
+	if File_lobby_messages_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_lobby_messages_proto_msgTypes[0].Exporter = func(v any, i int) any {
+			switch v := v.(*LobbyMessage); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_lobby_messages_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_lobby_messages_proto_goTypes,
+		DependencyIndexes: file_lobby_messages_proto_depIdxs,
+		MessageInfos:      file_lobby_messages_proto_msgTypes,
+	}.Build()
+	File_lobby_messages_proto = out.File
+	file_lobby_messages_proto_rawDesc = nil
+	file_lobby_messages_proto_goTypes = nil
+	file_lobby_messages_proto_depIdxs = nil
+}
diff --git a/internal/netwrk/netwrk.go b/internal/netwrk/netwrk.go
index 4876301..1e6f607 100644
--- a/internal/netwrk/netwrk.go
+++ b/internal/netwrk/netwrk.go
@@ -1,6 +1,7 @@
 package netwrk
 
 import (
+	"bufio"
 	"fmt"
 	"log"
 	"net"
@@ -30,6 +31,8 @@ type GameConnections struct {
 var clientPool *ClientPool
 var gameConnections *GameConnections
 
+// Starts listening on port 12345 for TCP connections
+// Also creates client pool and game connection singletons
 func Listen() {
 	clientPool = &ClientPool{
 		clients: map[string]Client{},
@@ -70,6 +73,50 @@ func Listen() {
 
 }
 
+func handleLobbyConnection(connID string, conn net.Conn) {
+	defer conn.Close()
+	reader := bufio.NewReader(conn)
+
+	for {
+		message, err := reader.ReadString('\n')
+		if err != nil {
+			log.Printf("Error reading message %v", err)
+			delete(clientPool.clients, connID)
+			return
+		}
+
+		handleLobbyMessage(message, conn)
+	}
+}
+
+func handleLobbyMessage(message string, conn net.Conn) {
+
+	key, data := decodeMessage(message)
+	switch message {
+	case "start":
+		break
+	case "waiting":
+		break
+	default:
+		clientPool.clients[message]
+	}
+}
+
+func decodeLobbyMessage(message string) (string, any) {
+	switch message {
+	case "start":
+		return "start", nil
+	case "waiting":
+		return "waiting", nil
+	default:
+	break
+	}
+
+	strings
+
+	}
+}
+
 func GetPool() (map[string]Client, bool) {
 	if clientPool.clients != nil {
 		return clientPool.clients, true
@@ -100,9 +147,6 @@ func CreateGame(clientID1, clientID2 string) (string, error) {
 		client2: client2,
 	}
 
-	delete(clientPool.clients, clientID1)
-	delete(clientPool.clients, clientID2)
-
 	return gameID, nil
 }
 
diff --git a/proto/lobby_messages.proto b/proto/lobby_messages.proto
new file mode 100644
index 0000000..695607a
--- /dev/null
+++ b/proto/lobby_messages.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package main;
+
+option go_package = "../internal/netwrk";
+
+message LobbyMessage {
+  string type = 1;
+  string content = 2;
+}