dfx 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +3 -0
- package/.prettierrc.json +4 -0
- package/DiscordREST/types.ts +5 -0
- package/DiscordWS/index.ts +0 -0
- package/WS/index.ts +122 -0
- package/discord-api-docs/.eslintrc.json +10 -0
- package/discord-api-docs/.gitattributes +11 -0
- package/discord-api-docs/.github/ISSUE_TEMPLATE/api-bug-report.yml +49 -0
- package/discord-api-docs/.github/ISSUE_TEMPLATE/config.yml +20 -0
- package/discord-api-docs/.github/ISSUE_TEMPLATE/developer-site-bug-report.yml +49 -0
- package/discord-api-docs/.github/ISSUE_TEMPLATE/message-components-bug-report.yml +49 -0
- package/discord-api-docs/.github/ISSUE_TEMPLATE/slash-command-bug-report.yml +49 -0
- package/discord-api-docs/.github/workflows/test.yaml +45 -0
- package/discord-api-docs/.prettierignore +1 -0
- package/discord-api-docs/.prettierrc.json +15 -0
- package/discord-api-docs/CODE_OF_CONDUCT.md +75 -0
- package/discord-api-docs/CONTRIBUTING.md +16 -0
- package/discord-api-docs/README.md +35 -0
- package/discord-api-docs/ci/checkLinks.ts +177 -0
- package/discord-api-docs/docs/Change_Log.md +474 -0
- package/discord-api-docs/docs/Intro.md +48 -0
- package/discord-api-docs/docs/Legal.md +154 -0
- package/discord-api-docs/docs/Policy.md +81 -0
- package/discord-api-docs/docs/Reference.md +476 -0
- package/discord-api-docs/docs/Store_Distribution_Agreement.md +179 -0
- package/discord-api-docs/docs/dispatch/Branches_and_Builds.md +654 -0
- package/discord-api-docs/docs/dispatch/Dispatch_and_You.md +17 -0
- package/discord-api-docs/docs/dispatch/Error_Codes.md +26 -0
- package/discord-api-docs/docs/dispatch/Field_Values.md +48 -0
- package/discord-api-docs/docs/dispatch/List_of_Commands.md +315 -0
- package/discord-api-docs/docs/game_and_server_management/Alpha_and_Beta_Testing.md +52 -0
- package/discord-api-docs/docs/game_and_server_management/How_to_Get_Your_Game_on_Discord.md +110 -0
- package/discord-api-docs/docs/game_and_server_management/Special_Channels.md +38 -0
- package/discord-api-docs/docs/game_sdk/Achievements.md +405 -0
- package/discord-api-docs/docs/game_sdk/Activities.md +561 -0
- package/discord-api-docs/docs/game_sdk/Applications.md +237 -0
- package/discord-api-docs/docs/game_sdk/Discord.md +443 -0
- package/discord-api-docs/docs/game_sdk/Discord_Voice.md +289 -0
- package/discord-api-docs/docs/game_sdk/Images.md +196 -0
- package/discord-api-docs/docs/game_sdk/Lobbies.md +1639 -0
- package/discord-api-docs/docs/game_sdk/Networking.md +377 -0
- package/discord-api-docs/docs/game_sdk/Overlay.md +195 -0
- package/discord-api-docs/docs/game_sdk/Relationships.md +234 -0
- package/discord-api-docs/docs/game_sdk/SDK_Starter_Guide.md +310 -0
- package/discord-api-docs/docs/game_sdk/Storage.md +312 -0
- package/discord-api-docs/docs/game_sdk/Store.md +555 -0
- package/discord-api-docs/docs/game_sdk/Users.md +178 -0
- package/discord-api-docs/docs/interactions/Application_Commands.md +1069 -0
- package/discord-api-docs/docs/interactions/Message_Components.md +454 -0
- package/discord-api-docs/docs/interactions/Receiving_and_Responding.md +372 -0
- package/discord-api-docs/docs/interactions/Slash_Commands.md +3 -0
- package/discord-api-docs/docs/resources/Application.md +82 -0
- package/discord-api-docs/docs/resources/Audit_Log.md +223 -0
- package/discord-api-docs/docs/resources/Channel.md +1267 -0
- package/discord-api-docs/docs/resources/Emoji.md +122 -0
- package/discord-api-docs/docs/resources/Guild.md +1157 -0
- package/discord-api-docs/docs/resources/Guild_Scheduled_Event.md +273 -0
- package/discord-api-docs/docs/resources/Guild_Template.md +148 -0
- package/discord-api-docs/docs/resources/Invite.md +150 -0
- package/discord-api-docs/docs/resources/Stage_Instance.md +106 -0
- package/discord-api-docs/docs/resources/Sticker.md +164 -0
- package/discord-api-docs/docs/resources/User.md +205 -0
- package/discord-api-docs/docs/resources/Voice.md +55 -0
- package/discord-api-docs/docs/resources/Webhook.md +281 -0
- package/discord-api-docs/docs/rich_presence/Best_Practices.md +88 -0
- package/discord-api-docs/docs/rich_presence/FAQ.md +45 -0
- package/discord-api-docs/docs/rich_presence/How_To.md +302 -0
- package/discord-api-docs/docs/rich_presence/Launch_Checklist.md +46 -0
- package/discord-api-docs/docs/topics/Certified_Devices.md +200 -0
- package/discord-api-docs/docs/topics/Community_Resources.md +98 -0
- package/discord-api-docs/docs/topics/Gateway.md +1600 -0
- package/discord-api-docs/docs/topics/OAuth2.md +427 -0
- package/discord-api-docs/docs/topics/Opcodes_and_Status_Codes.md +306 -0
- package/discord-api-docs/docs/topics/Permissions.md +229 -0
- package/discord-api-docs/docs/topics/RPC.md +1597 -0
- package/discord-api-docs/docs/topics/Rate_Limits.md +126 -0
- package/discord-api-docs/docs/topics/Teams.md +80 -0
- package/discord-api-docs/docs/topics/Threads.md +163 -0
- package/discord-api-docs/docs/topics/Voice_Connections.md +282 -0
- package/discord-api-docs/images/API_center.gif +0 -0
- package/discord-api-docs/images/ask-to-join.gif +0 -0
- package/discord-api-docs/images/available-published.png +0 -0
- package/discord-api-docs/images/button-styles.png +0 -0
- package/discord-api-docs/images/certified-device.png +0 -0
- package/discord-api-docs/images/command-with-groups-subcommands-parameters.png +0 -0
- package/discord-api-docs/images/command-with-groups-subcommands.png +0 -0
- package/discord-api-docs/images/command.png +0 -0
- package/discord-api-docs/images/cpp-files-sdk.png +0 -0
- package/discord-api-docs/images/create-store-channel.png +0 -0
- package/discord-api-docs/images/deferred-example.png +0 -0
- package/discord-api-docs/images/desktop-select.png +0 -0
- package/discord-api-docs/images/game-overlay-sdk-invite.gif +0 -0
- package/discord-api-docs/images/game-overlay-sdk-voice-settings.png +0 -0
- package/discord-api-docs/images/game-overlay-sdk-voice-widget.png +0 -0
- package/discord-api-docs/images/gift-code-creation.png +0 -0
- package/discord-api-docs/images/lib-linked-sdk.png +0 -0
- package/discord-api-docs/images/message-command.png +0 -0
- package/discord-api-docs/images/mobile-select.png +0 -0
- package/discord-api-docs/images/previous-new-server-background.png +0 -0
- package/discord-api-docs/images/rp-actionable.png +0 -0
- package/discord-api-docs/images/rp-all-fields.png +0 -0
- package/discord-api-docs/images/rp-bad-art.png +0 -0
- package/discord-api-docs/images/rp-good-art.png +0 -0
- package/discord-api-docs/images/rp-legend.png +0 -0
- package/discord-api-docs/images/rp-long-strings.png +0 -0
- package/discord-api-docs/images/rp-non-actionable.png +0 -0
- package/discord-api-docs/images/rp-not-all-fields.png +0 -0
- package/discord-api-docs/images/rp-profile-example-1.png +0 -0
- package/discord-api-docs/images/rp-profile-example-2.png +0 -0
- package/discord-api-docs/images/rp-short-strings.png +0 -0
- package/discord-api-docs/images/server-banner-example.png +0 -0
- package/discord-api-docs/images/server-banner-margin-top.png +0 -0
- package/discord-api-docs/images/sku-management.png +0 -0
- package/discord-api-docs/images/snowflake.png +0 -0
- package/discord-api-docs/images/snowflake_original_size.png +0 -0
- package/discord-api-docs/images/spectate.gif +0 -0
- package/discord-api-docs/images/team-2fa.png +0 -0
- package/discord-api-docs/images/team-make-app.png +0 -0
- package/discord-api-docs/images/team-page.png +0 -0
- package/discord-api-docs/images/transfer-app-to-team.png +0 -0
- package/discord-api-docs/images/user-command.png +0 -0
- package/discord-api-docs/package-lock.json +3186 -0
- package/discord-api-docs/package.json +38 -0
- package/discord-api-docs/tsconfig.eslint.json +4 -0
- package/discord-api-docs/tsconfig.json +19 -0
- package/mod.js +14 -0
- package/mod.ts +24 -0
- package/package.json +28 -0
- package/tsconfig.json +24 -0
- package/types.ts +5334 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
# Branches and Builds
|
|
2
|
+
|
|
3
|
+
> info
|
|
4
|
+
> Need help with Dispatch? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
|
|
5
|
+
|
|
6
|
+
In order for other people to download your game from Discord's servers, you need to _upload_ your game to Discord's servers. Let's learn how to do that!
|
|
7
|
+
|
|
8
|
+
## Getting Set Up
|
|
9
|
+
|
|
10
|
+
First, get Dispatch for your operating system.
|
|
11
|
+
|
|
12
|
+
- [Windows 64](https://dl-dispatch.discordapp.net/download/win64)
|
|
13
|
+
- [Windows 32](https://dl-dispatch.discordapp.net/download/win32)
|
|
14
|
+
- [Mac](https://dl-dispatch.discordapp.net/download/macos)
|
|
15
|
+
- [Linux](https://dl-dispatch.discordapp.net/download/linux)
|
|
16
|
+
|
|
17
|
+
You'll want to be able to use Dispatch across your projects, so let's handle that now by adding it to our PATH.
|
|
18
|
+
|
|
19
|
+
**MacOS/Linux:**
|
|
20
|
+
|
|
21
|
+
Bust out those \*nix skills.
|
|
22
|
+
|
|
23
|
+
- Open your choice of terminal
|
|
24
|
+
- Stick dispatch in a folder that will be added to your PATH. If you don't have a good spot for this stuff already, you can `mkdir ~/bin/` and call that Dispatch's new home (as well as any other executables you might want to access in the future)
|
|
25
|
+
- In that folder, run `chmod u+x dispatch-macos` so that Dispatch can be used as an executable
|
|
26
|
+
- Feel free to also rename `dispatch-macos` to just `dispatch` if you don't feel like typing so much
|
|
27
|
+
- Add that ~/bin directory to your path in a permanent way. I have `export PATH=$PATH:~/bin` at the bottom of my `~/.zshrc`, or `~/.bashrc`
|
|
28
|
+
- Restart your terminal
|
|
29
|
+
- `echo $PATH` and make sure you see the directory in the output
|
|
30
|
+
- Run `dispatch --help` to make sure it works
|
|
31
|
+
|
|
32
|
+
You're good! You can now call the dispatch command from anywhere!
|
|
33
|
+
|
|
34
|
+
**Windows**
|
|
35
|
+
|
|
36
|
+
Not as 1337 as some scripting skillz, but the Windows GUI will do just fine
|
|
37
|
+
|
|
38
|
+
- Stick `dispatch-x64` or `dispatch-x86`, depending on your OS, in a folder that will be added to your PATH
|
|
39
|
+
- Feel free to rename it to just `dispatch` if you don't feel like typing so much
|
|
40
|
+
- Hit that Windows key and start typing "Environment Variables"
|
|
41
|
+
- Select "Edit the system environment variables"
|
|
42
|
+
- Hit the "Environment Variables" button in the bottom right
|
|
43
|
+
- Edit the PATH entry for either the system or the current user, adding dispatch's directory
|
|
44
|
+
- Restart your command line
|
|
45
|
+
- Run `dispatch --help` to make sure it works
|
|
46
|
+
|
|
47
|
+
You're good! You can now call the dispatch command from anywhere!
|
|
48
|
+
|
|
49
|
+
> info
|
|
50
|
+
> Want some really fancy skills? You can set up autocompletions for dispatch in whatever shell you work.
|
|
51
|
+
> Run `dispatch completions -—help` to see instructions for a variety of popular shells.
|
|
52
|
+
|
|
53
|
+
## Authorizing Yourself to Use It
|
|
54
|
+
|
|
55
|
+
Run `dispatch login`, which will open a web browser and prompt you to authorize your Discord account with Dispatch.
|
|
56
|
+
|
|
57
|
+
Yup, that's it.
|
|
58
|
+
|
|
59
|
+
Small thing to note - the default `login` method works via an OAuth2 bearer token with special scopes. That means that if you run `dispatch login` on another machine—like a CI setup—it will invalidate your other tokens. If you want to set up build machines for your game, you'll want to use an alternate method of authorization.
|
|
60
|
+
|
|
61
|
+
First, find the `credentials.json` file at:
|
|
62
|
+
|
|
63
|
+
- Windows: `C:\Users\<you>\.dispatch\credentials.json`
|
|
64
|
+
- macOS: `~/.dispatch/credentials.json`
|
|
65
|
+
|
|
66
|
+
Inside that, we can use our Bot token for our application that will _not_ be invalidated across different machines.
|
|
67
|
+
|
|
68
|
+
> info
|
|
69
|
+
> Note that this token is only good for its owning application, so if you want to make one build machine deploy multiple applications, you'll need to edit this file per game.
|
|
70
|
+
|
|
71
|
+
You can get your bot token by going to your app in the Dev Portal --> `Bot` --> `Add Bot` --> copy the token. In our credentials file, replace the JSON with:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"BotCredentials": {
|
|
76
|
+
"application_id": "my_application_id",
|
|
77
|
+
"token": "my_token"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Voila! You can now use dispatch for that application with this token.
|
|
83
|
+
|
|
84
|
+
ONWARDS!
|
|
85
|
+
|
|
86
|
+
## Creating Branches
|
|
87
|
+
|
|
88
|
+
> warn
|
|
89
|
+
> If you have not yet set up a Team and an application, please follow the steps in [Get Set Up](#DOCS_GAME_SDK_SDK_STARTER_GUIDE/get-set-up)
|
|
90
|
+
|
|
91
|
+
Now that we're set up to use the tool, let's make some branches! Branches, builds, and everything in between in Discord are tied to an application. To get one for your game, ask a Discord team member to hook you up!
|
|
92
|
+
|
|
93
|
+
Then, head over to our [developer portal](https://discord.com/developers/), click into that new application, and copy the `Client Id` at the top of the page, keeping it handy throughout this process. Client ID and "application id" are interchangeable phrases. For the rest of this documentation, we'll refer to it as application id.
|
|
94
|
+
|
|
95
|
+
Back to your terminal, type:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
dispatch branch create <application_id> <branch_name>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This will create a named branch under that application id that can be pushed to. You can see your branches with:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
dispatch branch list <application_id>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Setting Up Our First Build
|
|
108
|
+
|
|
109
|
+
In order for Discord to understand what you're sending, you need to set up a config file for your game. This config file tells Discord which files to bundle together, how to run them, and other metadata to include. You should keep this file safe in your version control system of choice; that way, Discord is always up to date with whatever you've got locally. You'll reference these manifests later when building your store pages, so that Discord knows what to download to someone's computer when they hit that Big Buy Button.
|
|
110
|
+
|
|
111
|
+
Let's break an example `config.json` file down into pieces, and then put it together at the end.
|
|
112
|
+
|
|
113
|
+
## Basic Information
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
{
|
|
117
|
+
"application": {
|
|
118
|
+
"id": 467102538279999224,
|
|
119
|
+
"manifests": []
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
This is the top level of the config file. It has an `application` object at the top. `id` is your application id. `manifests` are the heart of this file, and offer a lot of customization for tagging and uploading data for the build. Let's jump into that now.
|
|
125
|
+
|
|
126
|
+
## Labels, Platforms, and Local Roots
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
{
|
|
130
|
+
"label": "my-awesome-game/windows",
|
|
131
|
+
"platforms": ["win32", "win64"],
|
|
132
|
+
"locales": [],
|
|
133
|
+
"local_root": "./game-files/windows",
|
|
134
|
+
"redistributables": [
|
|
135
|
+
"directx_june_2010"
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
We're in the heart of a manifest now! `label` is the name you want to give an individual manifest/bundle of files. Make these easily identifiable so you can reference them later in your store page creation.
|
|
141
|
+
|
|
142
|
+
`platforms` are the platforms for which the manifest is valid. Most simple configs, like our example, will use the same manifest for `win32` and `win64`, and then make other manifests for `macos` and `linux`. However, some older games may need specific configurations for 32bit and 64bit systems, and therefore need separate manifests.
|
|
143
|
+
|
|
144
|
+
`locales` is an array of locales for which the manifest is valid; leaving it empty denotes it's valid for all locales. For example, your base game files will probably have an empty `locales` array, but you may other manifests for things like language packs defined for `es-ES` or `fr` or other locales.
|
|
145
|
+
|
|
146
|
+
`local_root` is the relative path to the directory that contains the raw game files to upload for this manifest. This may be particularly useful if you have multiple manifests with different relative root directories, like:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
// Imaginary directory structure:
|
|
150
|
+
// C:\game\binary
|
|
151
|
+
// C:\game\langs\en-US
|
|
152
|
+
// C:\game\langes\fr
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
"manifests": [
|
|
156
|
+
{
|
|
157
|
+
"label": "game-files",
|
|
158
|
+
"local_root": "binary"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"label": "english-language-pack",
|
|
162
|
+
"local_root": "en-US"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"label": "french-language-pack",
|
|
166
|
+
"local_root": "fr"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
That way, you can `dispatch build push` from your actual root directory, but dispatch will be smart enough to separate the files properly.
|
|
173
|
+
|
|
174
|
+
`redistributables` is an array of any redistributable packages your game may need to function, like a certain install of DirectX, or a Microsoft C++ redistributable. A list of valid values can be found in [Field Values](#DOCS_DISPATCH_FIELD_VALUES/).
|
|
175
|
+
|
|
176
|
+
## File Rules
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
{
|
|
180
|
+
"file_rules": {
|
|
181
|
+
"mappings": [
|
|
182
|
+
{
|
|
183
|
+
"local_path": ".",
|
|
184
|
+
"install_path": "."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"local_path": "./languages/en-US/no-but-the-data-is-really-in-here/",
|
|
188
|
+
"install_path": "./english"
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
"properties": [
|
|
192
|
+
{
|
|
193
|
+
"install_path": "save/*",
|
|
194
|
+
"attributes": ["user_data"]
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"exclusions": [
|
|
198
|
+
{
|
|
199
|
+
"local_path": "**/*.pdb"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"local_path": "**/*.verycoolfile"
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
File rules is a special, and somewhat confusing, part of the manifest, but we'll get through it together! The `file_rules` object lets you:
|
|
210
|
+
|
|
211
|
+
1. Specify the way in which files get installed on a user's computer
|
|
212
|
+
2. Mark files as protected, so they don't get overwritten
|
|
213
|
+
3. Exclude certain files from being uploaded
|
|
214
|
+
|
|
215
|
+
`mappings` lets you tell Dispatch to download files to a certain place in the install directory on a user's machine, letting you create the folder structure you need. Your game build files may be tucked deep in a subdirectory on your machine, because who ever cleans up folder structures, but you can make sure it looks nice and clean for your players.
|
|
216
|
+
|
|
217
|
+
`properties` allows you to mark properties on globs of files. In this case, marking a glob of files as `user_data` tells Dispatch not to touch these files in any way if it sees them; don't want that save data overwritten!
|
|
218
|
+
|
|
219
|
+
`exclusions` also allow you to mark off globs of files. File globs here will not be uploaded by Dispatch on a build push. In the above example, debug files that match the `*.pdb` or `*.verycoolfile` patterns in any directory will be ignored.
|
|
220
|
+
|
|
221
|
+
> warn
|
|
222
|
+
> Dispatch supports [Rust globbing patterns](https://docs.rs/glob/0.2.11/glob/struct.Pattern.html).
|
|
223
|
+
|
|
224
|
+
## Cloud Storage
|
|
225
|
+
|
|
226
|
+
```js
|
|
227
|
+
{
|
|
228
|
+
"storage": {
|
|
229
|
+
"sync": true,
|
|
230
|
+
"roots": [
|
|
231
|
+
{
|
|
232
|
+
"id": "my-save-files",
|
|
233
|
+
"paths": [
|
|
234
|
+
{
|
|
235
|
+
"platform": "windows",
|
|
236
|
+
"path": "${DOCUMENTS}/My Games/My Awesome Game/Saves"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"platform": "macos",
|
|
240
|
+
"path": "${DOCUMENTS}/Games/My Awesome Game/Saves"
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
"patterns": ["**/*"]
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Discord supports cloud saves! Let's learn how to use it! This piece of the manifest, `storage`, helps Discord support cloud saves for your game. When `sync` is set to `true`, Discord will look in the `paths` provided here for any files that match one of the `patterns`. If it finds any, it will sync them to the cloud, so your user will have access to them across machines.
|
|
251
|
+
|
|
252
|
+
If you are **not** using our [Storage Manager](#DOCS_GAME_SDK_STORAGE/) to manage your game's save files, make sure to outline your save paths and file glob patterns here.
|
|
253
|
+
|
|
254
|
+
If you **are** using the Storage Manager in the GameSDK, just set `sync` to `true` and omit the `roots` key.
|
|
255
|
+
|
|
256
|
+
> danger
|
|
257
|
+
> `id` must be a constant, immutable value once set. You can pick whatever you'd like when first set, but ensure it does not change afterwards. Otherwise, Discord may incorrectly overwrite and/or delete users' save data.
|
|
258
|
+
|
|
259
|
+
We support a number of filepath replacements/shorteners like `{$DOCUMENTS}`, so you can have something like `${SAVEDGAMES}/My Awesome Game/${USERID}` and create user-specific save files. No longer will you need to worry about your little brother overwriting your save file! For the full list of path replacements, see [Cloud Save Path Replacements](#DOCS_DISPATCH_FIELD_VALUES/manifests-cloud-save-path-replacements).
|
|
260
|
+
|
|
261
|
+
As a side note, there may be a case where you might have multiple manifests that each have storage information defined. In the case that the two manifests define the same storage path but have _conflicting_ data, the source of truth will be the manifest that appears **later** in the array in the config file. So, if you have:
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
{
|
|
265
|
+
"manifests": [
|
|
266
|
+
{
|
|
267
|
+
"label": "one",
|
|
268
|
+
"storage": {
|
|
269
|
+
"sync": true,
|
|
270
|
+
"roots": [
|
|
271
|
+
{
|
|
272
|
+
"id": "one",
|
|
273
|
+
"paths": [
|
|
274
|
+
{
|
|
275
|
+
"platform": "windows",
|
|
276
|
+
"path": "${HOME}"
|
|
277
|
+
}
|
|
278
|
+
],
|
|
279
|
+
"patterns": ["**/*"]
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"label": "two",
|
|
286
|
+
"storage": {
|
|
287
|
+
"sync": true,
|
|
288
|
+
"roots": [
|
|
289
|
+
{
|
|
290
|
+
"id": "two",
|
|
291
|
+
"paths": [
|
|
292
|
+
{
|
|
293
|
+
"platform": "windows",
|
|
294
|
+
"path": "${HOME}"
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
"patterns": ["**/*"]
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Then, manifest `two` would be the source of truth in a data conflict. Wew, ok, good work. On to the next part!
|
|
307
|
+
|
|
308
|
+
## Registry Keys and Install Scripts
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
{
|
|
312
|
+
"install_scripts": [
|
|
313
|
+
{
|
|
314
|
+
"name": "SDB Compatibility",
|
|
315
|
+
"executable": "Install.bat",
|
|
316
|
+
"arguments": ["/silent"],
|
|
317
|
+
"requires_admin": true,
|
|
318
|
+
"platforms": ["win32", "win64"],
|
|
319
|
+
"completion_registry_key": {
|
|
320
|
+
"key": "Software\\My Game Company\\InstallScripts\\SDB-win32",
|
|
321
|
+
"value": 1
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
],
|
|
325
|
+
"registry_keys": [
|
|
326
|
+
{
|
|
327
|
+
"key": "Software\\My Game Company\\My Awesome Game\\FixAspctRatio",
|
|
328
|
+
"value": "1"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Some games may need specific registry keys set after installation, or might have some installation scripts that need to be run. If so, those can be set here!
|
|
335
|
+
|
|
336
|
+
For installation scripts, `name` is a user friendly name that Discord will surface to users when explaining what's happening during the installation process. `executable` is the name of the script that needs to be run. `arguments` is an array that takes any arguments that may need to be passed to the script. `requires_admin`, when marked `true`, will run the install scripts with admin privileges; for some Windows users, this may force a User Access Control security popup. You must also tell Discord the `completion_registry_key` of the scripts, so that we know not to try and run the script again if the given registry key is found on the user's machine.
|
|
337
|
+
|
|
338
|
+
`registry_keys` is a simple array of key/value pairs that will be written to the user's computer's registry. By default, Discord will create these keys in `HKEY_CURRENT_USER`. If your game requires registry keys in `HKEY_LOCAL_MACHINE`, they can be specified like:
|
|
339
|
+
|
|
340
|
+
```js
|
|
341
|
+
{
|
|
342
|
+
"key": "HKEY_LOCAL_MACHINE\\SOFTWARE\\My Game Company\\My Awesome Game\\MagicFix",
|
|
343
|
+
"value": "1"
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Don't forget to the notice the double backward slashes in the path name!
|
|
348
|
+
|
|
349
|
+
## Launch Options
|
|
350
|
+
|
|
351
|
+
```js
|
|
352
|
+
{
|
|
353
|
+
"launch_options": [
|
|
354
|
+
{
|
|
355
|
+
"name": "My Awesome Game",
|
|
356
|
+
"executable": "my-awesome-game.exe",
|
|
357
|
+
"arguments": [],
|
|
358
|
+
"platforms": ["win32", "win64"],
|
|
359
|
+
"working_dir": "important-files-here/"
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"name": "My Awesome Map Editor",
|
|
363
|
+
"executable": "my-awesome-map-editor.exe",
|
|
364
|
+
"arguments": [],
|
|
365
|
+
"platforms": ["win32", "win64"],
|
|
366
|
+
"working_dir": "important-files-here/"
|
|
367
|
+
}
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
The last bit of the config file is the launch options for your game. This is where you should tell Discord which executables your game can launch. In most cases, you'll just have one object, which is the main executable for your game. However, in the case that your game may have multiple executables that users can launch, you can specify all of them here.
|
|
373
|
+
|
|
374
|
+
> warn
|
|
375
|
+
> The `name` field _must_ be unique for each launch option.
|
|
376
|
+
|
|
377
|
+
When launching the game from their Game Library, players will be able to choose which executable is being launched, with the first option in the list as the default. So, for example, if your game comes with the game and a map editor, they'll have access to both without needing multiple entries in their library. Discord will smartly remember their choice for the future, but they'll always have the option to swap to a different one if they want.
|
|
378
|
+
|
|
379
|
+
You can also specify any arguments that need to be passed to your game on launch, like `--fullscreen` or `--console` or `--360-no-scope`.
|
|
380
|
+
|
|
381
|
+
If your game needs to have a specific working directly, you can also specify that here. Otherwise we'll default to the `content/` folder in the install directory.
|
|
382
|
+
|
|
383
|
+
> danger
|
|
384
|
+
> Currently, `executable` and `working_dir` are relative to the _install path_ on a user's machine, not your local root. This path is `${INSTALLDIR}/content/` unless otherwise specified in [File Rules](#DOCS_DISPATCH_BRANCHES_AND_BUILDS/file-rules).
|
|
385
|
+
|
|
386
|
+
## All Together Now
|
|
387
|
+
|
|
388
|
+
Let's see what one looks like all together!
|
|
389
|
+
|
|
390
|
+
```js
|
|
391
|
+
{
|
|
392
|
+
"application": {
|
|
393
|
+
"id": 467102538279999224,
|
|
394
|
+
"manifests": [
|
|
395
|
+
{
|
|
396
|
+
"label": "my-awesome-game/windows",
|
|
397
|
+
"platforms": ["win32", "win64"],
|
|
398
|
+
"locales": [],
|
|
399
|
+
"local_root": "./",
|
|
400
|
+
"file_rules": {
|
|
401
|
+
"mappings": [
|
|
402
|
+
{
|
|
403
|
+
"local_path": ".",
|
|
404
|
+
"install_path": "."
|
|
405
|
+
}
|
|
406
|
+
],
|
|
407
|
+
"properties": [
|
|
408
|
+
{
|
|
409
|
+
"install_path": "save/*",
|
|
410
|
+
"attributes": ["user_data"]
|
|
411
|
+
}
|
|
412
|
+
],
|
|
413
|
+
"exclusions": [
|
|
414
|
+
{
|
|
415
|
+
"local_path": "**/*.pdb"
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
"local_path": "**/*.verycoolfile"
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
"storage": {
|
|
423
|
+
"sync": true,
|
|
424
|
+
"roots": [
|
|
425
|
+
{
|
|
426
|
+
"id": "my-save-files",
|
|
427
|
+
"paths": [
|
|
428
|
+
{
|
|
429
|
+
"platform": "windows",
|
|
430
|
+
"path": "${DOCUMENTS}/My Games/My Awesome Game/Saves"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"platform": "macos",
|
|
434
|
+
"path": "${DOCUMENTS}/Games/My Awesome Game/Saves"
|
|
435
|
+
}
|
|
436
|
+
],
|
|
437
|
+
"patterns": ["**/*"]
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
},
|
|
441
|
+
"install_scripts": [
|
|
442
|
+
{
|
|
443
|
+
"name": "SDB Compatibility",
|
|
444
|
+
"executable": "Install.bat",
|
|
445
|
+
"arguments": ["/silent"],
|
|
446
|
+
"requires_admin": true,
|
|
447
|
+
"platforms": ["win32", "win64"],
|
|
448
|
+
"completion_registry_key": {
|
|
449
|
+
"key": "Software\\My Game Company\\InstallScripts\\SDB-win32",
|
|
450
|
+
"value": 1
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
"registry_keys": [
|
|
455
|
+
{
|
|
456
|
+
"key": "Software\\My Game Company\\My Awesome Game\\FixAspctRatio",
|
|
457
|
+
"value": "1"
|
|
458
|
+
}
|
|
459
|
+
],
|
|
460
|
+
"launch_options": [
|
|
461
|
+
{
|
|
462
|
+
"name": "My Awesome Game",
|
|
463
|
+
"executable": "my-awesome-game.exe",
|
|
464
|
+
"arguments": [],
|
|
465
|
+
"platforms": ["win32", "win64"],
|
|
466
|
+
"working_dir": "important-files-in-here/"
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"name": "My Awesome Map Editor",
|
|
470
|
+
"executable": "my-awesome-map-editor.exe",
|
|
471
|
+
"arguments": [],
|
|
472
|
+
"platforms": ["win32", "win64"],
|
|
473
|
+
"working_dir": "important-files-in-here/"
|
|
474
|
+
}
|
|
475
|
+
]
|
|
476
|
+
}
|
|
477
|
+
]
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
It seems like a lot of lines to parse, but now you know what they all mean!
|
|
483
|
+
|
|
484
|
+
## Multiple Manifests and DLC Content
|
|
485
|
+
|
|
486
|
+
If you're publishing a game with additional DLC content, this section is for you! Oftentimes in newer games, a user purchasing DLC content does not necessarily mean them downloading additional files to their computer, like expansion packs of ye olden days. A game will see that a user is entitled to a new thing, some flag in the code will flip, and presto! They can now explore the new area.
|
|
487
|
+
|
|
488
|
+
However, some games do rely on downloading additional files for DLC content. If that is the case with your game, let's see how Dispatch can help. What's gonna help here is making use of multiple manifests. When you create a `config.json` file to upload your game, you've got something that looks sort of like this:
|
|
489
|
+
|
|
490
|
+
```json
|
|
491
|
+
// A much smaller config example than the behemoth just above
|
|
492
|
+
{
|
|
493
|
+
"application": {
|
|
494
|
+
"id": 1234567890,
|
|
495
|
+
"manifests": [
|
|
496
|
+
{
|
|
497
|
+
// a bunch of stuff
|
|
498
|
+
}
|
|
499
|
+
]
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
"manifests" is an array, which means it can contain multiple items. What you'll want to do is create two manifests: one for your base game, and one for your DLC. Depending on how your build folder is set up, you can exclude the DLC files from being uploaded when you upload the base game. Let's pretend your build folder—the one on your local computer that you're uploading from—looks like this:
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
game/
|
|
508
|
+
|_ config.json
|
|
509
|
+
|_ build/
|
|
510
|
+
|_ game_data
|
|
511
|
+
|_ Assets/
|
|
512
|
+
|_ AssetBundles/
|
|
513
|
+
|_ Base/
|
|
514
|
+
|_ DLC/
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Your manifest would look something like this:
|
|
518
|
+
|
|
519
|
+
```
|
|
520
|
+
{
|
|
521
|
+
"application": {
|
|
522
|
+
"id": your_app_id,
|
|
523
|
+
"manifests": [
|
|
524
|
+
{
|
|
525
|
+
"label": "base-game",
|
|
526
|
+
"local_root": "build",
|
|
527
|
+
"file_rules": {
|
|
528
|
+
"mappings": [
|
|
529
|
+
{
|
|
530
|
+
"local_path": ".", // This makes the files appear in the base content/ directory, trust me :D
|
|
531
|
+
"install_path": "."
|
|
532
|
+
}
|
|
533
|
+
],
|
|
534
|
+
"exclusions": [
|
|
535
|
+
{
|
|
536
|
+
"local_path": "./game_data/Assets/AssetBundles/DLC" // This manifest will NOT include the DLC
|
|
537
|
+
}
|
|
538
|
+
]
|
|
539
|
+
},
|
|
540
|
+
// The rest of the config with launch options, etc.
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"label": "dlc", // Now we have a second manifest for the DLC files
|
|
544
|
+
"local_root": "build/game_data/Assets/AssetBundles/DLC", // Uploading files from the DLC folder
|
|
545
|
+
"file_rules": {
|
|
546
|
+
"mappings": [
|
|
547
|
+
{
|
|
548
|
+
"local_path": ".",
|
|
549
|
+
"install_path": "./game_data/Assets/AssetBundles/DLC" // Puts the DLC in the proper folder structure
|
|
550
|
+
}
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
]
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
So, what we've done is defined two manifests—or bundles of files—in one config. Now, how do we make 'em work?
|
|
560
|
+
|
|
561
|
+
When you create SKUs in the dev portal, you assign manifests to SKUs. You'll want to assign `base-game` to your base game SKU, and `dlc` to your DLC. Now, when players buy your base game, they'll get entitlement to the `base-game` manifest, and Discord will only download that one. Once they purchase `dlc`, they'll become entitled to that manifest, and Discord will patch the game with the new content they received.
|
|
562
|
+
|
|
563
|
+
## DRM
|
|
564
|
+
|
|
565
|
+
You can choose to add DRM to your game. Dispatch will wrap your executables and prevent a user from launching the game if they are not logged into Discord.
|
|
566
|
+
|
|
567
|
+
> danger
|
|
568
|
+
> This is a destructive operation. It will wrap your executable in place. It will not back up your executable. Make sure you have a backup somewhere else.
|
|
569
|
+
|
|
570
|
+
If you understand and agree to the above, run the following command on each of the executables you want to wrap.
|
|
571
|
+
|
|
572
|
+
```
|
|
573
|
+
dispatch build drm-wrap <application_id> <path_to_executable_to_wrap>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
This function will only work with Windows executables. If you want to wrap a unix executable, you'll need to instead use [ValidateOrExit](#DOCS_GAME_SDK_APPLICATIONS/validateorexit).
|
|
577
|
+
|
|
578
|
+
## Pushing Our First Build
|
|
579
|
+
|
|
580
|
+
We've got all our files ready for processing; let's ship this baby!
|
|
581
|
+
|
|
582
|
+
```
|
|
583
|
+
dispatch build push <branch_id> <path_to_config> <path_to_files_to_upload>
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
You'll see a bunch of request logging as it gets sent up to Discord—when it's done, you're greeted with a friendly completion message:
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
[2018-06-14][11:38:51][INFO] Pushed build. build_id=456889899375656960
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
To double check that it's all ready for publishing, run:
|
|
593
|
+
|
|
594
|
+
```
|
|
595
|
+
dispatch build list <application_id> <branch_id>
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
You'll see a table with the current status of your builds. Once the one you uploaded is marked as READY, you're good to publish it to the masses!
|
|
599
|
+
|
|
600
|
+
## Publishing Our First Build
|
|
601
|
+
|
|
602
|
+
Once you're ready to make a build live, run:
|
|
603
|
+
|
|
604
|
+
```
|
|
605
|
+
dispatch build publish <application_id> <branch_id> <build_id>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
To make sure it worked, you can again run:
|
|
609
|
+
|
|
610
|
+
```
|
|
611
|
+
dispatch branch list <application_id>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
And look for a `LIVE_BUILD_ID` under your application!
|
|
615
|
+
|
|
616
|
+
## Downloading a Build for Testing
|
|
617
|
+
|
|
618
|
+
Now that you've got a build pushed and published, we should make sure that what you've sent out into the world works as intended. You can download your published build on a given branch to your local machine with the command:
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
dispatch build update <application_id> <branch_id> <install_path> --platform <value> --locale <value>
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
`install_path` is any filepath on your local machine; this is where the files will be downloaded to. `--platform` and `--locale` are whatever values you set as valid platforms and locales in your config file for a given build. The default probably looks something like `win64` and `en-US`.
|
|
625
|
+
|
|
626
|
+
Here's an example of the command with our info:
|
|
627
|
+
|
|
628
|
+
```
|
|
629
|
+
dispatch build update 467102538279999224 456889899375659999 C:\my-game --platform win64 --locale en-US
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
Now you can run the executable for your game in that directory and make sure it works!
|
|
633
|
+
|
|
634
|
+
## Patching
|
|
635
|
+
|
|
636
|
+
If you need to push out a patch or a new build, no problem! Just repeat the process:
|
|
637
|
+
|
|
638
|
+
- Update your game files locally to whatever they need to be
|
|
639
|
+
- Push your build again
|
|
640
|
+
- Publish the build again
|
|
641
|
+
- List your branches to make sure the new build is live
|
|
642
|
+
|
|
643
|
+
Discord will do some magic in the background to diff your files, ensuring that your players only have to download the changes they need and letting them do it quickly so they can get back in the game. Or, really, without them even needing to know there _was_ a patch! Your players will automatically download your latest and greatest stuff, and quickly!
|
|
644
|
+
|
|
645
|
+
If you have your own patcher and do not want Discord to handle patching, set `"should_patch": false` in the application configuration. If `should_patch` is false, Discord will install the game and never patch, even if you update your game. On uninstall, Discord will delete the entire directory, including saves and user data.
|
|
646
|
+
|
|
647
|
+
```js
|
|
648
|
+
{
|
|
649
|
+
"application": {
|
|
650
|
+
"id": 467102538279999224,
|
|
651
|
+
"should_patch": false,
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Dispatch and You
|
|
2
|
+
|
|
3
|
+
> info
|
|
4
|
+
> Need help with Dispatch? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
|
|
5
|
+
|
|
6
|
+
If you're distributing a game on Discord, you'll need to send us the files! We quickly learned that email has a file size limit, and we ran out of carrier pigeons. Don't ask. Very touchy subject.
|
|
7
|
+
|
|
8
|
+
In light of those learnings, we built Dispatch! Great name, isn't it? _Dis_-patch? Anyway, Dispatch is your all-in-one uploader tool to get your builds, artwork, patches, DLC, and anything else onto Discord's servers. It's fast, easy to use, and I've been assured by our engineers that it's made of 100% farm-raised, cage-free, grass-fed code.
|
|
9
|
+
|
|
10
|
+
If you are looking to update your store page, head on over to our handy dandy [Developer Portal](https://discord.com/developers). It has all the tools you need to make changes to your store page for your game. To view your store page either make a store channel in the server you selected for your application and choose the SKU that you made the store page for or you can just hit the view store page button in the discord developer portal.
|
|
11
|
+
|
|
12
|
+
Let's get you pointed in the right direction; follow this little Table of Contents to start, and you'll be a pro with this tool faster than you can say "But wait I don't actually know what a terminal is."
|
|
13
|
+
|
|
14
|
+
1. [Creating Branches and Upload Builds](#DOCS_DISPATCH_BRANCHES_AND_BUILDS/)
|
|
15
|
+
2. [Pre-defined Field Values](#DOCS_DISPATCH_FIELD_VALUES/)
|
|
16
|
+
|
|
17
|
+
Hey, some cool community folks have made unofficial tools around dispatch, check them out [here](#DOCS_TOPICS_COMMUNITY_RESOURCES).
|