diff --git a/README.md b/README.md
index 0de8a002..a85d4e2b 100644
--- a/README.md
+++ b/README.md
@@ -4,28 +4,41 @@ A zone server for the multiplayer game Subspace based on *A Small Subspace Serve
## About
This is a cross-platform server written in C#. It was developed based on the *A Small Subspace Server* (*ASSS*) open-source project and can be considered a derivative. As such, the modular design closely resembles that of *ASSS* and is meant to be extended in very much the same ways.
-This project aims to match the core functionality of *ASSS*. Contrary to its name, *ASSS* is not "small". Porting over everything in *ASSS* is not a realistic goal, therefore a choice had to be made on what is considered essential. Nearly everything needed to run a zone is available. See [asss-equivalents](./doc/asss-equivalents.md) for a more detailed listing. Also, see [additional-features](./doc/additional-features.md) for information about features that this server adds, which are not in *ASSS*.
-
-For guidance on how to extend the server, see the [Developer Guide](./doc/developer-guide.md).
-
-## Setup / Use
-1. Open and build the solution: `"src/SubspaceServer.sln"`.
-2. Setup the Zone
- 1. Copy **Continuum.exe** (currently 0.40) into the zone's **'clients'** folder: `"src/SubspaceServer/Zone/clients"`.
- 2. Configure it much like you would for *ASSS*.
- - arenas
- - conf
- - maps
- - news.txt
-3. Run it.
-*Note: The working directory needs to be the **'Zone'** folder.*
+This project provides everything needed to host a zone. It has all of the essential functionality from *ASSS* and also many of the extras.
+
+- See [asss-equivalents](./doc/asss-equivalents.md) for a detailed listing and comparison of included parts.
+- Also, see [additional-features](./doc/additional-features.md) for information about features that this server adds, which are not in *ASSS*.
+
+## Get Started
+
+[Download](./releases) the latest release.
+
+- Follow the [Quickstart](./doc/quickstart.md) for instructions on how to get up and running from scratch.
+ - If you already have a zone running using *ASSS*, see [Quickstart from ASSS](./doc/quickstart-from-asss.md) instead. It has instructions on how to use your existing files.
+- Read the [User Manual](./doc/user-manual.md) for more information.
+
+## Build and Extend
+
+The built-in functionality of the server is more than enough to host a zone. It's highly configurable and supports all the regular gameplay modes. However, the true power of this project is in how it can be extended by writing plugins.
+
+For guidance on how to develop your own plugins to extend the server, see the [Developer Guide](./doc/developer-guide.md).
+
+To build the server,
+- Get the code:
+
+ ```
+ git clone https://github.com/gigamon-dev/SubspaceServer.git
+ ````
+
+- Open the solution: `"src/SubspaceServer.sln"` to build and run it.
+- Remember to place a copy of **Continuum.exe** (currently 0.40) into the zone's **'clients'** folder: `"src/SubspaceServer/Zone/clients"` before running.
## Dependencies
-- [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf)
-- [Iconic.Zlib.Netstandard](https://www.nuget.org/packages/Iconic.Zlib.Netstandard)
-- [Microsoft.Extensions.ObjectPool](https://www.nuget.org/packages/Microsoft.Extensions.ObjectPool)
-- [SixLabors.ImageSharp](https://www.nuget.org/packages/SixLabors.ImageSharp)
-- [System.Data.SQLite.Core](https://www.nuget.org/packages/System.Data.SQLite.Core)
+- [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf) - for serializing data
+- [Iconic.Zlib.Netstandard](https://www.nuget.org/packages/Iconic.Zlib.Netstandard) - for zlib and crc32
+- [Microsoft.Extensions.ObjectPool](https://www.nuget.org/packages/Microsoft.Extensions.ObjectPool) - object pooling to reduce the need to garbage collect
+- [SixLabors.ImageSharp](https://www.nuget.org/packages/SixLabors.ImageSharp) - for creating images of maps
+- [System.Data.SQLite.Core](https://www.nuget.org/packages/System.Data.SQLite.Core) - embedded database for persisting player and arena data
## License
GNU GPLv2, since that's what *A Small Subspace Server* uses and much of this can be considered as being a derivative of it.
diff --git a/doc/quickstart-from-asss.md b/doc/quickstart-from-asss.md
new file mode 100644
index 00000000..33e4afc1
--- /dev/null
+++ b/doc/quickstart-from-asss.md
@@ -0,0 +1,104 @@
+# Subspace Server .NET Quickstart from ASSS
+
+### Contents
+
+[Prerequisites](#prerequisites)
+[Installation](#installation)
+[Transition to Modules.config](#transition-to-modulesconfig)
+[Modules Attached to Arenas](#modules-attached-to-arenas)
+[Run the server](#run-the-server)
+[Take it further](#take-it-further)
+
+This article provides instructions on how to quickly get *Subspace Server .NET* up and running for those that already have a zone using *ASSS* and would like to try to hosting it using *Subspace Server .NET*.
+
+If you don't already have a zone running *ASSS*, see [Quickstart](./quickstart.md) instead for instructions on how to set up from scratch.
+
+## Prerequisites
+
+The server requires that .NET be installed. If you don't already have it, you can get it from: https://dotnet.microsoft.com. (Currently .NET 7)
+
+The server can technically be run on any system supported by .NET. However, pre-built binaries are only being provided for Linux x64 and Windows x64.
+
+> You are free to download the source code and build it for other platforms/architectures, but be aware of these known limitations:
+> - The System.Data.SQLite NuGet package doesn't include native binaries for ARM64. To work around this, either build your own ARM64 binary for SQLite or do not use the persist modules (`SS.Core.Modules.PersistSQLite` and `SS.Core.Modules.Persist`).
+> - The Continuum Encryption native binaries (closed source) are currently only available for Linux x64 and Windows x64. In the future, macOS and ARM64 binaries may be considered.
+
+## Installation
+
+Download the latest [release](../releases) and extract it to the location of your choice.
+
+Copy files from your ASSS zone including:
+- The `clients` folder (which should contain the Continuum.exe client)
+- The `maps` folder
+- The `arenas` folder
+- `news.txt`
+- `obscene.txt`
+- `conf/passwd.conf`
+- `conf/staff.conf`
+- any additional .conf files under `conf/` that your arenas #include
+
+## Transition to Modules.config
+
+ASSS uses the `conf/modules.conf` file to determine the which modules to load and the order to load them in. Subspace Server .NET uses `conf/Modules.config`, which is similar, but is an XML file.
+
+Module names are slightly different in Subspace Server .NET. It should be relatively obvious which modules you'll want to load compared to those being loaded for your existing ASSS zone. In fact, the default load order is more or less the same. If in doubt, see [asss-equivalents](asss-equivalents.md) for a mapping of ASSS modules to Subspace Server .NET modules.
+
+## Modules Attached to Arenas
+
+In an arena.conf file, the `Modules:AttachModules` setting is used to attach modules to the arena. The value of this setting differs slightly, so you'll need to edit each of the arena.conf files that includes this setting.
+
+In ASSS the setting looks like:
+```INI
+[ Modules ]
+AttachModules = \
+ points_kill \
+ points_flag \
+ points_goal \
+ buy
+```
+
+The setting is similar in Subspace Server .NET, except that the module names are different. Here's the equivalent of the above for Subspace Server .NET:
+```INI
+[ Modules ]
+AttachModules = \
+ SS.Core.Modules.Scoring.KillPoints \
+ SS.Core.Modules.Scoring.FlagGamePoints \
+ SS.Core.Modules.Scoring.BallGamePoints \
+ SS.Core.Modules.Buy
+```
+
+Notice the modules differ slightly in name, and they include the full namespace. See [asss-equivalents](asss-equivalents.md) for a mapping of ASSS modules to Subspace Server .NET modules.
+
+## Run the server
+
+To run the server, use the included startup script which is located in the zone's root folder.
+
+#### Linux and macOS
+
+The script is named: `run-server.sh`. From the shell, `cd` to the folder you installed the server to, and run it:
+
+```
+./run-server.sh
+```
+
+#### Windows
+
+The script is named: `run-server.cmd`. Run it from File Explorer, or from the command line `cd` to the folder you installed the server to, and run it.
+
+```
+run-server.cmd
+```
+
+#### PowerShell
+
+Alternatively, a PowerShell script, `run-server-ps1` is also included, in case that is your preference.
+
+```
+./run-server.ps1
+```
+
+## Take it further
+
+For more information about the server, see the [User Manual](./user-manual.md).
+
+To learn how to create your own plugin modules, see the [Developer Guide](./developer-guide.md).
diff --git a/doc/quickstart.md b/doc/quickstart.md
new file mode 100644
index 00000000..c1a90b0f
--- /dev/null
+++ b/doc/quickstart.md
@@ -0,0 +1,96 @@
+# Subspace Server .NET Quickstart
+
+### Contents
+
+[Prerequisites](#prerequisites)
+[Installation](#installation)
+[Run the server](#run-the-server)
+[Connect to your zone](#connect-to-your-zone)
+[Take it further](#take-it-further)
+
+This article provides instructions on how to quickly get *Subspace Server .NET* up and running from scratch.
+
+If you already have a zone running *ASSS*, see [Quickstart from ASSS](quickstart-from-asss.md) instead for instructions on how to use your existing *ASSS* files.
+
+## Prerequisites
+
+The server requires that .NET be installed. If you don't already have it, you can get it from: https://dotnet.microsoft.com. (Currently .NET 7)
+
+The server can technically be run on any system supported by .NET. However, pre-built binaries are only being provided for Linux x64 and Windows x64.
+
+> You are free to download the source code and build it for other platforms/architectures, but be aware of these known limitations:
+> - The System.Data.SQLite NuGet package doesn't include native binaries for ARM64. To work around this, either build your own ARM64 binary for SQLite or do not use the persist modules (`SS.Core.Modules.PersistSQLite` and `SS.Core.Modules.Persist`).
+> - The Continuum Encryption native binaries (closed source) are currently only available for Linux x64 and Windows x64. In the future, macOS and ARM64 binaries may be considered.
+
+## Installation
+
+1. Download the latest [release](../releases) and extract it to the location of your choice.
+
+2. In the folder you extracted to, find the folder named `clients`. Copy `Continuum.exe` from your Continuum client's folder into the `clients` folder.
+
+At this point, the server can technically be run and you'd be able to connect to it on port 5000. However, you'll likely want to change that.
+
+## Configure the endpoint to Listen on
+
+Open the `conf/global.conf` file and find the `[Listen]` section. It should look something like:
+
+```ini
+[ Listen ]
+Port = 5000
+BindAddress =
+```
+
+The `Port` setting tells the server which UDP port to listen on for game requests. It also determines which port to listen on for ping requests, which is always implicitly the `Port` number + 1. Therefore, in this example, it listens for game requests on port 5000 and for ping requests on port 5001.
+
+The `BindAddress` setting tells the server which IP address to listen on. By default, this setting is empty, meaning listen on all available network interfaces.
+
+## Run the server
+
+To run the server, use the included startup script which is located in the zone's root folder.
+
+#### Linux and macOS
+
+The script is named: `run-server.sh`. From the shell, `cd` to the folder you installed the server to, and run it:
+
+```
+./run-server.sh
+```
+
+#### Windows
+
+The script is named: `run-server.cmd`. Run it from File Explorer, or from command line `cd` to the folder you installed the server to, and run it.
+
+```
+run-server.cmd
+```
+
+#### PowerShell
+
+Alternatively, a PowerShell script, `run-server-ps1` is also included, in case that is your preference.
+
+```
+./run-server.ps1
+```
+
+> To shut the server down gracefully, use: `Ctrl + C`
+
+## Connect to your zone
+
+Start the Continuum client. On the main screen, click the **Zones** button to open the **Add/Update Zones** window. Alternatively, it can be opened by navigating on the menu bar to: **View** --> **Zones...**
+
+On the **Add/Update Zones** window, click the "**Add Custom...**" button and fill out the fields. Fill in the **Zone Name** with a name of your choice. Fill in the **IP Address** of the server. If you're running it locally, you can use 127.0.0.1 to specify localhost. The **Port** should be the value you configured earlier, or 5000 if you skipped that step.
+
+Confirm you choices and your zone should appear on list and you should be able to connect to it.
+
+## Take it further
+
+Now that you have your server running, what you do with it is up to you.
+
+For more information about the server, see the [User Manual](./user-manual.md).
+
+Here are a few topics that might be of interest:
+- [How to initially set yourself up as sysop](./user-manual.md#how-to-initially-set-yourself-up-as-sysop)
+- [List your zone on directory servers](./user-manual.md#list-your-zone-on-directory-servers)
+- [Connect your zone to a billing server](./user-manual.md#connect-your-zone-to-a-billing-server)
+
+If you would like to learn how to create your own plugins, see the [Developer Guide](./developer-guide.md).
diff --git a/doc/user-manual.md b/doc/user-manual.md
new file mode 100644
index 00000000..a34466a5
--- /dev/null
+++ b/doc/user-manual.md
@@ -0,0 +1,336 @@
+# Subspace Server .NET User Manual
+
+> This is a work in progress.
+
+## Directory structure
+
+```
++-- arenas
+| +-- (public)
+| | arena.conf
+| +-- (default)
++-- bin
+| +-- modules
++-- clients
++-- conf
+| +-- groupdef.dir
+| + global.conf
+| + groupdef.conf
+| + Modules.config
+| + passwd.conf
+| + staff.conf
++-- data
++-- log
++-- maps
++-- recordings
++-- tmp
++ news.txt
++ obscene.txt
++ scrty
++ scrty1
+```
+
+TODO: Add info about each folder and notable files.
+
+## Running the Server
+
+The server is a .NET application and can be run using the `.NET CLI`.
+
+From the zone root directory run:
+
+```
+dotnet ./bin/SubspaceServer.dll
+```
+
+The server also accepts passing optional arguments:
+
+```
+dotnet ./bin/SubspaceServer.dll [] [-i]`
+```
+
+Alternatively, a default host executable is provided:
+
+#### Linux or macOS
+
+`./bin/SubspaceServer [] [-i]`
+
+#### Windows
+
+`./bin/SubspaceServer.exe [] [-i]`
+
+### Command line arguments
+
+``
+The root path of the zone.
+
+`-i`
+To use interactive mode.
+
+
+> Unlike *ASSS*, this server does not support running chrooted on Linux.
+
+### Use a Startup Script
+
+Startup scripts are provided that start the server. They will restart the server if the server wants to reccyle (e.g. due to a `?recyclezone` or `?shutdown -r`).
+
+#### Linux and macOS
+
+```
+./run-server.sh
+```
+
+#### Windows (cmd)
+
+```
+run-server.cmd
+```
+
+#### PowerShell
+
+```
+./run-server.ps1
+```
+
+## Modules
+
+## Access Control
+
+Getting started
+
+TODO: describe how to initially set yourself up with a password and add yourself as a sysop
+
+TODO: Groups and capabilities
+
+`conf/staff.conf`
+`conf/passwd.conf`
+
+Groups:
+- default : regular user
+- mod : moderator
+- smod : super moderator
+- bot : non-human, bot application connecting as a privileged user
+- sysop : highest access level available, can manage files directly with `?putfile`, `?getfile`, etc...
+
+### Advanced Access Control
+
+> Works exactly the same as in ASSS. See the ASSS [userguide.pdf](https://asss.minegoboom.com/files/userguide.html#%_sec_4)
+
+TODO: describe `conf/groupdef.conf` and the `conf/groupdef.dir` directory
+
+In `conf/groupdef.conf` sections are group names. Individual lines within a section are capabilities. There are 3 types of capabilities:
+
+#### Command capabilties
+
+Determine which commands a user can run.
+
+- cmd_*<command name>*
+
+- privcmd_*<command name>*
+
+- rprivcmd_*<command name>*
+
+#### Hierarchy capabilities
+
+Are in format:
+> `higher_than_`*<group name>*
+
+ For example:
+- higher_than_default
+- higher_than_mod
+- higher_than_smod
+
+#### Special bulit-in capabilities
+- **seemodchat** -
+- **sendmodchat** -
+- **sendsoundmessages** -
+- **uploadfile** -
+- **seesysoplogall** -
+- **seesysoplogarena** -
+- **seeprivarena** -
+- **seeprivfreq** -
+- **suppresssecurity** -
+- **bypasssecurity** -
+- **broadcastbot** -
+- **broadcastany** -
+- **invisiblespectator** -
+- **unlimitedchat** -
+- **changesettings** -
+- **isstaff** -
+- **seeallstaff** -
+- **forceshipfreqchange** -
+- **excludepopulation** -
+- **bypasslock** -
+- **seenrg** -
+- **seeepd** -
+- **setbanner** -
+
+## Logging
+
+TODO: describe the logging system
+
+> Works exactly the same as in ASSS. See the ASSS [userguide.pdf](https://asss.minegoboom.com/files/userguide.html#%_sec_5)
+
+## Configuration
+
+The server is highly configurable. Here are some of the most important changes you'll probably want to make.
+
+### Listen endpoint(s)
+
+Open the `conf/global.conf` file and find the `[Listen]` section. It should look something like:
+```ini
+[ Listen ]
+Port = 5000
+BindAddress =
+AllowVIE = 1
+AllowCont = 1
+ConnectAs =
+```
+The `Port` setting tells the server which UDP port to listen on for game requests. In this example, it listens on port 5000. Also, ping requests are listened to on the `Port` number + 1. So in this example, the server will listen for ping requests on port 5001.
+
+The `BindAddress` setting tells the server which IP address to listen on. By default, this setting is empty, meaning listen on all network interfaces.
+
+The `AllowVIE` setting controls whether to allow VIE protocol clients. Note, this includes the original Subspace 1.34 and bots.
+
+The `AllowCont` setting controls whether to allow Continuum clients. You'll want to leave this set to 1.
+
+The `ConnectAs` setting tells which arena to send players to, empty means use the first available public arena (e.g. as if you typed ?go when in game without specifying an arena name).
+
+> Like ASSS, the server supports listening on multiple endpoints simultaneously by configuring multiple listen sections (e.g. `[Listen]`, `[Listen1]`, `[Listen2]`, and so on) but is is recommended to just use the single `[Listen]` (no number) endpoint since it is used when connecting to a Billing server.
+
+### How to initially set yourself up as sysop
+
+These instructions describe how to set up your zone after initially installing it, to allow yourself to login as a sysop.
+
+Verify that the `SS.Core.Modules.AuthFile` module is being loaded by opening the `conf/Modules.config` file and making sure it's included. If this is a fresh install of the server, then it should already be there. This is what the line should look like:
+
+```ini
+
+```
+
+Open the `conf/staff.conf` file. Find the `[(global)]` section and add a line to it that says:
+
+```ini
+ = sysop
+ ```
+
+ where `` is the username you want to be able to login as sysop with.
+
+Open the `conf/passwd.conf` file. Find the `[General]` section and verify that the following settings are set to `yes`.
+```ini
+AllowUnknown = yes
+RequireAuthenticationToSetPassword = no
+```
+> Turning off `RequireAuthenticationToSetPassword` is dangerous and should only be used temporarily. At the end of these instuctions we will turn it back on. DO NOT SKIP THAT STEP!
+
+Start the server up and login with the username you configured earlier. When in-game, set your password using the following command, filling in `` with the password you want to use:
+
+```
+?local_password
+```
+
+Log out and reconnect to the zone with the password you just set. You should now be logged in as sysop. To verify, run the following command in-game:
+
+```
+?getgroup
+```
+
+and the server should respond with:
+```
+You are in group sysop.
+```
+
+Open the `conf/passwd.conf` file. Find the `[General]` section and change the `RequireAuthenticationToSetPassword` setting to `yes`.
+
+```ini
+RequireAuthenticationToSetPassword = yes
+```
+
+### How to add a mod / smod
+
+TODO:
+
+
+### List your zone on Directory server(s)
+
+To list your zone on Directory servers, so that others can find it, do the following:
+
+Open the `conf/global.conf` file and fill in the `[Directory]` section. It should look like:
+```INI
+[ Directory ]
+Name = test zone
+Description = this is a test zone.
+Password =
+
+Server1 = sscentral.sscuservers.net
+Server2 = sscentral.trenchwars.org
+```
+These settings allow you to set a `Name` and `Description` for your zone and choose which directory servers you want to publish to. Do not change `Password` setting (leave it empty), unless you know what you're doing. Certain zone name prefixes such as "SSC" are reserved and require a password.
+
+Open the `conf/Modules.config` file and uncomment the line for `SS.Core.Modules.DirectoryPublisher`. This tells the server to load the DirectoryPublisher module. Here's what the line should look like after uncommenting it:
+```XML
+
+
+```
+
+### Connect your zone to a Billing server
+
+If you have access to a billing server, you can connect your zone to it using the `SS.Core.Modules.BillingUdp`. To set it up, first edit your `conf/Modules.config` to load the module.
+
+```
+
+```
+
+Next, open the `conf/global.conf` file and edit the `[Billing]` section.
+
+```INI
+[ Billing ]
+IP = 127.0.0.1
+Port = 1850
+ServerName = Test zone
+Password = bill
+ServerID = 0
+GroupID = 1
+ScoreID = 0
+```
+
+The administrator of the billing server should be able to provide you with the setting values to use.
+
+- `IP` - the IP address of the billing server
+- `Port` - the port of the billing server
+- `ServerName` - the name to use for your zone on the billing server
+- `Password` - the password to connect to the billing server with
+
+### Arena Attachable modules
+
+Certain modules need to be attached to an arena for their functionality to be made active. This allows for a more fine grained control over which functionality to use available in each arena, rather be active server-wide (every arena). The downside is that it requires a bit more configuration.
+
+For example, one arena might host a ball game, and there you would likely want to use the `SS.Core.Modules.Scoring.BallGamePoints` module to handle scoring of the ball game. Whereas, another arena might host a capture the flag game, and it would likely want to use `SS.Core.Modules.Scoring.FlagGamePoints`.
+
+In an `arena.conf`, attached modules are specified through the `Modules:AttachModules` setting. For example, for an arena hosting a capture the flag game, the setting might look like:
+
+```ini
+[ Modules ]
+AttachModules = \
+ SS.Core.Modules.Scoring.KillPoints \
+ SS.Core.Modules.Scoring.FlagGamePoints
+```
+
+That is, functionality for awarding points for kills is enabled, and functionality for running the flag game (determining a winner and awarding points) is enabled.
+
+> For a module to be attached to an arena, it needs to have been loaded. So, remember to include the module in the `conf/Modules.config` for it to be loaded on startup.
+
+Here's a list of the included modules that support attaching to arenas:
+
+| Module | Description |
+| --- | --- |
+| `SS.Core.Modules.Buy` | Ability to ?buy prizes. |
+| `SS.Core.Modules.Scoring.BallGamePoints` | Scoring for ball games. |
+| `SS.Core.Modules.Scoring.FlagGamePoints` | Scoring for flag games. |
+| `SS.Core.Modules.Scoring.KillPoints` | Scoring for kills. |
+| `SS.Core.Modules.Scoring.Koth` | "King of the Hill" game mode / scoring. |
+| `SS.Core.Modules.Scoring.SpeedGame` | "Speed" game mode / scoring. |
+| `SS.Core.Modules.Enforcers.LegalShip` | Enforces legal ships by freq. |
+| `SS.Core.Modules.Enforcers.LockSpec` | Enforces that players can only spectate. |
+| `SS.Core.Modules.Enforcers.ShipChange` | Enforces rules for changing ships. |
+| `SS.Matchmaking.Modules.OneVersusOneStats` | Stats for 1v1 matches. For use in conjunction with `SS.Matchmaking.Modules.OneVersusOneMatch`. |
+| `SS.Matchmaking.Modules.TeamVersusStats` | Stats for team matches. For use in conjunction with `SS.Matchmaking.Modules.TeamVersusMatch` |