@fabi-play/protocol 0.0.0-stage → 0.2.0
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 +76 -0
- package/README.md +75 -2
- package/dist/index.d.ts +741 -0
- package/dist/index.js +605 -0
- package/fabi-play.schema.json +176 -0
- package/package.json +52 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Fabi Play Kit License
|
|
2
|
+
Version 1.0 (DRAFT, not yet reviewed by a lawyer)
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Fabi Play. All rights reserved.
|
|
5
|
+
|
|
6
|
+
This license applies to the Fabi Play Kit: the packages @fabi-play/protocol, @fabi-play/motion,
|
|
7
|
+
@fabi-play/avatars, @fabi-play/sdk and @fabi-play/engine, in source and built form, as published on npm, served
|
|
8
|
+
from https://cdn.fabiplay.app or found in this repository, including their code, type declarations, documentation,
|
|
9
|
+
avatar artwork and other assets (together, the "Kit").
|
|
10
|
+
|
|
11
|
+
1. Free of charge, for Fabi Play only
|
|
12
|
+
|
|
13
|
+
Fabi Play grants you a worldwide, non-exclusive, non-transferable, non-sublicensable, royalty-free license to
|
|
14
|
+
use, copy, and modify the Kit, and to distribute it as part of a Permitted Work, solely to make, test, run and
|
|
15
|
+
distribute Permitted Works.
|
|
16
|
+
|
|
17
|
+
A "Permitted Work" is a game, tool, or other software made to run on, be published on, or support the
|
|
18
|
+
development of games for the Fabi Play platform (https://fabiplay.app), including games submitted to Fabi Play
|
|
19
|
+
and tools used to build, test or preview them.
|
|
20
|
+
|
|
21
|
+
2. What is not allowed
|
|
22
|
+
|
|
23
|
+
You may not, without Fabi Play's prior written permission:
|
|
24
|
+
|
|
25
|
+
a. use the Kit, or any part or modified version of it, in software that is not a Permitted Work, including in
|
|
26
|
+
any other game platform, product or service;
|
|
27
|
+
b. distribute the Kit, or a modified version of it, on its own or as a library, SDK, engine or framework for
|
|
28
|
+
others to build with, other than as part of a Permitted Work (installing it from npm or loading it from
|
|
29
|
+
https://cdn.fabiplay.app is not a distribution by you);
|
|
30
|
+
c. sell, rent or sublicense the Kit itself;
|
|
31
|
+
d. remove or alter this license, copyright notices, or the license banners in the built files;
|
|
32
|
+
e. use the avatars, the mascot "Fabi", or the name, logos or other trademarks of Fabi Play, except as the Kit
|
|
33
|
+
does when it runs inside a Permitted Work. This license grants no trademark rights;
|
|
34
|
+
f. use the Kit to circumvent, interfere with or misrepresent the Fabi Play platform, its safety, privacy or
|
|
35
|
+
parental controls, or its rules for games.
|
|
36
|
+
|
|
37
|
+
3. Visible, not open source
|
|
38
|
+
|
|
39
|
+
The Kit's code is published so that developers can read it, debug with it and build Permitted Works. Being
|
|
40
|
+
visible does not make it open source; no rights are granted beyond those stated here.
|
|
41
|
+
|
|
42
|
+
4. Your works
|
|
43
|
+
|
|
44
|
+
You keep all rights in your own code and content. This license does not give Fabi Play any rights in your
|
|
45
|
+
Permitted Works; publishing a game on Fabi Play is governed by Fabi Play's separate developer terms.
|
|
46
|
+
|
|
47
|
+
5. Feedback
|
|
48
|
+
|
|
49
|
+
If you send Fabi Play suggestions or changes for the Kit, Fabi Play may use them without obligation to you.
|
|
50
|
+
|
|
51
|
+
6. Termination
|
|
52
|
+
|
|
53
|
+
This license ends automatically if you break its terms. If you fix the breach within 30 days of becoming aware
|
|
54
|
+
of it, the license is reinstated, unless Fabi Play has already told you in writing that it is terminated. On
|
|
55
|
+
termination you must stop using and distributing the Kit. Permitted Works already distributed to end users in
|
|
56
|
+
compliance with this license may continue to be used by those end users.
|
|
57
|
+
|
|
58
|
+
7. No warranty
|
|
59
|
+
|
|
60
|
+
THE KIT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
61
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
62
|
+
|
|
63
|
+
8. Limitation of liability
|
|
64
|
+
|
|
65
|
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL FABI PLAY OR ITS CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
|
|
66
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
67
|
+
CONNECTION WITH THE KIT OR THE USE OR OTHER DEALINGS IN THE KIT.
|
|
68
|
+
|
|
69
|
+
9. Changes to this license
|
|
70
|
+
|
|
71
|
+
Fabi Play may publish new versions of this license. Each version of the Kit is governed by the license version
|
|
72
|
+
it is distributed with, unless you choose to accept a later version.
|
|
73
|
+
|
|
74
|
+
10. Contact
|
|
75
|
+
|
|
76
|
+
For permissions beyond this license: https://fabiplay.app
|
package/README.md
CHANGED
|
@@ -1,3 +1,76 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @fabi-play/protocol
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The messages between the phone, the screen and the games of [Fabi Play](https://fabiplay.app), with their checks:
|
|
4
|
+
the body landmarks (`P`, `Body`), players, age bands, the game manifest (`fabi-play.json`, `parseManifest`, and its
|
|
5
|
+
JSON Schema), and the parsers every side runs on what it receives.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @fabi-play/protocol
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { parseManifest, AGE_RANGES, type GameManifest } from '@fabi-play/protocol'
|
|
13
|
+
|
|
14
|
+
const result = parseManifest(JSON.parse(text))
|
|
15
|
+
if ('errors' in result) console.error(result.errors)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The manifest's JSON Schema: `@fabi-play/protocol/fabi-play.schema.json` (also served next to the SDK on
|
|
19
|
+
https://cdn.fabiplay.app). ESM only, types included, no dependencies. Docs: https://docs.fabiplay.app.
|
|
20
|
+
|
|
21
|
+
## The game intro
|
|
22
|
+
|
|
23
|
+
A manifest's optional `intro` (`GameIntro`: 1 to 4 steps, each a sentence over an image or a move) is what Fabi
|
|
24
|
+
says on the TV before calibration; see "Fabi explains your game" in the
|
|
25
|
+
[`@fabi-play/sdk` README](https://www.npmjs.com/package/@fabi-play/sdk). `parseManifest` reports what is wrong with
|
|
26
|
+
it; `parseIntro` gives the intro or null (the TV skips a bad one, unknown fields included), `introText` the
|
|
27
|
+
sentence for a locale and age.
|
|
28
|
+
|
|
29
|
+
- **Sentences**: up to 90 characters per language, counted as Unicode code points of the NFC form (an emoji is
|
|
30
|
+
one); no white space at either end; no control characters, lone surrogates or bidirectional controls
|
|
31
|
+
(U+202A–U+202E, U+2066–U+2069). The JSON Schema says the same, except lone surrogates and the NFC count, which
|
|
32
|
+
portable JSON Schema regexes can't express: `parseManifest` is the reference.
|
|
33
|
+
- **Paths** (`entry`, a step's `image`): relative to the game's address, no scheme, no leading `/`, no empty, `.` or
|
|
34
|
+
`..` segments, up to 200 characters; segments of ASCII letters, digits, `_` and `-` (dots inside, not first);
|
|
35
|
+
extensions in lowercase: `.html` for `entry`, `.jpg` or `.png` for images (`intro/track.jpg`, not
|
|
36
|
+
`intro/Track.PNG`). No WebP: old TV browsers (WebKit-based Tizen 2.x, webOS 1–2) may not decode it. JPG (quality
|
|
37
|
+
about 80) for screenshots, PNG only for flat art.
|
|
38
|
+
- **Voice clips**: a sentence's clip is at `voiceUrl(base, voiceKeySync(text, locale))` (`voiceKey` is the same as
|
|
39
|
+
a promise). The key is the first 32 lowercase hex characters of SHA-256 of the UTF-8 bytes of
|
|
40
|
+
`` `${FABI_VOICE}\n${locale}\n${t}` `` (`FABI_VOICE` is `fabi-v1`), where `t` is the text in Unicode NFC with
|
|
41
|
+
JavaScript's `trim()` applied; a valid sentence has no white space around it, so for a generator in any language
|
|
42
|
+
`t` is just the NFC text. So `voiceKeySync('Salta!', 'it')` is `cbd16ba39816bdc5afd34a3e84082331` and its clip
|
|
43
|
+
`https://cdn.fabiplay.app/voice/fabi-v1/cbd16ba39816bdc5afd34a3e84082331.mp3`. The SHA-256 is plain JavaScript,
|
|
44
|
+
synchronous: no `crypto.subtle`, so it works on TV pages served over http, old TV browsers and Node 18 (the
|
|
45
|
+
package's `engines`).
|
|
46
|
+
- **The phone's buttons**: during the intro the phone sends `{ type: 'intro', action }`, with action `next`,
|
|
47
|
+
`repeat`, `skip`, or `replay` (from the pause menu: the explanation again); the screen tells it what Fabi is
|
|
48
|
+
saying with `{ type: 'intro', step, steps, text, voice }`. Its `phase` message carries `intro: true` when the
|
|
49
|
+
game has an intro: only then does the phone offer `replay`.
|
|
50
|
+
|
|
51
|
+
## Poses on the wire
|
|
52
|
+
|
|
53
|
+
The phone streams `{ type: 'pose', t, bodies }` about 30 times a second over an unordered, no-retransmit data
|
|
54
|
+
channel. A screen that lists `POSE_CODEC_VERSION` in its welcome (`binaryPose: [1]`, see `acceptsBinaryPose`) gets
|
|
55
|
+
them in binary, `encodePose` on the phone and `decodePose` on the screen; any other screen gets JSON, and a screen
|
|
56
|
+
reads both. Version 1, little-endian:
|
|
57
|
+
|
|
58
|
+
| Offset | Size | Field |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| 0 | 1 | magic `0xFB` |
|
|
61
|
+
| 1 | 1 | codec version, 1 |
|
|
62
|
+
| 2 | 1 | kind, 1 = pose |
|
|
63
|
+
| 3 | 1 | body count, 0–4 |
|
|
64
|
+
| 4 | 8 | `t`, float64 (ms on the phone's clock) |
|
|
65
|
+
| 12 | 132 per body | 33 landmarks × uint32: bits 0–9 x·1000, 10–19 y·1000, 20–29 visibility·1000, 30–31 zero |
|
|
66
|
+
|
|
67
|
+
So 12 + 132 × bodies bytes (540 for 4 bodies). Values are the thousandths `toPlayerSpace` rounds to, so a decoded
|
|
68
|
+
pose holds exactly the numbers the JSON one would. `decodePose` returns null on anything else (wrong length,
|
|
69
|
+
magic, version or kind, more than 4 bodies, a value over 1000, `t` not finite) and never throws.
|
|
70
|
+
|
|
71
|
+
Most games need only [`@fabi-play/sdk`](https://www.npmjs.com/package/@fabi-play/sdk), which includes what it uses
|
|
72
|
+
from this package.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
Fabi Play Kit License: free to use, for making games and tools for Fabi Play only. See [LICENSE](./LICENSE).
|