← docs

Manifest v1

El manifest es lo único que entregas a la plataforma (además de tu listing). Declara identidad, plataforma, transporte, eventos que consumes y el schema de configuración que el streamer verá renderizado en el portal. Se valida en el servidor al publicar; el wizard te muestra los mismos errores EN VIVO mientras editas.

Ejemplo completo

{
  "manifestVersion": 1,
  "appId": "com.pepitodev.batalla-clanes",
  "name": "Batalla de Clanes",
  "version": "1.2.0",
  "platform": "gtasa",
  "transport": "local-poll",
  "events": ["chat", "gift", "join"],

  "listing": {
    "title": "Batalla de Clanes para GTA San Andreas",
    "shortDescription": "Tus viewers pelean en bandos escribiendo JOIN en el chat",
    "description": "Markdown largo con instrucciones de instalación…",
    "coverImage": "cover.png",
    "videos": ["https://www.youtube.com/watch?v=XXXX"],
    "downloadUrl": "https://github.com/pepitodev/batalla-clanes/releases/latest",
    "categoryIds": ["<id-de-categoria>"]
  },

  "config": [
    { "key": "comando_join", "type": "string", "default": "JOIN",
      "label": "Comando para unirse", "group": "basico" },
    { "key": "vidas_iniciales", "type": "number", "default": 3, "min": 1, "max": 10,
      "label": "Vidas iniciales", "group": "basico" },
    { "key": "equipos", "type": "select", "default": "2",
      "options": [ {"value": "2", "label": "2 equipos"}, {"value": "4", "label": "4 equipos"} ],
      "label": "Cantidad de equipos", "group": "basico" },
    { "key": "gift_revive", "type": "gift-picker", "default": 5655,
      "label": "Gift que revive al jugador", "group": "avanzado" },
    { "key": "modo_hardcore", "type": "boolean", "default": false,
      "label": "Modo hardcore", "group": "avanzado" }
  ]
}

Campos raíz

CampoReqDescripción
manifestVersionSiempre 1.
appIdId único, inmutable entre versiones. ^[a-z0-9][a-z0-9.-]{2,99}$ (3–100 chars).
nameNombre corto interno.
versionSemver x.y.z. Cada publicación sube versión (estrictamente creciente).
platformweb | gta5 | gtasa | roblox | other.
transportlocal-ws | local-poll | cloud-relay. Roblox obliga cloud-relay.
eventsSubconjunto no vacío de: chat, gift, join, like, follow, share, live_status. El canal solo entrega lo declarado.
listingFicha pública (abajo).
configSchema de configuración (abajo). Puede ser [].

listing — la ficha en Community

CampoReqReglas
title≤ 80 chars.
shortDescription≤ 160 chars (card del catálogo).
descriptionMarkdown, ≤ 20k. Las instrucciones de instalación de un mod van aquí.
coverImageNombre del archivo que subes en el wizard. 16:9, ≤ 2 MB.
screenshotsHasta 6, mismas reglas que la carátula.
videosLinks de YouTube (embed). No hospedamos video.
downloadUrlsí (mods externos)Link EXTERNO de descarga. Con el flag hostedUploads puedes en cambio subir los archivos del mod.
categoryIds1–3 categorías existentes y visibles. Se validan al publicar.

source — origen del código (solo platform: "web")

Los juegos web community se hospedan con nosotros y quedan en https://communitygame.tikxander.com/<appId>/index.html. El manifest declara el origen:

"source": { "type": "upload" }

o, para importar desde un repositorio:

"source": { "type": "github", "repo": "https://github.com/tu/repo", "branch": "main", "path": "dist" }
  • Con type: "upload" subes un ZIP del build estático (requiere el flag hostedUploads).
  • Con type: "github" clonamos el repo (branch + path). Si el repo es privado, el wizard te pide un token de SOLO lectura: se guarda cifrado, viaja fuera del manifest y puedes revocarlo tras la revisión.
  • Sin el flag hostedUploads, platform: "web" exige type: "github".

config — schema de configuración

Cada campo se renderiza en el portal del streamer. Reglas por campo:

ReglaDetalle
key^[a-z0-9_]+$, único en el array.
typestring | number | boolean | select | color | gift-picker | image | media-picker.
groupbasico o avanzado (organiza la UI del streamer).
defaultOBLIGATORIO en TODOS los campos.
selectrequiere options: [{value, label}]; el default debe estar entre los value.
numberopcional min/max (con slider), step, integer: true (fuerza enteros) y unit (sufijo mostrado, ej. "seg", "%"). El default debe caer en el rango.
string/text/textareaopcional maxLength y minLength (largo mínimo del valor). El default debe respetar ambos.
gift-pickerel streamer elige del catálogo real (imagen + diamantes), no tipea el id. Guarda el giftId de TikTok (estable entre regiones). Con "multiple": true guarda un number[] (varios regalos → mismo efecto); su default es un array.
imageel streamer sube su propia imagen (o la elige de su Biblioteca) para personalizar el juego — p. ej. la skin de una caja, un fondo o un logo. Abre la Biblioteca del streamer con el flujo de consentimiento/ToS de subida (privacidad + responsabilidad) y guarda la URL pública de la imagen (un string). Tu juego la recibe en config.<key> como URL lista para usar (<img src> / textura); si está vacía, usá tu asset por defecto. El default es la URL de tu imagen base (o "").
sectionnombre de sección para agrupar campos dentro del tab (string). Si falta, el campo cae en la sección general.
sectionCollapsible / sectionCollapsedbool. La sección se puede plegar si algún campo suyo trae sectionCollapsible: true; sectionCollapsed: true en algún campo la deja plegada al inicio. Se marcan a nivel de campo pero describen la sección completa.
colSpan1 | 2 | 3 — cuántas de 3 columnas ocupa el campo en su fila (default 3 = fila completa). Permite 2 o 3 campos en una misma línea; es responsivo (se apila en móvil).
visibleIfmuestra el campo condicionalmente: { "field": "<otra_key>", "equals": <valor> } o { "field": "...", "oneOf": [<valores>] }. Ej.: mostrar mult_duracion_seg solo si mult_es_permanente === false.
Avisosi dos gift-picker comparten el mismo giftId, el portal muestra una advertencia (el mismo regalo dispararía varios efectos).
Evoluciónun key existente NO puede cambiar de type entre versiones (usa un key nuevo).

Códigos de validación

El servidor devuelve un array [{field, code, message}] y el wizard los pinta EN VIVO sobre los campos. Algunos códigos: manifest_version_invalid, app_id_invalid, app_id_immutable, name_required, version_invalid, semver_not_increasing, platform_invalid, transport_invalid, roblox_requires_cloud_relay, events_invalid, listing_title_invalid, listing_short_invalid, listing_description_invalid, cover_required, too_many_screenshots, video_url_invalid, categories_count_invalid, category_not_found, source_type_invalid, source_github_required, bundle_required, github_source_incomplete, config_key_invalid, config_key_duplicate, config_group_invalid, config_default_required, config_options_required, config_default_not_in_options, config_default_type_mismatch, config_default_out_of_range, config_default_too_short, config_type_changed.