diff --git a/Cargo.lock b/Cargo.lock
index 02a6658..bc4f684 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -228,12 +228,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b71031c1463c2bec1984316ea5f5173a9e09c028"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b71031c1463c2bec1984316ea5f5173a9e09c028"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e"
 dependencies = [
  "hashbrown 0.15.1",
  "hbbytecode",
@@ -245,7 +245,7 @@ dependencies = [
 [[package]]
 name = "hbvm"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b71031c1463c2bec1984316ea5f5173a9e09c028"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e"
 dependencies = [
  "hbbytecode",
 ]
@@ -824,9 +824,9 @@ dependencies = [
 
 [[package]]
 name = "uart_16550"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4922792855b1bce30997fbaa5418597902c278a92d20dfe348e6f062c3bd861d"
+checksum = "e492212ac378a5e00da953718dafb1340d9fbaf4f27d6f3c5cab03d931d1c049"
 dependencies = [
  "bitflags 2.6.0",
  "rustversion",
diff --git a/sysdata/libraries/render/TODO.md b/sysdata/libraries/render/TODO.md
index c17ae88..83ee875 100644
--- a/sysdata/libraries/render/TODO.md
+++ b/sysdata/libraries/render/TODO.md
@@ -1,7 +1,4 @@
 # Images
-- General over image format
-- Support formats:
-    - PNG
 - Animation
 
 # API
diff --git a/sysdata/libraries/stn/src/buffer.hb b/sysdata/libraries/stn/src/buffer.hb
index 2a448b8..17f5a3f 100644
--- a/sysdata/libraries/stn/src/buffer.hb
+++ b/sysdata/libraries/stn/src/buffer.hb
@@ -22,7 +22,7 @@ create := fn(msg: ^u8): uint {
 	return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
 }
 
-$create_without_name := fn(): uint {
+$create_nameless := fn(): uint {
 	return @eca(1, 0)
 }
 
diff --git a/sysdata/libraries/sunset_proto/src/client.hb b/sysdata/libraries/sunset_proto/src/client.hb
index 9044bdb..9346e6c 100644
--- a/sysdata/libraries/sunset_proto/src/client.hb
+++ b/sysdata/libraries/sunset_proto/src/client.hb
@@ -1,59 +1,65 @@
-.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb");
-.{Window, WindowData, WindowProps, MessageHeader, send_message, message, await_buffer, await_message, BUFFER} := @use("./lib.hb")
-render := @use("../../render/src/lib.hb")
+.{math: .{Vec2}, buffer, log, memory, string} := @use("../../stn/src/lib.hb");
+.{Channel, Window, send_header, send_message, await_channel, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("./lib.hb");
+.{new_surface, Color} := @use("../../render/src/lib.hb")
 
-server_id := @as(uint, idk)
-screen := @as(render.Surface, idk)
+// ! in the future this should be safely handled
+channel := @as(Channel, idk)
 
 find_server := fn(): void {
-	// ! to be removed in the future
-	screen = render.init(false)
-	render.clear(screen, render.black)
-	log.debug("client: waiting for server\0")
-	server_id = await_buffer(BUFFER)
-	log.debug("client: found server\0")
+	log.info("client: locating server\0")
+	channel = await_channel()
+	log.info("client: server located\0")
 }
 
 new := fn(props: WindowProps): ?Window {
-	send_message(MessageHeader, .(message.syn, 0), server_id)
-	log.debug("client: sent syn\0")
-	response := await_message(MessageHeader, server_id)
-	if response.kind != message.ack {
-		log.error("client: refused syn\0")
+	send_header(message.syn, channel.server)
+	response := await_message(Channel, channel.client)
+	if response.header.kind != message.ack {
+		log.info(string.display_int(@bitcast(response.header.kind), "\0\0\0\0\0\0\0\0\0\0\0\0\0", 10))
 		return null
 	}
-	log.debug("client: got ack\0")
-
-	buffer_id := response.data
-	send_message(WindowProps, props, buffer_id)
-	log.debug("client: sent props\0")
-
-	response2 := await_message(WindowData, buffer_id)
-	log.debug("client: got window data\0")
-	surface := render.new_surface(
-		response2.props.dimensions.x,
-		response2.props.dimensions.y,
-	)
-	return .(response2, surface)
+	log.info("client: recv ack\0")
+	send_message(WindowProps, message.props, props, response.body.server)
+	windowdata := await_message(WindowData, response.body.client)
+	if windowdata.header.kind != message.ack {
+		return null
+	}
+	log.info("client: recv windowdata\0")
+	surface := new_surface(windowdata.body.props.dimensions.x, windowdata.body.props.dimensions.y)
+	return .(windowdata.body, surface)
 }
 
-// ! client buffers are not being read by the server yet
 quit := fn(client: Window): void {
-	send_message(MessageHeader, .(message.quit, 0), client.data.buffer_id)
+	send_header(message.quit, client.data.channel.server)
 }
 
-shutdown_server := fn(): void {
-	send_message(MessageHeader, .(message.shutdown, 0), server_id)
+connected := fn(client: Window): bool {
+	return true
 }
 
-update_props := fn(client: Window): bool {
-	log.error("client: update props unimplemented\0")
+shutdown_server := fn(client: Window): bool {
 	return false
 }
 
-//! temporarily just throw our window at the screen
-frame_ready := fn(client: Window): void {
-	send_message(MessageHeader, .(message.ready, 0), client.data.buffer_id)
-	log.warn("client: we are blitting to screen from the client\n\r      this is temporary behaviour\0")
-	render.put_surface(screen, client.surface, client.data.props.position, false)
+update_props := fn(client: Window): bool {
+	return false
+}
+
+update_permissions := fn(client: Window): bool {
+	return false
+}
+
+send_frame := fn(client: Window): bool {
+	server_id := client.data.channel.server
+	client_id := client.data.channel.client
+	send_header(message.frame_ready, server_id)
+	response := await_message(uint, client_id)
+	if response.header.kind != message.ack {
+		return false
+	}
+	log.info("client: recv ack\0")
+	// ! FOR NOW, server will ALWAYS be local,
+	// ! so we can send pointer to surface.
+	send_message(^Color, message.ack, client.surface.buf, server_id)
+	return true
 }
\ No newline at end of file
diff --git a/sysdata/libraries/sunset_proto/src/lib.hb b/sysdata/libraries/sunset_proto/src/lib.hb
index f4f0a5d..498447f 100644
--- a/sysdata/libraries/sunset_proto/src/lib.hb
+++ b/sysdata/libraries/sunset_proto/src/lib.hb
@@ -1,43 +1,92 @@
 .{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
 .{Surface} := @use("../../render/src/lib.hb")
 
-$BUFFER := "sunset\0"
+$BUFFER_SERVER := "sunset_server\0"
+$BUFFER_CLIENT := "sunset_client\0"
+
+Channel := packed struct {
+	client: uint,
+	server: uint,
+}
 
 client := @use("./client.hb")
 server := @use("./server.hb")
 message := @use("./message.hb")
+permissions := @use("./permissions.hb")
 
-receive_message := fn($Expr: type, buffer_id: uint): ?Expr {
-	recv := @as(?Expr, null)
-	buffer.recv(?Expr, buffer_id, &recv)
-	return recv
+opaque := fn(i: uint): bool {
+	if i == 0 {
+		return true
+	}
+	return false
 }
 
-send_message := fn($Expr: type, msg: Expr, buffer_id: uint): void {
-	buffer.write(?Expr, buffer_id, &@as(?Expr, msg))
+sleep := fn(): void {
+	i := 10000000
+	loop if opaque(i) break else i -= 1
 }
 
-await_buffer := fn(name: ^u8): uint {
-	id := 0
-	loop if id != 0 return id else id = buffer.search(BUFFER)
+$send_message := fn($Expr: type, kind: uint, msg: Expr, buffer_id: uint): void {
+	buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg)))
 }
 
-await_message := fn($Expr: type, buffer_id: uint): Expr {
-	response := @as(?Expr, null)
+$send_header := fn(kind: uint, buffer_id: uint): void {
+	buffer.write(?MessageHeader, buffer_id, &@as(?MessageHeader, .(kind)))
+}
+
+$recv_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
+	response := @as(?Message(Expr), null)
+	buffer.recv(?Message(Expr), buffer_id, &response)
+	return response
+}
+
+$recv_header := fn(buffer_id: uint): ?MessageHeader {
+	response := @as(?MessageHeader, null)
+	buffer.recv(?MessageHeader, buffer_id, &response)
+	return response
+}
+
+await_channel := fn(): Channel {
+	server_id := 0
+	loop if server_id == 0 {
+		server_id = buffer.search(BUFFER_SERVER)
+	}
+	client_id := 0
+	loop if client_id == 0 {
+		client_id = buffer.search(BUFFER_CLIENT)
+	}
+	return .{client: client_id, server: server_id}
+}
+
+await_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
+	response := @as(?Message(Expr), null)
 	loop {
-		buffer.recv(?Expr, buffer_id, &response)
+		buffer.recv(?Message(Expr), buffer_id, &response)
 		if response != null {
-			i := 0
-			return @as(Expr, response)
+			return @as(Message(Expr), response)
+		}
+	}
+}
+
+await_header := fn(buffer_id: uint): MessageHeader {
+	response := @as(?MessageHeader, null)
+	loop {
+		buffer.recv(?MessageHeader, buffer_id, &response)
+		if response != null {
+			return @as(?MessageHeader, response)
 		}
 	}
 }
 
-// ! we need a better message format but this will do for now.
-// enums would be nice
 MessageHeader := packed struct {
 	kind: uint,
-	data: uint,
+}
+
+Message := fn($Expr: type): type {
+	return packed struct {
+		header: MessageHeader,
+		body: Expr,
+	}
 }
 
 WindowProps := struct {
@@ -49,7 +98,8 @@ WindowProps := struct {
 
 WindowData := struct {
 	props: WindowProps,
-	buffer_id: uint,
+	channel: Channel,
+	permissions: uint,
 }
 
 Window := struct {
diff --git a/sysdata/libraries/sunset_proto/src/message.hb b/sysdata/libraries/sunset_proto/src/message.hb
index b12d3d7..918f55e 100644
--- a/sysdata/libraries/sunset_proto/src/message.hb
+++ b/sysdata/libraries/sunset_proto/src/message.hb
@@ -3,6 +3,6 @@ $syn := 1
 $ack := 2
 $refused := 3
 $quit := 4
-$update_props := 5
+$props := 5
 $shutdown := 6
-$ready := 7
\ No newline at end of file
+$frame_ready := 7
\ No newline at end of file
diff --git a/sysdata/libraries/sunset_proto/src/permissions.hb b/sysdata/libraries/sunset_proto/src/permissions.hb
new file mode 100644
index 0000000..57bf4d8
--- /dev/null
+++ b/sysdata/libraries/sunset_proto/src/permissions.hb
@@ -0,0 +1,5 @@
+$none := 0b0
+$exclusive_framebuffer := 0b1
+$shutdown := 0b100
+
+$default := none
\ No newline at end of file
diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb
index b205070..f44bb44 100644
--- a/sysdata/libraries/sunset_proto/src/server.hb
+++ b/sysdata/libraries/sunset_proto/src/server.hb
@@ -1,46 +1,60 @@
 .{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
-.{Surface, new_surface} := @use("../../render/src/lib.hb");
-.{Window, WindowProps, WindowData, MessageHeader, BUFFER, message, receive_message, send_message, await_message} := @use("./lib.hb")
+.{Color, Surface, new_surface, put_surface, sync} := @use("../../render/src/lib.hb");
+.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb")
 
 WindowServer := struct {
 	window_count: uint,
-	id: uint,
+	channel: Channel,
 	// ! replace this with an actual collection when we get an allocator
-	windows: ^WindowData,
+	windows: [?WindowData; 10],
 }
 
 // ! in the future this should be safely handled
 server := @as(WindowServer, idk)
 
 start := fn(): void {
-	windows := memory.alloc(WindowData, 10)
-	server = .(0, buffer.create(BUFFER), windows)
-	log.debug("server: started server\0")
+	server = .(0, .{client: buffer.create(BUFFER_CLIENT), server: buffer.create(BUFFER_SERVER)}, .(null, null, null, null, null, null, null, null, null, null))
+	log.info("server: started server\0")
 }
 
-// ! this function will be rewritten to several functions that allow the server mainloop to handle these itself
-handle_connections := fn(): bool {
-	recv := receive_message(MessageHeader, server.id)
-	if recv == null {
+incoming := fn(): bool {
+	msg := recv_header(server.channel.server)
+	if msg == null {
 		return true
 	}
-	if recv.kind == message.syn {
-		buffer_id := buffer.create_without_name()
-
-		send_message(MessageHeader, .(message.ack, buffer_id), server.id)
-		log.debug("server: sent ack\0")
-
-		resp := await_message(WindowProps, buffer_id)
-		log.debug("server: received props\0")
-
-		data := WindowData.(resp, buffer_id)
-		send_message(WindowData, data, buffer_id)
-		log.debug("server: sent window data\0");
-		*(server.windows + server.window_count) = data
-		server.window_count += 1
-	} else if recv.kind == message.shutdown {
-		log.warn("server: shutdown handled without validation\n\r      this is temporary behaviour\0")
-		return false
+	if msg.kind == message.syn {
+		log.info("server: recv syn\0")
+		channel := Channel.(buffer.create_nameless(), buffer.create_nameless())
+		send_message(Channel, message.ack, channel, channel.client)
+		props := await_message(WindowProps, channel.server)
+		if props.header.kind != message.props {
+			return true
+		}
+		log.info("server: recv props\0")
+		// ! do inspection of requested props here
+		send_message(WindowData, message.ack, .(props.body, channel, permissions.default), channel.client)
 	}
 	return true
+}
+
+render_clients := fn(screen: Surface): void {
+	i := 0
+	loop if i == 10 break else {
+		window := server.windows[i]
+		if window == null {
+			continue
+		}
+		header := recv_header(window.channel.server)
+		if header == null | @unwrap(header).kind != message.frame_ready {
+			continue
+		}
+		send_header(message.ack, window.channel.client)
+		ptr := await_message(^Color, window.channel.server)
+		if ptr.header.kind != message.ack {
+			continue
+		}
+		put_surface(screen, .(ptr.body, window.props.dimensions.x, window.props.dimensions.y, window.props.dimensions.x * window.props.dimensions.y), window.props.position, false)
+		i += 1
+	}
+	sync(screen)
 }
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb
index 9369afd..77cb04c 100644
--- a/sysdata/programs/render_example/src/main.hb
+++ b/sysdata/programs/render_example/src/main.hb
@@ -1 +1 @@
-.{example: main} := @use("./examples/colors.hb")
\ No newline at end of file
+.{example: main} := @use("./examples/text.hb")
\ No newline at end of file
diff --git a/sysdata/programs/sunset_client/src/main.hb b/sysdata/programs/sunset_client/src/main.hb
index 1dfc989..eec5c12 100644
--- a/sysdata/programs/sunset_client/src/main.hb
+++ b/sysdata/programs/sunset_client/src/main.hb
@@ -4,17 +4,14 @@ render := @use("../../../libraries/render/src/lib.hb")
 
 main := fn(): void {
 	sunset.client.find_server()
-	client := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0"))
-	if client == null {
-		log.error("we did not get a window\0")
+
+	window := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0"))
+	if window == null {
+		log.error("got no window\0")
 		return
 	}
-	if sunset.client.update_props(client) == false {
-		log.error("we did not update props\0")
+	render.put_filled_circle(window.surface, .(50, 50), 25, render.white)
+	if sunset.client.send_frame(window) == false {
+		log.error("did not send frame\0")
 	}
-
-	render.put_filled_circle(client.surface, .(50, 50), 20, render.white)
-	sunset.client.frame_ready(client)
-	sunset.client.quit(client)
-	sunset.client.shutdown_server()
 }
\ No newline at end of file
diff --git a/sysdata/programs/sunset_server/src/main.hb b/sysdata/programs/sunset_server/src/main.hb
index 79dc01e..f11694e 100644
--- a/sysdata/programs/sunset_server/src/main.hb
+++ b/sysdata/programs/sunset_server/src/main.hb
@@ -1,7 +1,10 @@
 sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
+render := @use("../../../libraries/render/src/lib.hb")
 
 main := fn(): void {
+	screen := render.init(true)
 	sunset.server.start()
-	loop if sunset.server.handle_connections() {
+	loop if sunset.server.incoming() {
+		sunset.server.render_clients(screen)
 	}
 }
\ No newline at end of file
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index ab597c0..da9cbd0 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -22,8 +22,8 @@ resolution = "1024x768x24"
 
 [boot.limine.ableos.modules]
 
-[boot.limine.ableos.modules.render_example]
-path = "boot:///render_example.hbf"
+# [boot.limine.ableos.modules.render_example]
+# path = "boot:///render_example.hbf"
 
 # [boot.limine.ableos.modules.horizon]
 # path = "boot:///horizon.hbf"
@@ -34,8 +34,8 @@ path = "boot:///render_example.hbf"
 # [boot.limine.ableos.modules.ps2_keyboard_driver]
 # path = "boot:///ps2_keyboard_driver.hbf"
 
-# [boot.limine.ableos.modules.sunset_client]
-# path = "boot:///sunset_client.hbf"
+[boot.limine.ableos.modules.sunset_client]
+path = "boot:///sunset_client.hbf"
 
-# [boot.limine.ableos.modules.sunset_server]
-# path = "boot:///sunset_server.hbf"
+[boot.limine.ableos.modules.sunset_server]
+path = "boot:///sunset_server.hbf"