Referência dos objetos de Schema
Última atualização: 16 de julho de 2026
Esta página explica os conceitos centrais de Schema usados no PlayServ Backoffice.
Use-a quando precisar de uma definição clara de um objeto de Schema, de um tipo de campo ou de uma configuração de campo, e quiser entender como aquilo se encaixa no modelo de dados como um todo. Ela existe para responder perguntas diretas como o que é uma Entity, em que a Relationship difere da Inclusion, ou o que acontece quando um objeto é marcado como Singleton.
O Schema é a definição formal da estrutura de dados de um Project. Ele descreve quais objetos existem no Project, quais campos eles contêm, quais valores esses campos podem guardar e como esses objetos se relacionam entre si.
Entity, Entity Part e Enum
O Schema é construído a partir de três tipos de objeto centrais — cada um com um papel distinto no modelo de dados.
Objeto autônomo
Um objeto de Schema de nível superior que define uma estrutura completa e autônoma. As Entities são os principais blocos de construção do seu Schema — elas representam conceitos reais do seu jogo, como o perfil de um Player, a configuração de uma arma, um item de loja ou o registro de uma partida.
Cada Entity tem os seus próprios Records na visão Data. Ela pode ter campos próprios, ser referenciada por outras Entities através de campos Relationship, e ter Entity Parts embutidas nela através de campos Inclusion.
Fragmento reutilizável
Um objeto de Schema reutilizável que define um pedaço de estrutura destinado a ser embutido dentro de outros objetos de Schema. Use-o quando o mesmo grupo de campos deve aparecer em vários lugares, ou quando um objeto maior deve ser montado a partir de pedaços menores e nomeados, em vez de definido de uma vez só.
Entity Parts não têm Records próprios na visão Data — elas só existem como parte das Entities que as incluem. Bons exemplos são blocos de atributos, grupos de configuração ou estruturas de inventário que pertencem a um objeto maior.
Conjunto controlado de valores
Um tipo que define um conjunto fixo de valores permitidos. Use-o quando um campo deve aceitar um valor de uma lista controlada, em vez de entrada livre. Enums mantêm os dados consistentes e evitam que os valores se dispersem com o tempo.
Por exemplo, um enum TankStatus com os valores Active, Destroyed e Respawning garante que nenhum status inesperado possa ser armazenado. Enums são referenciados por campos através do kind Enum reference.

Tipos de campo
Toda Entity e toda Entity Part é construída a partir de campos. Ao adicionar um campo, você escolhe o seu Kind — que determina o que o campo guarda e como ele se conecta ao resto do Schema.
Existem quatro kinds de campo: Primitive, Enum reference, Relationship → entity e Inclusion ↩ part.
Primitive
Um campo Primitive guarda um valor escalar direto. Use-o quando o campo deve conter um único valor que não referencia nenhum outro objeto de Schema.

| Tipo | Guarda |
|---|---|
| Text | String curta |
| Long text | String de várias linhas |
| Integer | Número inteiro |
| Number | Float / decimal |
| Decimal | Precisão fixa |
| Boolean | true / false |
| Date & time | Timestamp ISO |
| Date | YYYY-MM-DD |
| UUID | Identificador único |
| JSON | Objeto estruturado |
| E-mail validado | |
| URL | Link |
Escolha Primitive quando o campo guarda um valor diretamente — um nome, um valor de velocidade, uma flag, um timestamp. A maioria dos campos de um Schema típico é Primitive.
Enum reference
Um campo Enum reference restringe o valor do campo a uma das opções de um Enum predefinido.

Depois de escolher este kind, selecione qual Enum o campo deve referenciar. Em runtime, o campo só pode conter um dos valores definidos naquele Enum.
Use Enum reference quando um campo deve aceitar apenas um conjunto controlado de valores — por exemplo, um campo status que pode ser Draft, Active ou Archived. Isso impede que valores livres entrem nos dados e deixa as opções válidas explícitas no próprio Schema.
Relationship → entity
Um campo Relationship cria uma chave estrangeira para outra Entity. Use-o quando o objeto atual deve apontar para um Record separado, de existência independente, em vez de embutir a estrutura dele.

Ao adicionar um campo Relationship, selecione a Entity de destino e a cardinalidade:
- 1-to-1 — o objeto atual aponta para exatamente um Record da Entity de destino
- 1-to-many — o objeto atual aponta para vários Records da Entity de destino
Use Relationship quando os objetos são de fato separados e devem existir de forma independente. Por exemplo, uma Entity Match que referencia uma lista de Entities Player — os Players existem por conta própria e podem ser referenciados por várias partidas. Diferente da Inclusion, uma Relationship não embute a estrutura do destino; ela guarda apenas um link para ele.
Use Relationship quando o objeto vinculado tem identidade e ciclo de vida próprios. Use Inclusion quando a estrutura pertence ao objeto pai e não precisa existir de forma independente.
Inclusion ↩ part
Um campo Inclusion embute uma Entity Part diretamente no objeto atual, como parte da estrutura dele. Use-o quando a estrutura aninhada pertence ao objeto pai e não deve existir como um Record separado e autônomo.

Ao adicionar um campo Inclusion, selecione a Entity Part de destino e a cardinalidade:
- 1-to-1 — embute uma única instância da part
- 1-to-many — embute uma lista de instâncias da part
Use Inclusion para compor objetos maiores a partir de pedaços estruturais reutilizáveis. Por exemplo, uma Entity Tank que inclui uma part TankConf para a configuração e uma part BattleConf para os parâmetros de batalha — essas estruturas pertencem ao tanque e não precisam existir por conta própria.
Diferente da Relationship, a Inclusion não cria um link para um Record separado. Ela insere os campos da part diretamente na estrutura do pai.
Com uma Relationship, Match e Player são Records separados — Match guarda apenas um link. Com uma Inclusion, TankConf não tem Record próprio; os campos dela vivem dentro de Tank.
Restrições de campo
Todo campo, independentemente do kind, suporta um conjunto de restrições que controlam o seu comportamento.
| Restrição | Comportamento |
|---|---|
| Required | O campo precisa ter um valor. Um Record não pode ser salvo sem ele. |
| Unique | Dois Records não podem compartilhar o mesmo valor para este campo. |
| Indexed | Melhora o desempenho das consultas ao filtrar ou ordenar por este campo em escala. |
| Min / Max value | Limita a faixa numérica. Disponível para campos Integer, Number e Decimal. |
| Min / Max length | Limita o comprimento da string. Disponível para campos Text e Long text. |
| Min / Max items | Limita a quantidade de entradas em um campo de array. |
Singleton
Um Singleton é um objeto de Schema para o qual só pode existir um único Record.

Use Singleton para objetos de configuração global ou ajustes únicos, válidos para todo o Project, que não devem existir como uma lista de Records. Um exemplo típico é uma Entity GameConfig que guarda parâmetros válidos para todo o servidor — existe uma única configuração, não uma coleção delas.
A distinção é simples:
- uma Entity comum pode ter muitos Records
- uma Entity Singleton pode ter exatamente um
Quando uma Entity é marcada como Singleton, a visão Data reflete isso — em vez de uma lista de Records com um botão de criar, ela mostra um único formulário de Record.
Uma Entity Singleton tem exatamente uma linha, sem chave primária de nível de negócio. Internamente ela é armazenada com um id oculto, para que as chaves estrangeiras continuem funcionando.
Configurações de Entity
Além dos seus campos, uma Entity carrega algumas configurações que mudam o comportamento dos seus Records.
Owned by player
Uma Entity pode ser marcada como owned by a player, o que atrela cada Record ao Player que o criou. Isso é o que ativa o escopo de linhas por Player no plano de dados — um cliente vê e escreve apenas as próprias linhas — e está detalhado em Access Control.
Para uma Entity owned você também escolhe o que acontece com as linhas de um Player quando a conta dele é removida ou mesclada:
| Configuração | Valores | Significado |
|---|---|---|
on_player_delete | cascade-delete, restrict, anonymise | Quando um Player é excluído: remover as linhas dele, bloquear a exclusão enquanto houver linhas, ou manter as linhas removendo o vínculo com o dono. |
on_player_merge | (política) | Como as linhas owned são tratadas quando duas contas de Player são mescladas em uma. |
Essas políticas rodam automaticamente — excluir ou mesclar um Player aplica a regra em todas as Entities owned, para que não fiquem Records órfãos.
Raw fields
Por padrão, um Record só pode conter campos declarados no Schema; um campo não declarado é rejeitado. Uma Entity pode, alternativamente, permitir raw fields (allow_raw_fields), o que deixa os Records carregarem chaves extras arbitrárias que o Schema não define — uma saída sem Schema para dados cujo formato você não quer modelar de antemão. Os campos declarados continuam sendo validados normalmente; os raw fields andam ao lado deles, sem verificação.
Ative raw fields de propósito. É uma troca: você abre mão das garantias do Schema (validação, consultas tipadas) em favor de flexibilidade naquela Entity — útil para blobs de formato livre, incômodo para qualquer coisa que você vá querer consultar ou migrar depois.
Como esses conceitos funcionam juntos
O Schema começa pelos objetos centrais: Entities definem estruturas autônomas, Entity Parts definem fragmentos reutilizáveis e Enums definem conjuntos controlados de valores. Esses objetos são construídos a partir de campos. Os campos guardam valores diretos através de Primitive, impõem valores controlados através de Enum reference, ligam-se a outros Records através de Relationship e embutem estrutura reutilizável através de Inclusion. Singleton marca os objetos que só devem ter um Record.
Juntos, esses conceitos definem a estrutura completa que os dados de um Project vão seguir.
Próximos passos
- Building a Game Schema — sair das definições e partir para a prática