hopple 0.0.0 → 0.1.0-rc.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/LICENSE ADDED
@@ -0,0 +1,40 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The Hopple authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ --------------------------------------------------------------------------------
24
+
25
+ The files `hopple create` writes into a new project are not under the license
26
+ above. They are under the BSD Zero Clause License (0BSD), so a game made from
27
+ them owes nothing to anyone:
28
+
29
+ Copyright (c) 2026 The Hopple authors
30
+
31
+ Permission to use, copy, modify, and/or distribute this software for any
32
+ purpose with or without fee is hereby granted.
33
+
34
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
35
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
37
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
38
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
39
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
40
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # hopple: the command line
2
+
3
+ The command-line tool for game developers:
4
+
5
+ - `hopple create` starts a new game with the recommended setup (optional).
6
+ - `hopple dev` runs a built game in the **dev shell**, a host made for
7
+ testing, which runs it with the same code as the real clients.
8
+ - `hopple check` says whether a game can be published, and `hopple publish`
9
+ uploads it to a Hopple server.
10
+ - `hopple list`, `login`, `logout` and `whoami` manage what you've published
11
+ and who you publish as.
12
+
13
+ It is a dev dependency of the game (`npm install --save-dev hopple`, which
14
+ `hopple create` sets up), run with `npx hopple`. It is one compiled file with
15
+ no dependencies, and needs Node 22.18 or later.
16
+
17
+ `hopple` is not a bundler. It takes a game that is already built, by
18
+ whatever tool the game uses.
19
+
20
+ ## The project's config
21
+
22
+ `dev`, `check` and `publish` work on a **project**: a directory with a hopple
23
+ config in it. They find it in the current directory, or the nearest one above
24
+ it (like `tsconfig.json`). The config says everything they need to know:
25
+
26
+ ```ts
27
+ // hopple.config.ts
28
+ import type { HoppleConfig } from '@hopple/sdk';
29
+
30
+ export default {
31
+ build: 'npm run build',
32
+ page: 'dist/index.html',
33
+ manifest: {
34
+ schema: 1,
35
+ id: 'my-game',
36
+ version: '0.1.0',
37
+ title: 'My Game',
38
+ orientation: 'portrait',
39
+ sdk: '^0.1.0',
40
+ audio: null,
41
+ },
42
+ } satisfies HoppleConfig;
43
+ ```
44
+
45
+ - **`build`** (optional) is the command that builds the game. It runs first, in
46
+ the config's directory, and a failed build stops the command. So
47
+ `npx hopple publish` can't upload a stale build. `--no-build` skips it.
48
+ - **`page`** is the built HTML file, relative to the config. It is the one file
49
+ that is played in the dev shell and published, so it must contain the whole
50
+ game.
51
+ - **`manifest`** is what the game is: its id, title, description, and what it
52
+ declares. See [the manifest's reference](https://docs.hopple.app/manifest.md).
53
+
54
+ Only the page and the manifest are uploaded; `build` and `page` never leave
55
+ your machine.
56
+
57
+ The config can be `hopple.config.ts`, `hopple.config.js` (both default-export
58
+ it) or `hopple.config.json` (which is it). A TypeScript config needs no build
59
+ of its own: Node runs it. Any other key is an error, so a misspelt `build`
60
+ can't be silently skipped, and two configs in one directory are an error too.
61
+
62
+ A JSON config can start with
63
+ `"$schema": "./node_modules/@hopple/sdk/config.schema.json"` for completion
64
+ and errors in an editor, the manifest's included.
65
+
66
+ ## Commands
67
+
68
+ ```
69
+ hopple create <dir>
70
+ hopple dev [project] [--port <n>] [--no-build]
71
+ hopple check [project] [--no-build]
72
+ hopple publish [project] [--server <url>] [--no-build]
73
+ hopple list [--server <url>]
74
+ hopple login [--server <url>]
75
+ hopple logout [--server <url>]
76
+ hopple whoami [--server <url>]
77
+ hopple --version
78
+ ```
79
+
80
+ `[project]` is a project's directory (or a directory inside it), or its config
81
+ file. Left out, it is the current directory.
82
+
83
+ The server is taken from `--server`, then `$HOPPLE_SERVER`, then
84
+ `https://hopple.app`. It is named by its site; the CLI finds the API under
85
+ `/api` on it.
86
+
87
+ ### `hopple create`
88
+
89
+ ```bash
90
+ npx hopple create my-game
91
+ cd my-game && npm install
92
+ npx hopple dev # build, then play it in the dev shell
93
+ npm run watch # in another terminal: rebuild on every change, then reload the shell
94
+ npx hopple publish # build, check, then publish
95
+ ```
96
+
97
+ Writes a new project into `<dir>`, which must be new or empty. The directory's
98
+ name becomes the game's id (lowercase letters, digits and hyphens). It is the
99
+ recommended setup, not a requirement:
100
+
101
+ - **Vite** builds it, with `vite-plugin-singlefile` inlining every script,
102
+ style and imported asset into `dist/index.html`.
103
+ - **`hopple.config.ts`** builds with `npm run build` (typecheck with `tsc`,
104
+ then bundle), names `dist/index.html` as the page, and holds the manifest.
105
+ Being TypeScript, a mistake in the manifest is a type error.
106
+ - **There is no `publish` script**: `npm publish` would run it, then upload the
107
+ project to the npm registry. The project is also `"private": true`.
108
+ - `src/game.ts` is a small working game (a ball you keep in the air) that uses
109
+ the SDK the way every game should: `init`, the loop, layout, input and pause.
110
+
111
+ A game built any other way (another bundler, or a hand-written HTML file) is
112
+ played and published with the same commands, once it has a config.
113
+
114
+ ### `hopple dev`
115
+
116
+ ```bash
117
+ npx hopple dev # this project's game, built: http://localhost:5173
118
+ npx hopple dev path/to/project --port 8080
119
+ ```
120
+
121
+ The dev server serves:
122
+
123
+ - `/`: the dev shell.
124
+ - `/game/`: the config's `page`, and `/game/…` the other files in its
125
+ directory, with CORS enabled and caching disabled. Nothing outside that
126
+ directory is served.
127
+
128
+ A valid manifest is shown in the shell. An invalid or missing one is reported
129
+ in the terminal and on the page, naming the bad fields, and the game still
130
+ runs. The config is read again every time the shell page loads, so **an edited
131
+ manifest shows up on reload**, with no restart. So does a rebuilt game.
132
+
133
+ It plays a build that loads files from beside its page (a separate script, a
134
+ stylesheet, images), but says in the terminal that it can't be published like
135
+ that.
136
+
137
+ **With no project to be found**, the shell starts empty and waits for a URL
138
+ like `/?server=<server url>&game=<owner>/<name>@<version>`. The admin pages'
139
+ "Dev shell" button opens exactly that, so you can run any uploaded game (yours
140
+ or someone else's) in the dev shell. The shell downloads the game and its
141
+ manifest from that server's feed and runs it exactly as it would a local build.
142
+
143
+ ### `hopple check`
144
+
145
+ ```bash
146
+ npx hopple check # this project's game, built
147
+ npx hopple check --no-build # as it was last built
148
+ ```
149
+
150
+ Everything `publish` checks before it uploads, without uploading:
151
+
152
+ 1. The manifest validates.
153
+ 2. The **page** exists, and loads nothing from outside itself: no
154
+ `<script src>`, stylesheet `<link>`, `<img>` or CSS `url()` that isn't a
155
+ `data:` URL. Only that one file is published, so it must contain the whole
156
+ game, with every script and asset inlined. (Files the game's code fetches
157
+ can't be seen this way; they fail the same way.)
158
+
159
+ It exits with 1 and says what is wrong, or prints the game's id, version and
160
+ size.
161
+
162
+ ### `hopple publish`
163
+
164
+ ```bash
165
+ npx hopple publish # this project's game, built
166
+ npx hopple publish path/to/project
167
+ ```
168
+
169
+ 1. Makes every check `hopple check` makes, so mistakes are caught before
170
+ anything is uploaded.
171
+ 2. Uploads the manifest and the page, and publishes them as
172
+ `<your username>/<manifest id>`, as a new version. The game is listed with
173
+ the manifest's `title` and `description`: to change them, change the
174
+ manifest.
175
+ 3. Prints the version's address, whether it is live, and a link that opens that
176
+ exact version.
177
+
178
+ If you are a trusted user or an admin, the version goes live immediately.
179
+ Otherwise it waits for an admin to review it, and the previous live version
180
+ (if any) stays in the feed meanwhile.
181
+
182
+ ### `hopple login`, `logout`, `whoami`, `list`
183
+
184
+ - The first command that talks to a server starts an **anonymous session**,
185
+ so you can publish without an account.
186
+ - `hopple login` signs that same session in. It prints a link and a short
187
+ code, and waits: open the link in a browser where you are signed in to the
188
+ site (or sign in there, any way the site offers), check that the page shows
189
+ the same code, and approve. Nothing is typed in the terminal, and the link
190
+ can be opened on another machine. It is good for ten minutes.
191
+ Anything you published anonymously from this machine moves into your account.
192
+ - `hopple whoami` shows who you are on that server and how you signed in.
193
+ - `hopple logout` ends the session and forgets it.
194
+ - `hopple list` shows each game you've published, its live version, its
195
+ newest version if different (and whether it is waiting for review), and a
196
+ link to each.
197
+
198
+ Sessions are stored per server in `~/.config/hopple/sessions.json` (or under
199
+ `$XDG_CONFIG_HOME`, or `$HOPPLE_CONFIG_DIR` if set), readable only by you.
200
+ The file contains your session tokens, so treat it like a password.
201
+
202
+ Every request names the CLI and its version (`User-Agent: hopple-cli/<version>`).
203
+ The server uses that to count games published and terminals signed in from
204
+ the CLI, under your Hopple player in our usage analytics. Nothing else is
205
+ collected, and nothing is collected on your machine. Set `DO_NOT_TRACK=1` to
206
+ leave your publishes and sign-ins out of those counts.
207
+
208
+ ## The dev shell
209
+
210
+ The dev shell runs the game the way real hosts do (same sandbox, same bridge),
211
+ but surrounds it with controls for testing. Its panel (opened from the rail's
212
+ handle or the corner button) has:
213
+
214
+ - **Device**: the frame's shape (portrait phone, landscape phone, or the whole
215
+ browser window), where the host's buttons go, and a fake notch.
216
+ - **Lifecycle**: switch the game between `active`, `passive` and `hidden`; the
217
+ log shows the orders each one sends (sound, loop, resources). Ping it.
218
+ - **Info**: device tier, locale, whether the player is returning, and "be a new
219
+ player". Each of these **restarts the game**, because info is only sent once,
220
+ at the start.
221
+ - **Manifest**: what the game declares.
222
+ - **The log**: every analytics event, every refusal, every save read, write and
223
+ clear (with sizes), every share link, and every error the game threw, with
224
+ its stack. An error also shows over the game until it is read, and is
225
+ printed in the terminal `hopple dev` runs in: once with its stack, then again
226
+ only when it has been thrown 10, 100, 1000… times, and whole again after a
227
+ restart.
228
+
229
+ Switches that make the host misbehave on purpose, so you can see your game
230
+ cope:
231
+
232
+ - Reserve the host's buttons even though the game said `draw-under`.
233
+ - A host with no save store, a full one, or one that takes 2 seconds to reply.
234
+ - A host with no scores, no achievements, no panel, no input settings, no
235
+ audio settings, or that never asks the game to pause. These restart the game,
236
+ since what a host offers is settled at the start.
237
+ - Analytics rate limits like a real host's: 10 events a second, 15 in 15
238
+ seconds, 30 a minute.
239
+
240
+ What each feature does in the shell:
241
+
242
+ | Feature | In the dev shell |
243
+ |---|---|
244
+ | Save | Stored in the browser's `localStorage`. The panel shows what is stored, its size and age, and can delete it. |
245
+ | Score | A made-up leaderboard, so you can see how a rank looks before any real players exist. You can set the range. Your submitted scores join it. Reloading generates a new one. |
246
+ | Achievements | Kept in memory for one player. *Reset* clears them **without** restarting the game (the running game keeps what it was told, just as in a real client). |
247
+ | Share | Every link (the game's, or the rail's Share button) gets a record kept in the browser's `localStorage`: where it came from, and the game's `data` and `meta`. The record is written to the log, the link is copied to the clipboard, and the game is told `copied`. Opening the link in the same browser restarts the game with that data. *Open without the link* drops it. |
248
+ | Panel | The same panel as a real host's, with the game's pages in it. The game can ask for one; opening the panel yourself, on the game's pages or on others, shows how the game reacts to a panel it didn't ask for. |
249
+ | Input | The key-binding page, and a switch for which input device the player is using. |
250
+ | Sound | Mute, master volume and a slider per declared channel, in the panel, on the game's page. The log says whether the game answered with the mix it was asked for. |
251
+ | Pause | A button in the corner, shown only when the game says it can pause. |
252
+
253
+ ## License
254
+
255
+ MIT; see `LICENSE`. The files `hopple create` writes into a new
256
+ project are under 0BSD instead, so a game made from them owes nothing to
257
+ anyone. The license covers the code, not the Hopple name or logo.
@@ -0,0 +1,138 @@
1
+ The hopple CLI includes the following packages, under the licenses below.
2
+
3
+ --------------------------------------------------------------------------------
4
+
5
+ @stylexjs/stylex 0.15.4 (MIT)
6
+
7
+ Licensed under MIT. The package ships no license text.
8
+
9
+ --------------------------------------------------------------------------------
10
+
11
+ react-dom 19.2.3 (MIT)
12
+
13
+ MIT License
14
+
15
+ Copyright (c) Meta Platforms, Inc. and affiliates.
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in all
25
+ copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ SOFTWARE.
34
+
35
+ --------------------------------------------------------------------------------
36
+
37
+ react-strict-dom 0.0.55 (MIT)
38
+
39
+ MIT License
40
+
41
+ Copyright (c) Meta Platforms, Inc. and affiliates.
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ of this software and associated documentation files (the "Software"), to deal
45
+ in the Software without restriction, including without limitation the rights
46
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ copies of the Software, and to permit persons to whom the Software is
48
+ furnished to do so, subject to the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be included in all
51
+ copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
56
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
59
+ SOFTWARE.
60
+
61
+ --------------------------------------------------------------------------------
62
+
63
+ react 19.2.3 (MIT)
64
+
65
+ MIT License
66
+
67
+ Copyright (c) Meta Platforms, Inc. and affiliates.
68
+
69
+ Permission is hereby granted, free of charge, to any person obtaining a copy
70
+ of this software and associated documentation files (the "Software"), to deal
71
+ in the Software without restriction, including without limitation the rights
72
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
73
+ copies of the Software, and to permit persons to whom the Software is
74
+ furnished to do so, subject to the following conditions:
75
+
76
+ The above copyright notice and this permission notice shall be included in all
77
+ copies or substantial portions of the Software.
78
+
79
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
81
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
82
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
83
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
84
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
85
+ SOFTWARE.
86
+
87
+ --------------------------------------------------------------------------------
88
+
89
+ scheduler 0.27.0 (MIT)
90
+
91
+ MIT License
92
+
93
+ Copyright (c) Meta Platforms, Inc. and affiliates.
94
+
95
+ Permission is hereby granted, free of charge, to any person obtaining a copy
96
+ of this software and associated documentation files (the "Software"), to deal
97
+ in the Software without restriction, including without limitation the rights
98
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
+ copies of the Software, and to permit persons to whom the Software is
100
+ furnished to do so, subject to the following conditions:
101
+
102
+ The above copyright notice and this permission notice shall be included in all
103
+ copies or substantial portions of the Software.
104
+
105
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
106
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
107
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
108
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
109
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
110
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
111
+ SOFTWARE.
112
+
113
+ --------------------------------------------------------------------------------
114
+
115
+ uqr 0.1.3 (MIT)
116
+
117
+ MIT License
118
+
119
+ Copyright (c) Project Nayuki
120
+ Copyright (c) 2023 Anthony Fu <https://github.com/antfu>
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining a copy
123
+ of this software and associated documentation files (the "Software"), to deal
124
+ in the Software without restriction, including without limitation the rights
125
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
126
+ copies of the Software, and to permit persons to whom the Software is
127
+ furnished to do so, subject to the following conditions:
128
+
129
+ The above copyright notice and this permission notice shall be included in all
130
+ copies or substantial portions of the Software.
131
+
132
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
133
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
134
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
135
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
136
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
137
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
138
+ SOFTWARE.