@playbox-ai/playable-settings
v0.1.0
Published
Runtime settings contract for playable games
Readme
@playbox-ai/playable-settings
Runtime-настройки для TypeScript playable-игр. Пакет не имеет runtime-зависимостей и не импортирует Cocos Creator, Playable Kit, React или browser globals из корневого entrypoint.
Установка и лицензия
npm install @playbox-ai/playable-settingsПроприетарное ПО Playbox. Использование, включая коммерческое использование и распространение в составе playable, требует отдельного письменного разрешения или лицензии правообладателя. Доступность в npm сама по себе такого разрешения не предоставляет. См. LICENSE.
Публичные entrypoint'ы:
import { defineSettings } from '@playbox-ai/playable-settings';
import { attachSettingsPreview } from '@playbox-ai/playable-settings/preview';
import { connectSettingsHost } from '@playbox-ai/playable-settings/host';Корень работает в Node.js и обычном TypeScript-проекте. /preview и /host — браузерные адаптеры через window.postMessage; UI и storage в пакет не входят.
Модель выполнения
Игра объявляет одну схему. config — принятая конфигурация, подходящая для snapshot. values — активная конфигурация текущего запуска: live меняются сразу, startup ждут следующего startRun.
const settings = defineSettings({
speed: {
type: 'number', default: 5, apply: 'live',
label: 'Скорость', description: 'Скорость движения персонажа в метрах в секунду.',
group: 'Персонаж', ui: { min: 0, max: 20 },
},
totalTime: { type: 'number', default: 30, apply: 'startup' },
sound: { type: 'boolean', default: true, apply: 'live' },
mode: {
type: 'select', default: 'easy', apply: 'startup',
options: [{ value: 'easy' }, { value: 'hard' }],
},
}, {
onApply: ({ values, changed }) => updateLiveValues(values, changed),
});
await settings.startRun(values => createRound(values));
await settings.set({ speed: 8, totalTime: 45 });
// speed активен; totalTime ждёт нового startRun.label (название), description (пояснение обычным текстом), group, priority и showIf объявляются в игре и передаются оболочке в connection.schema. Оболочка отображает текст без интерпретации HTML; при отсутствии label использует ID, без description не выводит пояснение. Служебные подписи и сообщения редактора принадлежат оболочке.
ui.min, ui.max, ui.step описывают редакторский control и не ограничивают runtime. Для жёсткого ограничения используйте validate; для cross-field правил — schema validate. Преобразования строк и чисел не выполняются. Цвета нормализуются к lowercase #RRGGBB или #RRGGBBAA; числа должны быть конечными.
Результат операции содержит полное состояние. Статусы applied, restart_required, rejected, apply_failed показывают применение, отложенный startup, отказ проверки/конфликта и ошибку обработчика. После apply_failed принятая конфигурация сохраняется, а новый успешный startRun восстанавливает работу. Доступны reset, resetAll, restore, getSnapshot и subscribe.
Preview и host handshake
Preview подключается с точным parentOrigin и identity; host — с тем же identity и точным expectedOrigin. Обе стороны проверяют event.source и event.origin; транспорт использует namespace plbx:settings, protocol version 1 и точный targetOrigin.
const preview = attachSettingsPreview({
settings,
identity: { creativeId: 'creative-1', buildId: 'build-2' },
parentOrigin: 'https://editor.example',
initializeRun: values => createRound(values),
});
const initial = await preview.ready;
// После ready и независимого разрешения рекламного boot:
await settings.startRun(values => createRound(values));Родитель регистрирует listener до загрузки iframe:
const host = connectSettingsHost({
iframe,
expectedOrigin: 'https://game.example',
creativeId: 'creative-1',
buildId: 'build-2',
});
const connection = await host.connect();
// connection.schema: типы, label, description, options, group, showIf, priority.
// connection.capabilities.restart: доступность игрового перезапуска.
await host.initialize({ source: 'defaults' });
await host.set({ speed: 8 });
await host.restart({ configuration: 'current' });Host последовательно отправляет записи и использует последнюю revision. Timeout/disconnect после отправки означает неизвестный результат и не означает откат; повторять неизвестную запись автоматически нельзя. Неотправленная команда имеет известный исход. Runtime-отказы возвращаются как данные ChangeResult.
Hosting для standalone npm-игры
Игра, установленная из npm, не обязана объявлять window.plbx_html.settings: hosting обнаруживает attachSettingsPreview() по сообщению plbx:settings:available и повторно проверяет iframe через plbx:settings:probe. Передайте реальный origin родительской hosting-страницы. Списка разрешённых доменов в пакете нет; адрес можно определить при запуске. Для same-origin iframe используйте window.parent.location.origin, включая blob iframe с пустым referrer. Для cross-origin передайте origin через конфигурацию интеграции:
attachSettingsPreview({
settings,
identity: { creativeId: 'org/project/playable', buildId: 'deployment-id' },
parentOrigin: 'https://editor.example',
initializeRun: values => createRound(values),
})Уже скомпилированные Cocos-игры со старой версией пакета или жёстко заданным http://localhost:4174 discovery не получают автоматически. Обновите пакет, укажите hosting origin и пересоберите игру.
Snapshot, Restore и Reset
getSnapshot(identity) сохраняет всю принятую config, включая отложенные startup-поля, с formatVersion: 1, identity, типами, revision и eligibility. Сохраняйте только eligible; pending и failed не должны заменять последнюю пригодную запись.
Оболочка также проверяет отчёт initialization из initialize()/getState(): fallback на дефолты не должен автоматически затирать ранее сохранённый снимок. Для нового buildId начинайте с defaults; Restore предыдущего билда выполняйте только по явному действию пользователя.
restore проверяет identity и схему. Неизвестные ID, изменившиеся типы, удалённые варианты select и ошибки полевых проверок попадают в skipped; совместимые поля проходят общую проверку атомарно. reset(id) меняет одно поле, resetAll() меняет defaults без скрытого restart. Для атомарного Reset + нового запуска используйте startRun(..., { configuration: 'defaults' }).
Hosting adapter and build
Hosting also accepts plbx_html.settings({ fields, values, applyValues, validate, restart }). applyValues(values, changed) applies one accepted batch. validate(candidate) returns issues before engine mutation. Startup fields require restart(values); live-only declarations may omit it. The old apply(id, value) callback is rejected rather than risking partial reset/restore.
Supported types: number, range, angle, boolean, enum, select, tags, string, text, color, asset, easing, vec2, vec3, transform, readonly. Compound values are immutable JSON. tags.options, when present, limits membership; duplicates reject. readonly can only be changed by the game. showIf accepts an equality map or { parameter, equals }; priority sorts descending. Editor-only uniform is not part of a transform value.
Разработка
npm run typecheck
npm test
npm packnpm pack пересобирает пакет. Архив включает только JS, TypeScript declarations,
README, LICENSE и package.json. В игре не требуются runtime-зависимости пакета.
Cocos Creator 3.x web projects consume the package and explicitly call startRun before creating a round. Previously compiled games must update the package and be rebuilt; hosting cannot patch an old game bundle.
