diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/data/output.rs
index a5b5680..12d80f5 100644
--- a/protocol-generator/src/data/output.rs
+++ b/protocol-generator/src/data/output.rs
@@ -3,6 +3,7 @@ use std::collections::HashSet;
 use std::fmt;
 use std::fmt::Display;
 
+#[derive(Debug)]
 pub enum State {
     Handshake,
     Status,
@@ -13,10 +14,10 @@ pub enum State {
 impl State {
     pub fn data_import(&self) -> &str {
         match self {
-            State::Handshake => "crate::packet::handshake",
-            State::Status => "crate::packet::status",
-            State::Login => "crate::packet::login",
-            State::Game => "crate::packet::game",
+            State::Handshake => "crate::data::handshake::*",
+            State::Status => "crate::data::status::*",
+            State::Login => "crate::data::login::*",
+            State::Game => "crate::data::game::*",
         }
     }
 }
@@ -50,7 +51,7 @@ impl Display for Bound {
     }
 }
 
-#[derive(Serialize)]
+#[derive(Serialize, Debug)]
 pub struct Packet {
     pub id: u8,
     pub name: String,
@@ -67,7 +68,7 @@ impl Packet {
     }
 }
 
-#[derive(Serialize)]
+#[derive(Serialize, Debug)]
 pub struct Field {
     pub name: String,
     #[serde(flatten)]
@@ -81,9 +82,13 @@ impl Field {
             data_type,
         }
     }
+
+    pub fn change_type(&self, data_type: DataType) -> Field {
+        Field::new(&self.name, data_type)
+    }
 }
 
-#[derive(Serialize, Eq, PartialEq)]
+#[derive(Serialize, Eq, PartialEq, Debug)]
 #[serde(tag = "type")]
 pub enum DataType {
     #[serde(rename(serialize = "bool"))]
@@ -137,6 +142,7 @@ impl DataType {
     }
 }
 
+#[derive(Debug)]
 pub struct Protocol {
     pub state: State,
     pub server_bound_packets: Vec<Packet>,
diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs
index c09e7be..86dc94b 100644
--- a/protocol-generator/src/main.rs
+++ b/protocol-generator/src/main.rs
@@ -6,6 +6,7 @@ use heck::{CamelCase, SnakeCase};
 
 use crate::data::input::{Container, Data, ProtocolData, ProtocolState};
 use crate::data::output;
+use crate::data::output::Field;
 use serde::Serialize;
 use serde_json::json;
 use std::collections::HashMap;
@@ -132,7 +133,7 @@ fn transform_protocol_data(
         let id = *packet_ids
             .get(no_prefix_name)
             .expect("Failed to get packet id");
-        let name = rename_packet(&no_prefix_name.to_camel_case(), &bound);
+        let packet_name = rename_packet(&no_prefix_name.to_camel_case(), &bound);
 
         let mut fields = vec![];
 
@@ -142,14 +143,14 @@ fn transform_protocol_data(
                     match container {
                         Container::Value { name, data } => {
                             if let Some(field) = transform_field(name, data) {
-                                fields.push(field);
+                                fields.push(modify_field(&packet_name, field));
                             }
                         }
                         Container::List { name, data_vec } => {
                             if let Some(name) = name {
                                 for data in data_vec {
                                     if let Some(field) = transform_field(name, data) {
-                                        fields.push(field);
+                                        fields.push(modify_field(&packet_name, field));
                                     }
                                 }
                             }
@@ -159,7 +160,11 @@ fn transform_protocol_data(
             }
         }
 
-        let packet = output::Packet { id, name, fields };
+        let packet = output::Packet {
+            id,
+            name: packet_name,
+            fields,
+        };
 
         packets.push(packet);
     }
@@ -218,8 +223,8 @@ fn format_field_name(unformatted_field_name: &str) -> String {
     }
 }
 
-fn transform_data_type(str_type: &str) -> Option<output::DataType> {
-    match str_type {
+fn transform_data_type(name: &str) -> Option<output::DataType> {
+    match name {
         "bool" => Some(output::DataType::Boolean),
         "i8" => Some(output::DataType::Byte),
         "i16" => Some(output::DataType::Short),
@@ -237,12 +242,21 @@ fn transform_data_type(str_type: &str) -> Option<output::DataType> {
         "buffer" => Some(output::DataType::ByteArray { rest: false }),
         "restBuffer" => Some(output::DataType::ByteArray { rest: true }),
         _ => {
-            println!("{}", str_type);
+            println!("Unknown data type \"{}\"", name);
             None
         }
     }
 }
 
+fn modify_field(packet_name: &str, field: output::Field) -> output::Field {
+    match (packet_name, field.name.as_str()) {
+        ("StatusResponse", "response") => field.change_type(output::DataType::RefType {
+            ref_name: "ServerStatus".to_owned(),
+        }),
+        _ => field,
+    }
+}
+
 fn rename_packet(name: &str, bound: &output::Bound) -> String {
     match (name, bound) {
         ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse",
diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/packet_enum.hbs
index 0b81503..c596a16 100644
--- a/protocol-generator/templates/packet_enum.hbs
+++ b/protocol-generator/templates/packet_enum.hbs
@@ -32,7 +32,7 @@ impl {{packet_enum_name}} {
         }
     }
 {{#each packets as |p|}}
-    pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{f.type}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self {
+    pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{#if (ne f.type "RefType")}}{{f.type}}{{~else}}{{f.ref_name}}{{/if}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self {
     {{~#if p.fields}}
         let {{snake_case p.name}} = {{p.name}} {
         {{~#each p.fields as |f|}}
diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs
index 4beb5be..6392a83 100644
--- a/protocol/src/packet/status.rs
+++ b/protocol/src/packet/status.rs
@@ -1,5 +1,6 @@
 // This file is automatically generated.
 // It is not intended for manual editing.
+use crate::data::status::*;
 use crate::DecodeError;
 use crate::Decoder;
 use minecraft_protocol_derive::Packet;
@@ -70,7 +71,7 @@ impl StatusClientBoundPacket {
         }
     }
 
-    pub fn status_response(response: String) -> Self {
+    pub fn status_response(response: ServerStatus) -> Self {
         let status_response = StatusResponse { response };
 
         Self::StatusResponse(status_response)
@@ -90,7 +91,7 @@ pub struct PingRequest {
 
 #[derive(Packet, Debug)]
 pub struct StatusResponse {
-    pub response: String,
+    pub response: ServerStatus,
 }
 
 #[derive(Packet, Debug)]