@fabi-play/protocol

中文文档
0.9.0发布于 2026/11/14SEE LICENSE IN LICENSETypeScriptES Module零依赖近 30 天下载 2081

手机、屏幕和游戏之间的信息 以及他们的支票.

中文使用文档
文档目录9 节
  1. 游戏介绍
  2. 盖面
  3. 方向
  4. 两个屏幕上的旋转木马
  5. 电线上的可能性
  6. 许可证
  7. 电视遥控器
  8. 箭头作为光标
  9. 手机上的图片

@ fabi-play/ protocol (英语)

电话、屏幕和游戏之间的信息 Fabi 游戏,用他们的支票: 地标P, (中文(简体) ), Body),玩家,年龄乐队,游戏表 (fabi-play.json, (中文(简体) ), parseManifest,以及 JSON Schema),和剖析方 运行在其得到的.

npm install @fabi-play/protocol
import { parseManifest, AGE_RANGES, type GameManifest } from '@fabi-play/protocol'

const result = parseManifest(JSON.parse(text))
if ('errors' in result) console.error(result.errors)

名单的JSON斯克马: @fabi-play/protocol/fabi-play.schema.json (同样在SDK旁边服役) https://cdn.fabiplay.app (英语)无害环境管理,包括类型,不依赖。 文档 : https://docs.fabiplay.app (英语)。 。 。 .

游戏介绍

清单的可选性 intro (单位:千美元)GameIntro: 1到4个步骤,每个句子在一幅相片或一幅相片上),就是法比所想的 校正前在电视上说,请看"Fabi解释你的游戏" @fabi-play/sdk 读取。 。 。 . parseManifest 报告有什么不对劲 (a) 与《公约》有关的规定; parseIntro 给予介绍或无效(电视跳过一个坏的,包括未知的字段), introText 页:1 语言和年龄.

  • 判决:每个语言最多90个字符,计为NFC格式的Unicode代码点(一个emoji是 ; 两端没有空白; 没有控制字符、 单独代位或双向控制 (U+202A–U+202E,U+2066–U+2069). JSON Schema也这么说 除了孤独的代孕者和NFC计数 便携式JSON Schema regexes无法表达: parseManifest 这是参考文献.
  • 路径 (单位:千美元)entry,一个步骤的 image:相对于游戏地址,没有方案,没有领先 /没有空的, . 或者说 .. 片段,最多200个字符; ASCII 字母的片段, 数字, _ 财务报告和审定财务报表 - (口袋在里面,不是第一个); 小写扩展 : .html 页:1 entry, (中文(简体) ), .jpg 或者说 .png 图像( e)intro/track.jpg没有 intro/Track.PNG. 没有WebP:旧电视浏览器(WebKit基于Tizen 2.x,webOS 1–2)可能无法解码. JPG (质量) 大约80个),用于截图,PNG只用于平面艺术.
  • 语音短片:一个句子的片断在 voiceClipUrl(base, locale, voiceKeySync(text, locale)),这是 ${base}/voice/${FABI_VOICE}/${locale}/${key}.mp3,每个语言一个文件夹(voiceKey 与约同; voiceClipUrl 抛出在本地地址上,但 it 或者说 en) (中文(简体) ). 键是 UTF-8 字节中的 SHA-256 的第一个32个小写十六进制字符 `${FABI_VOICE}\n${locale}\n${t}` (单位:千美元)FABI_VOICE 实值 fabi-v1),在其中 t 是 Unicode NFC 中的文本,使用 Java 脚本 trim() 已应用; 有效句子周围没有空白, 因此对于任何语言的生成器 t 只是NFC的文本。 这么说吧 voiceKeySync('Salta!', 'it') 实值 cbd16ba39816bdc5afd34a3e84082331 及其剪辑 https://cdn.fabiplay.app/voice/fabi-v1/it/cbd16ba39816bdc5afd34a3e84082331.mp3。 。 。 . voiceUrl(base, key)旧的 没有本地文件夹的平面布局, 已贬值 。 SHA-256为平原JavaScript,, 同步: 无 crypto.subtle因此,它在电视网页上工作,服务于http、旧的电视浏览器和节点18 软件包 engines) (中文(简体) ).
  • 电话的按钮: 在介绍期间,电话发送 { type: 'intro', action },有动作 next, (中文(简体) ), repeat, (中文(简体) ), skip,或 replay (从暂停菜单:再次解释);屏幕告诉它什么是法比 说 { type: 'intro', step, steps, text, voice }。 。 phase 信件携带 intro: true 当 游戏有介绍:只有这样,电话才会提供 replay。 。 。 .

盖面

清单的可选性 cover 是游戏目录中的游戏卡片: 游戏的16: 9 图像( 建议 1280x720) 拥有文件, cover.jpg。 。 。 . parseManifest 检查路径( e)isCoverPath: 相对、无计划、无领导 /,没有 倒斜,没有空的, . 或者说 .. 部分, .jpg, (中文(简体) ), .jpeg, (中文(简体) ), .png 或者说 .webp 小写,最多 COVER_MAX_PATH, (中文(简体) ), (原始内容存档于2017-10-12). 128, phone. 文件本身由 Fabi Play 的审查检查, 常数导出在此 : COVER_MAX_BYTES (15万个), COVER_ASPECT (第16/9号决议) COVER_ASPECT_TOLERANCE (0.02,相对数) isCoverAspect(width, height)· ; COVER_EXTENSIONS 财务报告和审定财务报表 COVER_RECOMMENDED (1280×720) (中文(简体) ).

方向

清单的可选性 orientations 列出游戏可以玩的屏幕取向( e)Orientation数字 : 'landscape' | 'portrait',他们全部在 ORIENTATIONS:非空地,不重复;没有手段 ['landscape'],哪个 gameOrientations(manifest) 适用。 一个电话(“Gioca qui / Play here”)是直立的 只提供列表的游戏 'portrait'电视和石碑都是景观 屏幕说方向a 游戏开始于 init.orientation (单位:千美元)orientationOf(width, height): 宽度( h): 'landscape'; 缺席 旧宿主,意思是 'landscape'。这是信息:一个游戏的外观大小.

瞄准目标. aimPoint(body | frame, side, { orientation, view }) 一条规则是 手对准 屏幕(它碰到的),分数:地平面 toScreen(view, wrist); 在肖像中, 相机图像所在之处 在电话底部很小,手腕被肩膀伸到整个屏幕上(HAND_SPACE,则 长度 PlayerFrame.leftHand,被夹到0–1;臀部看不见的躯干至少是 TORSO_PER_SHOULDER_WIDTH 肩宽。 当手腕(在肖像上,肩膀也一样)不见时,是无效的 (单位:千美元)AIM_VISIBLE) (中文(简体) ). AimHold {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}把一只失落的手藏起来 AIM_HOLD_MS (300) (英语). SDK的车 play.aim 编辑 发动机 hands() 应用它.

安全区. init.safeArea (可选的)是电话的出处, 圆角和家酒吧封面, 分数 在游戏的取景口: { top, bottom, left, right } (单位:千美元)SafeArea) (中文(简体) ). parseSafeArea 每边夹到0-0.25 (单位:千美元)MAX_SAFE_INSET失踪时为0; NO_SAFE_AREA 是所有0, 什么主机不发送它的意思.

局部姿势. init.localPoses (可选)是 true 当画面中的尸体来自同一个相机 设备作为屏幕(单独播放的电话或平板电脑),而不是网络上的电话。 然后SDK滑动 默认情况下插出变相器较轻( 空闲度: 要吸收的不快), 除非游戏给出 (单位:千美元) smooth 数额。 缺席(老年人主机,电话发送到电视)是指 false。 。 。 .

电话可以显示电视机的旋转木马游戏,两者同时移动. 成年的刷子,电话发出 { type: 'focus', game } (CaptainMessage) 对于它中心卡片: 仅一个预览,没有开始(pick 开始 (游戏) 屏幕将同一张牌集中,并用其声音(屏幕拥有声音 电话保持安静。 当屏幕的旋转木马因任何其他原因而移动时(遥控器、手光标、另一个) 电话,它发送 { type: 'focus', game } (ScreenMessage)和电话跟随. 都一样 pick (单位:千美元)isGameId; 其目录中没有游戏的一面忽略了消息.

电线上的可能性

电话流 { type: 'pose', t, bodies } 在一个无序、无转发的数据上每秒约30次 频道. 列表的屏幕 POSE_CODEC_VERSION 致欢迎词binaryPose: [1],参见 acceptsBinaryPose获得 在二进制中, encodePose 电话和 decodePose 在屏幕上; 任何其他屏幕都得到 JSON 和屏幕 都读了 版本 1, 小- endian :

折减大小外地
0 个1个魔术 0xFB
1个1个编码版本, 1
2个1个类型, 1=姿势
3个1个尸体数,0-4
页:1第8条t,浮点64 (按电话钟计)
第12条每人132人33个地标 × 金特32:比特0-9 x-1000,10-19 y-1000,20-29能见度 1000,30-31 0

因此有12个+132×个活体字节(4个活体540个活体). 值为千分之一 toPlayerSpace 弹入,所以解码 姿势和JSON一样. decodePose 返回为空(长度错误,), 魔法,版本或类型,超过4个身体,值超过1000, t 永远不要扔.

大多数游戏只需要 @fabi-play/sdk,它包括它使用的东西 从这个包裹.

许可证

Fabi Play Kit License:可自由使用,仅用于为Fabi Play制作游戏和工具. 见 自由主义。 。 。 .

电视遥控器

清单的可选性 inputs (单位:千美元)GameInput[]从 GAME_INPUTS数字 : body, (中文(简体) ), remote; 缺席 ["body"],参见 gameInputs),表示在没有电话的情况下,游戏是否可以用电视遥控器来玩; parseManifest 需求 body 在其中,没有重复和未知值。 屏幕告诉游戏如何播放会话 init.input (缺席) 'body'和,与 'remote',是否远程点(init.pointerLG的魔法遥控器: 游戏页面中的普通指针和鼠标事件). 屏幕将密钥转换成手势( QQ 或 确定) jump, 举行 squat编号 :stand车道,好两次 clap,退后平台的暂停),一次扮演一个孩子:init's players 是孩子现在在玩(一个id)。 有几个孩子轮流玩游戏,他们的名单上写着 "turns": true (仅以 remote 内 inputs;这意味着游戏遵循回合合同;没有它,只有一个孩子: init.turns 按顺序列出每个儿童parseTurnOrder; 缺席 : players) (中文(简体) ). 游戏每个孩子玩一回合; 当 a 孩子们的圆末(也撞倒了) 转弯不动,它问 break('turn'),屏幕总是回答 break-start (它转动的屏幕), { type: 'turn', players: [2] } (确切地说,一个id,下一个顺序; parseTurnPlayers 检查其形状)和 break-done下一个孩子的傀儡就在中道 之后 最后一轮比赛以每个孩子的分数结束. level 财务报告和审定财务报表 gameover 课间休息从不交换玩家; 主机 在转弯前回答 turn 作为未知的原因,一次。 游戏按玩家ID保持分数. 见"用电视遥控器播放" @fabi-play/sdk 读取。 。 。 .

箭头作为光标

清单的可选性 "remoteCursor": true (仅以 remote 内 inputs)以远程模式询问屏幕, 将箭头变成自由光标而不是手势。 屏幕保存所持箭头并运行 KeyCursor 每个动画框( e)update(held, dtMs) → { x, y }, 0–1 游戏框: 初慢而快 箭头持有的时间越长,对面箭头取消,对角不快,被夹在边上,一个长相框计算 等于100毫秒; reset() 在游戏上方绘制光标,并发送 { type: 'cursor', x, y, down } (单位:千美元)parseCursor当它移动,当OK走下或上。 里面写着 pointer: true以魔术遥控器发誓, 这个 SDK在游戏的页面中将信件变成指针和鼠标事件,因此游戏无论用哪种方式都可以看到鼠标. 回来 保留平台的暂停; OK是光标的按钮, 不是跳出 .

手机上的图片

游戏可以在家庭手机上保存一张照片. 路径和消息:

  1. 屏幕告诉游戏是否可以: init.pictures 当它改变时, { type: 'capabilities', pictures }。这是真实的,当一个电话 hello 说 pictures: true 链接( app; 网络电话) 不说).
  2. 游戏发送 { type: 'picture', data, title?, id? } (游戏): data a base64 数据 URL, data:image/jpeg 或者说 data:image/png最多 MAX_PICTURE_BYTES (3 MiB of image),其字节真正开始为 该类型(checkPicture· ; parseGameMessage 其他东西都丢掉); title 最多 MAX_PICTURE_TITLE (60个) 字符,由 parsePictureTitle。 。 。 .
  3. 屏幕通过他们可靠 订购的数据频道发送到手机上 片段,因为数据频道 不要携带多兆字节消息( 16 KiB 是每个浏览器需要的) : chunkPicture(dataUrl, id, title) 给 { type: 'picture-start', id, mime, size, title? } (单位:千美元)size 在图像的字节中),然后 { type: 'picture-chunk', id, seq, data } (单位:千美元)PICTURE_CHUNK_CHARS16,000个基数64,每个但最后一个, seq 从 0 开始;那么, JSON 的每个消息都保持在 16 KiB 以内 { type: 'picture-end', id } (史记.
  4. 电话给他们喂的 PictureAssembler (按任意顺序划出;缺少块,超过极限的图片,a) 块过其大小, 字节不是该开始的类型, 全部失败有原因) 和答案 { type: 'picture-saved', id } 或者说 { type: 'picture-failed', id } (主计长发言).
  5. 屏幕回答游戏 { type: 'picture-result', id, result } (单位:千美元)parsePictureResult: 'sent', (中文(简体) ), 'unavailable', (中文(简体) ), 'too-big' 或者说 'error'。 。 。 .

隐私:照片只通过直接链接(WebRTC,加密)通过电视 手机,从未通过或进入服务器, 其它地方也没有副本 Games只能这样发送一个JPEG或PNG图像.

版本与发布记录

@fabi-play/protocol 共发布 10 个版本,首次发布于 2026/11/05;过去 12 个月发布了 10 个版本。

版本发布日期距今
0.9.0latest2026/11/14今天
0.8.02026/11/14今天
0.7.12026/11/095 天前
0.7.02026/11/095 天前
0.5.02026/11/086 天前
0.4.02026/11/086 天前

关于 @fabi-play/protocol 的常见问题

@fabi-play/protocol 是什么?

手机、屏幕和游戏之间的信息 以及他们的支票.

如何安装 @fabi-play/protocol?

在项目目录运行 npm install @fabi-play/protocol,或使用 pnpm add / yarn add / bun add。

@fabi-play/protocol 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fabi-play/protocol 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@fabi-play/protocol 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@fabi-play/protocol 可以商用吗?

@fabi-play/protocol 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@fabi-play/protocol 的下载量有多少?

根据 npm 官方下载统计,@fabi-play/protocol 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,081 次,日均约 69 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fabi-play/protocol 还在维护吗?

最新版本 0.9.0 发布于 2026/11/14(今天);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/11/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。