diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..e444c24f
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "resources"]
+ path = resources
+ url = git@Repo.Ez-webz.com:Stride/resources.git
diff --git a/deployment/README.txt b/deployment/README.txt
new file mode 100644
index 00000000..365bdf42
--- /dev/null
+++ b/deployment/README.txt
@@ -0,0 +1,36 @@
+This deployment folder contains files that describe how a release of TTSride should be run on the gameservers.
+
+uberdogs.yml contains the 'uberdogs' section of an astrond.yml. Please keep it updated, or else you'll break prod!
+
+deploy.json describes a the environment for a release of TTSride. It contains the version of astron to use as well as the version of Panda3D to use as well as the libpandadna version to use..
+deploy.json also contains a version prefix. This is used to generate dev version strings on the development server (which are probably something like ttstride-beta-dev-gabcdef0).
+When we deploy a release to prod, we push a git tag named after the version to the repository (i.e. ttstride-alpha-v1.3.7). It is required that the tag's name contain the version prefix specified in deploy.json.
+The key 'server-resources' maps to a list of file extensions of files in the resources directory that are necessary to be used server-side. We do not package and deploy art assets onto servers.
+
+Last, server.prc is the configuration file we use for specifying config vars related to gameplay (a variable like want-sbhq should be put in server.prc, while a variable like air-stateserver does not belong here). server.prc is the last portion added to generated configuration files.
+We also have a tag system to allow certain blocks of configuration to be used only in a certain environment. This allows us to generate releases that behaive differently depending on the environment that they are deployed in. For example:
+
+-----
+want-toontowncentral #t
+#
+want-bbhq #f
+#
+
+#
+want-bbhq #t
+#
+-----
+
+In prod, the parsed config file would look like this:
+
+-----
+want-toontowncentral #t
+#
+want-bbhq #f
+#
+
+#
+##UNUSED SECTION
+##want-bbhq #t
+#
+-----
\ No newline at end of file
diff --git a/deployment/deploy.json b/deployment/deploy.json
new file mode 100644
index 00000000..6e6eb8c3
--- /dev/null
+++ b/deployment/deploy.json
@@ -0,0 +1,8 @@
+{
+ "__fyi__": "If you use anything other than the first 7 characters of the git hash, you just broke everything",
+ "astron": "6b769e6",
+ "panda3d": "b924139",
+ "libpandadna": "a0047ce",
+ "version-prefix": "ttstride-alpha-",
+ "server-resources": ["pdna", "txt", "dat", "bam", "ttf"]
+}
diff --git a/deployment/public_client.prc b/deployment/public_client.prc
new file mode 100644
index 00000000..f7190d31
--- /dev/null
+++ b/deployment/public_client.prc
@@ -0,0 +1,88 @@
+# This is the PRC configuration file for a published TTStride client. Note that only
+# this file and Panda3D's Confauto.prc are included. Any relevant directives in
+# Config.prc should be reproduced here.
+
+# Client settings
+window-title Toontown Stride
+server-version SERVER_VERSION_HERE
+audio-library-name p3openal_audio
+video-library-name p3ffmpeg
+want-dev #f
+preload-avatars #t
+
+
+# Textures:
+texture-anisotropic-degree 16
+
+
+# Resources settings
+model-path /
+model-cache-models #f
+model-cache-textures #f
+vfs-mount resources/default/phase_3.mf /
+vfs-mount resources/default/phase_3.5.mf /
+vfs-mount resources/default/phase_4.mf /
+vfs-mount resources/default/phase_5.mf /
+vfs-mount resources/default/phase_5.5.mf /
+vfs-mount resources/default/phase_6.mf /
+vfs-mount resources/default/phase_7.mf /
+vfs-mount resources/default/phase_8.mf /
+vfs-mount resources/default/phase_9.mf /
+vfs-mount resources/default/phase_10.mf /
+vfs-mount resources/default/phase_11.mf /
+vfs-mount resources/default/phase_12.mf /
+vfs-mount resources/default/phase_13.mf /
+default-model-extension .bam
+
+
+# DC files are NOT configured.
+# They're wrapped up into the code automatically.
+
+
+# Core features:
+want-pets #t
+want-parties #f
+want-cogdominiums #t
+want-lawbot-cogdo #t
+want-anim-props #t
+want-game-tables #t
+want-find-four #t
+want-chinese-checkers #t
+want-checkers #t
+want-house-types #t
+want-gifting #t
+want-top-toons #f
+want-language-selection #t
+estate-day-night #t
+want-mat-all-tailors #t
+
+
+# Temporary:
+smooth-lag 0.4
+want-old-fireworks #t
+
+
+# Developer options:
+want-dev #f
+want-pstats 0
+
+
+# Crates:
+dont-destroy-crate #t
+get-key-reward-always #t
+get-crate-reward-always #t
+
+
+# Chat:
+want-whitelist #t
+
+
+#
+show-total-population #t
+want-instant-parties #t
+want-instant-delivery #t
+cogdo-pop-factor 1.5
+cogdo-ratio 0.5
+default-directnotify-level info
+#
+
diff --git a/deployment/server.prc b/deployment/server.prc
new file mode 100644
index 00000000..657b5f75
--- /dev/null
+++ b/deployment/server.prc
@@ -0,0 +1,32 @@
+# While dev.prc contains settings for both the dev server and client, the
+# live server separates these. The client settings go in config/public_client.prc
+# and server settings go here. Don't forget to update both if necessary.
+
+# Server settings
+want-dev #f
+want-cheesy-expirations #t
+cogsuit-hack-prevent #t
+
+
+# Core features:
+want-pets #t
+want-parties #f
+want-cogdominiums #t
+want-lawbot-cogdo #t
+want-anim-props #t
+want-game-tables #t
+want-find-four #t
+want-chinese-checkers #t
+want-checkers #t
+want-house-types #t
+want-gifting #t
+want-top-toons #f
+want-language-selection #t
+estate-day-night #t
+want-mat-all-tailors #t
+is-server #t
+
+
+# Chat Settings
+want-whitelist #t
+want-sequence-list #t
diff --git a/deployment/toontown/ai/ServiceStart.py b/deployment/toontown/ai/ServiceStart.py
new file mode 100644
index 00000000..9f1451de
--- /dev/null
+++ b/deployment/toontown/ai/ServiceStart.py
@@ -0,0 +1,71 @@
+import __builtin__
+
+
+__builtin__.process = 'ai'
+
+
+# Temporary hack patch:
+__builtin__.__dict__.update(__import__('pandac.PandaModules', fromlist=['*']).__dict__)
+from direct.extensions_native import HTTPChannel_extensions
+
+import argparse, gc, os
+
+# Panda3D 1.10.0 is 63.
+gc.disable()
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--base-channel', help='The base channel that the server may use.')
+parser.add_argument('--max-channels', help='The number of channels the server may use.')
+parser.add_argument('--stateserver', help="The control channel of this AI's designated State Server.")
+parser.add_argument('--district-name', help="What this AI Server's district will be named.")
+parser.add_argument('--astron-ip', help="The IP address of the Astron Message Director to connect to.")
+parser.add_argument('--eventlogger-ip', help="The IP address of the Astron Event Logger to log to.")
+parser.add_argument('config', nargs='*', default=['dependencies/config/general.prc', 'dependencies/config/release/dev.prc'], help="PRC file(s) to load.")
+args = parser.parse_args()
+
+for prc in args.config:
+ loadPrcFile(prc)
+
+if os.path.isfile('dependencies/config/local.prc'):
+ loadPrcFile('dependencies/config/local.prc')
+
+localconfig = ''
+if args.base_channel: localconfig += 'air-base-channel %s\n' % args.base_channel
+if args.max_channels: localconfig += 'air-channel-allocation %s\n' % args.max_channels
+if args.stateserver: localconfig += 'air-stateserver %s\n' % args.stateserver
+if args.district_name: localconfig += 'district-name %s\n' % args.district_name
+if args.astron_ip: localconfig += 'air-connect %s\n' % args.astron_ip
+if args.eventlogger_ip: localconfig += 'eventlog-host %s\n' % args.eventlogger_ip
+loadPrcFileData('Command-line', localconfig)
+
+from otp.ai.AIBaseGlobal import *
+
+from toontown.ai.ToontownAIRepository import ToontownAIRepository
+simbase.air = ToontownAIRepository(config.GetInt('air-base-channel', 401000000),
+ config.GetInt('air-stateserver', 4002),
+ config.GetString('district-name', 'Devhaven'))
+host = config.GetString('air-connect', '127.0.0.1')
+port = 7100
+if ':' in host:
+ host, port = host.split(':', 1)
+ port = int(port)
+simbase.air.connect(host, port)
+
+isServer = config.GetBool('is-server', False)
+
+try:
+ run()
+ gc.enable()
+except SystemExit:
+ raise
+except Exception:
+ info = describeException()
+
+ simbase.air.writeServerEvent('ai-exception', avId=simbase.air.getAvatarIdFromSender(), accId=simbase.air.getAccountIdFromSender(), exception=info)
+
+ if isServer:
+ import datetime
+ with open(config.GetString('ai-crash-log-name', '/opt/var/log/%s-ai-crash-%s.txt' % (config.GetString('district-name', 'Devhaven'), datetime.datetime.now())), 'w+') as file:
+ file.write(info + "\n")
+
+ raise
diff --git a/deployment/toontown/uberdog/ServiceStart.py b/deployment/toontown/uberdog/ServiceStart.py
new file mode 100644
index 00000000..5c48e920
--- /dev/null
+++ b/deployment/toontown/uberdog/ServiceStart.py
@@ -0,0 +1,60 @@
+import __builtin__
+
+
+__builtin__.process = 'uberdog'
+
+# Temporary hack patch:
+__builtin__.__dict__.update(__import__('pandac.PandaModules', fromlist=['*']).__dict__)
+from direct.extensions_native import HTTPChannel_extensions
+
+import argparse, os
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--base-channel', help='The base channel that the server may use.')
+parser.add_argument('--max-channels', help='The number of channels the server may use.')
+parser.add_argument('--stateserver', help="The control channel of this UD's designated State Server.")
+parser.add_argument('--astron-ip', help="The IP address of the Astron Message Director to connect to.")
+parser.add_argument('--eventlogger-ip', help="The IP address of the Astron Event Logger to log to.")
+parser.add_argument('config', nargs='*', default=['dependencies/config/general.prc', 'dependencies/config/release/dev.prc'], help="PRC file(s) to load.")
+args = parser.parse_args()
+
+for prc in args.config:
+ loadPrcFile(prc)
+
+if os.path.isfile('dependencies/config/local.prc'):
+ loadPrcFile('dependencies/config/local.prc')
+
+localconfig = ''
+if args.base_channel:
+ localconfig += 'air-base-channel %s\n' % args.base_channel
+if args.max_channels:
+ localconfig += 'air-channel-allocation %s\n' % args.max_channels
+if args.stateserver:
+ localconfig += 'air-stateserver %s\n' % args.stateserver
+if args.astron_ip:
+ localconfig += 'air-connect %s\n' % args.astron_ip
+if args.eventlogger_ip:
+ localconfig += 'eventlog-host %s\n' % args.eventlogger_ip
+loadPrcFileData('Command-line', localconfig)
+
+
+from otp.ai.AIBaseGlobal import *
+
+from toontown.uberdog.ToontownUberRepository import ToontownUberRepository
+simbase.air = ToontownUberRepository(config.GetInt('air-base-channel', 400000000),
+ config.GetInt('air-stateserver', 4002))
+host = config.GetString('air-connect', '127.0.0.1')
+port = 7100
+if ':' in host:
+ host, port = host.split(':', 1)
+ port = int(port)
+simbase.air.connect(host, port)
+
+try:
+ run()
+except SystemExit:
+ raise
+except Exception:
+ info = describeException()
+ simbase.air.writeServerEvent('uberdog-exception', simbase.air.getAvatarIdFromSender(), simbase.air.getAccountIdFromSender(), info)
+ raise
diff --git a/deployment/uberdogs.yml b/deployment/uberdogs.yml
new file mode 100644
index 00000000..3deba31a
--- /dev/null
+++ b/deployment/uberdogs.yml
@@ -0,0 +1,20 @@
+uberdogs:
+ - class: ClientServicesManager
+ id: 4665
+ anonymous: true
+
+ - class: ChatAgent
+ id: 4681
+ anonymous: false
+
+ - class: FriendManager
+ id: 4501
+ anonymous: false
+
+ - class: TTSFriendsManager
+ id: 4666
+ anonymous: false
+
+ - class: GlobalPartyManager
+ id: 4477
+ anonymous: false
\ No newline at end of file