diff --git a/Cargo.lock b/Cargo.lock
index a4a7395b05..177191b539 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1614,6 +1614,14 @@ dependencies = [
  "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "portpicker"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "pretty_env_logger"
 version = "0.3.0"
@@ -2360,6 +2368,7 @@ dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msgbox 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "portpicker 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
  "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2750,6 +2759,7 @@ dependencies = [
 "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
 "checksum png 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925"
 "checksum png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63daf481fdd0defa2d1d2be15c674fbfa1b0fd71882c303a91f9a79b3252c359"
+"checksum portpicker 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b497d05c16fe00939445c00a4fe2fa4f3d3dfc9c0401a3ab5c577afda2debb9"
 "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
 "checksum proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "ba92c84f814b3f9a44c5cfca7d2ad77fa10710867d2bbb1b3d175ab5f47daa12"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
diff --git a/server/src/lib.rs b/server/src/lib.rs
index d4e9af9777..9ea247aaad 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -8,10 +8,19 @@ pub mod input;
 // Reexports
 pub use crate::{error::Error, input::Input};
 
-use crate::{
-    client::{Client, Clients},
-    cmd::CHAT_COMMANDS,
+use std::{
+    collections::HashSet,
+    net::SocketAddr,
+    sync::mpsc,
+    time::Duration,
+    i32,
 };
+use specs::{
+    join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
+    Entity as EcsEntity,
+};
+use threadpool::ThreadPool;
+use vek::*;
 use common::{
     comp,
     comp::character::Animation,
@@ -20,14 +29,11 @@ use common::{
     state::{State, Uid},
     terrain::TerrainChunk,
 };
-use specs::{
-    join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
-    Entity as EcsEntity,
-};
-use std::{collections::HashSet, i32, net::SocketAddr, sync::mpsc, time::Duration};
-use threadpool::ThreadPool;
-use vek::*;
 use world::World;
+use crate::{
+    client::{Client, Clients},
+    cmd::CHAT_COMMANDS,
+};
 
 const CLIENT_TIMEOUT: f64 = 20.0; // Seconds
 
@@ -51,9 +57,15 @@ pub struct Server {
 }
 
 impl Server {
-    /// Create a new `Server`.
+    /// Create a new `Server` bound to the default socket.
     #[allow(dead_code)]
     pub fn new() -> Result<Self, Error> {
+        Self::bind(SocketAddr::from(([0; 4], 59003)))
+    }
+
+    /// Create a new server bound to the given socket
+    #[allow(dead_code)]
+    pub fn bind<A: Into<SocketAddr>>(addrs: A) -> Result<Self, Error> {
         let (chunk_tx, chunk_rx) = mpsc::channel();
 
         let mut state = State::new();
@@ -63,7 +75,7 @@ impl Server {
             state,
             world: World::new(),
 
-            postoffice: PostOffice::bind(SocketAddr::from(([0; 4], 59003)))?,
+            postoffice: PostOffice::bind(addrs.into())?,
             clients: Clients::empty(),
 
             thread_pool: threadpool::Builder::new()
diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml
index 8a7f84fe3d..e470bc23c7 100644
--- a/voxygen/Cargo.toml
+++ b/voxygen/Cargo.toml
@@ -46,3 +46,4 @@ fnv = "1.0"
 simplelog = "0.5"
 msgbox = "0.1"
 directories = "1.0"
+portpicker = "0.1"
diff --git a/voxygen/src/menu/main/client_init.rs b/voxygen/src/menu/main/client_init.rs
index 732b849179..82b920754c 100644
--- a/voxygen/src/menu/main/client_init.rs
+++ b/voxygen/src/menu/main/client_init.rs
@@ -3,6 +3,8 @@ use common::comp;
 use std::{
     sync::mpsc::{channel, Receiver, TryRecvError},
     thread::{self, JoinHandle},
+    net::ToSocketAddrs,
+    time::Duration,
 };
 
 #[derive(Debug)]
@@ -20,14 +22,17 @@ pub struct ClientInit {
     rx: Receiver<Result<Client, Error>>,
 }
 impl ClientInit {
-    pub fn new(connection_args: (String, u16, bool), client_args: (comp::Player, u64)) -> Self {
+    pub fn new(connection_args: (String, u16, bool), client_args: (comp::Player, u64), wait: bool) -> Self {
         let (server_address, default_port, prefer_ipv6) = connection_args;
         let (player, view_distance) = client_args;
 
         let (tx, rx) = channel();
 
         let handle = Some(thread::spawn(move || {
-            use std::net::ToSocketAddrs;
+            // Sleep the thread to wait for the single-player server to start up
+            if wait {
+                thread::sleep(Duration::from_millis(250));
+            }
             // Parses ip address or resolves hostname
             // Note: if you use an ipv6 address the number after the last colon will be used as the port unless you use [] around the address
             match server_address
diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs
index 78b431b9a8..417643863a 100644
--- a/voxygen/src/menu/main/mod.rs
+++ b/voxygen/src/menu/main/mod.rs
@@ -102,6 +102,7 @@ impl PlayState for MainMenuState {
                         client_init = client_init.or(Some(ClientInit::new(
                             (server_address, DEFAULT_PORT, false),
                             (comp::Player::new(username.clone()), 300),
+                            false,
                         )));
                     }
                     MainMenuEvent::StartSingleplayer => {
diff --git a/voxygen/src/menu/main/start_singleplayer.rs b/voxygen/src/menu/main/start_singleplayer.rs
index 0d3c8d81f0..c160439d04 100644
--- a/voxygen/src/menu/main/start_singleplayer.rs
+++ b/voxygen/src/menu/main/start_singleplayer.rs
@@ -1,19 +1,24 @@
-use super::{client_init::ClientInit, DEFAULT_PORT};
+use std::net::SocketAddr;
+use common::comp;
 use crate::{
     menu::char_selection::CharSelectionState, singleplayer::Singleplayer, Direction, GlobalState,
     PlayState, PlayStateResult,
 };
-use common::comp;
+use super::{client_init::ClientInit, DEFAULT_PORT};
 
 pub struct StartSingleplayerState {
     singleplayer: Singleplayer,
+    sock: SocketAddr,
 }
 
 impl StartSingleplayerState {
     /// Create a new `MainMenuState`
     pub fn new() -> Self {
+        let (singleplayer, sock) = Singleplayer::new();
+
         Self {
-            singleplayer: Singleplayer::new(),
+            singleplayer,
+            sock,
         }
     }
 }
@@ -23,11 +28,12 @@ impl PlayState for StartSingleplayerState {
         match direction {
             Direction::Forwards => {
                 let username = "singleplayer".to_owned();
-                let server_address = "localhost".to_owned();
+                let server_address = self.sock.ip().to_string();
 
                 let client_init = ClientInit::new(
-                    (server_address.clone(), DEFAULT_PORT, false),
+                    (server_address.clone(), self.sock.port(), false),
                     (comp::Player::new(username.clone()), 300),
+                    true,
                 );
 
                 // Client creation
diff --git a/voxygen/src/singleplayer.rs b/voxygen/src/singleplayer.rs
index c4ad5f6eb9..364646ac24 100644
--- a/voxygen/src/singleplayer.rs
+++ b/voxygen/src/singleplayer.rs
@@ -1,9 +1,13 @@
-use common::clock::Clock;
+use std::{
+    sync::mpsc::{channel, Receiver, Sender, TryRecvError},
+    time::Duration,
+    thread::{self, JoinHandle},
+    net::SocketAddr,
+};
 use log::info;
+use portpicker::pick_unused_port;
+use common::clock::Clock;
 use server::{Event, Input, Server};
-use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
-use std::time::Duration;
-use std::{thread, thread::JoinHandle};
 
 const TPS: u64 = 30;
 
@@ -19,15 +23,21 @@ pub struct Singleplayer {
 }
 
 impl Singleplayer {
-    pub fn new() -> Self {
+    pub fn new() -> (Self, SocketAddr) {
         let (sender, reciever) = channel();
+
+        let sock = SocketAddr::from(([0; 4], pick_unused_port()
+            .expect("Failed to find unused port")));
+
+        let sock2 = sock.clone();
         let thread = thread::spawn(move || {
-            run_server(reciever);
+            run_server(sock2, reciever);
         });
-        Singleplayer {
+
+        (Singleplayer {
             server_thread: thread,
             sender,
-        }
+        }, sock)
     }
 }
 
@@ -37,14 +47,14 @@ impl Drop for Singleplayer {
     }
 }
 
-fn run_server(rec: Receiver<Msg>) {
+fn run_server(sock: SocketAddr, rec: Receiver<Msg>) {
     info!("Starting server-cli...");
 
     // Set up an fps clock
     let mut clock = Clock::new();
 
     // Create server
-    let mut server = Server::new().expect("Failed to create server instance");
+    let mut server = Server::bind(sock).expect("Failed to create server instance");
 
     loop {
         let events = server