diff --git a/cryp.cbor b/cryp.cbor
deleted file mode 100644
index 7f62e2ac..00000000
--- a/cryp.cbor
+++ /dev/null
@@ -1 +0,0 @@
-©bidx$8f1755ac-8bf1-47b9-b181-c998aa16a04bcdmg¢evaluedkindcDmgcdef¢evaluedkindcDefdstam¢evaluedkinddStambhp¢evaluedkindbHpbxpclvlfskills�fStoneydnameihatchling
\ No newline at end of file
diff --git a/src/cryp.rs b/src/cryp.rs
index b095ca9c..b1cc019b 100755
--- a/src/cryp.rs
+++ b/src/cryp.rs
@@ -1,10 +1,12 @@
 use uuid::Uuid;
 use rand::prelude::*;
-use skill::{Skill};
 use serde_cbor::*;
 use std::fs::File;
 use std::io::prelude::*;
 
+use rpc::{GenerateParams};
+use skill::{Skill};
+
 #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
 pub enum StatKind {
   Dmg,
@@ -176,6 +178,19 @@ impl Cryp {
 
 }
 
+pub fn generate(params: GenerateParams) -> Vec<u8> {
+    let level_two = Cryp::new()
+        .named("hatchling".to_string())
+        .level(params.level)
+        .learn(Skill::Stoney)
+        .create();
+
+    match to_vec(&level_two) {
+        Ok(v) => v,
+        Err(e) => panic!("couldn't serialize cryp"),
+    }
+}
+
 
 #[cfg(test)]
 mod tests {
diff --git a/src/main.rs b/src/main.rs
index dea80e75..8e1b515b 100755
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ mod battle;
 mod net;
 mod combat;
 mod skill;
+mod rpc;
 
 use net::{start};
 
diff --git a/src/net.rs b/src/net.rs
index 949662f6..f8688ae4 100755
--- a/src/net.rs
+++ b/src/net.rs
@@ -1,34 +1,7 @@
-use cryp::{Cryp};
-use skill::{Skill};
-use serde_cbor::{to_vec,from_slice,Value};
-use serde_cbor::error::Error as CborError;
+use cryp::{generate};
 use ws::{listen, Handler, Sender, Result, Message, Handshake, CloseCode, Error};
-use std::result::Result as StdResult;
-
-#[derive(Debug)]
-enum RpcError {
-    Parse(CborError),
-    // UnknownMethod,
-}
-
-struct Rpc;
-impl Rpc {
-    pub fn receive(&self, msg: Message) -> StdResult<Vec<u8>, RpcError> {
-        // specify rpc message as the resulting type
-        match from_slice::<RpcMessage>(&msg.into_data()) {
-            Ok(v) => {
-               println!("{:?}", v);
-               Ok(generate())
-            },
-            Err(e) => Err(RpcError::Parse(e)),
-        }
-    }
-}
-
-#[derive(Debug,Clone,Serialize,Deserialize)]
-struct RpcMessage {
-    method: String,
-}
+use rpc::{Rpc,RpcMessage};
+use serde_cbor::{to_vec};
 
 struct Server {
     out: Sender,
@@ -37,14 +10,14 @@ struct Server {
 
 impl Handler for Server {
     fn on_open(&mut self, _: Handshake) -> Result<()> {
-        // We have a new connection, so we increment the connection counter
         println!("somebody joined");
         Ok(())
     }
 
     fn on_message(&mut self, msg: Message) -> Result<()> {
-        let reply = Message::binary(generate());
-        self.out.send(reply)
+        let reply = self.rpc.receive(msg);
+        println!("{:?}", reply);
+        self.out.send(reply.unwrap())
     }
 
     fn on_close(&mut self, code: CloseCode, reason: &str) {
@@ -64,30 +37,4 @@ impl Handler for Server {
 
 pub fn start() {
   listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {} } }).unwrap();
-}
-
-pub fn generate() -> Vec<u8> {
-    let level_two = Cryp::new()
-        .named("hatchling".to_string())
-        .level(64)
-        .learn(Skill::Stoney)
-        .create();
-
-    match to_vec(&level_two) {
-        Ok(v) => v,
-        Err(e) => panic!("couldn't serialize cryp"),
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn rpc_parse() {
-        let rpc = Rpc {};
-        let msg = RpcMessage { method: "grep".to_string() };
-        let v = to_vec(&msg).unwrap();
-        let received = rpc.receive(Message::Binary(v));
-    }
 }
\ No newline at end of file
diff --git a/src/rpc.rs b/src/rpc.rs
new file mode 100644
index 00000000..876ef1cf
--- /dev/null
+++ b/src/rpc.rs
@@ -0,0 +1,72 @@
+use std::result::Result as StdResult;
+use ws::{Message};
+use serde_cbor::{from_slice};
+use serde_cbor::error::Error as CborError;
+
+use cryp::generate;
+
+pub struct Rpc;
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+struct GenerateMsg {
+    method: String,
+    params: GenerateParams,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct GenerateParams {
+    pub level: u8,
+}
+
+impl Rpc {
+    pub fn receive(&self, msg: Message) -> StdResult<Vec<u8>, RpcError> {
+        // specify rpc message as the resulting type
+        let data = msg.into_data();
+        match from_slice::<RpcMessage>(&data) {
+            Ok(v) => {
+
+                // now we have the method name
+                // match on that to determine what fn to call
+                match v.method.as_ref() {
+                    "cryp_generate" => {
+                        match from_slice::<GenerateMsg>(&data) {
+                            Ok(v) => Ok(generate(v.params)),
+                            Err(_) => Err(RpcError::Parse),
+                        }
+                    },
+                    _ => Err(RpcError::UnknownMethod),
+                }
+            },
+            Err(_) => Err(RpcError::Parse),
+        }
+    }
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct RpcMessage {
+    method: String,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub enum RpcError {
+    Parse,
+    UnknownMethod,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+enum RpcParam {
+    GenerateParams { level: u16 },
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use serde_cbor::to_vec;
+    #[test]
+    fn rpc_parse() {
+        let rpc = Rpc {};
+        let msg = GenerateMsg { method: "cryp_generate".to_string(), params: GenerateParams { level: 64 }  };
+        let v = to_vec(&msg).unwrap();
+        let received = rpc.receive(Message::Binary(v));
+    }
+}
\ No newline at end of file
