prometeu-runtime/docs/runtime/agendas/023-tilemap-empty-cell-vs-tile-id-zero.md
2026-03-24 13:40:56 +00:00

3.5 KiB

Tilemap Empty Cell vs Tile ID Zero

Contexto

O runtime hoje usa tile.id == 0 como atalho para "tile ausente" no caminho de render de tilemap.

Ao mesmo tempo, o contrato de tile bank em evolucao no packer quer permitir que tile_id = 0 seja um tile real e valido dentro do bank.

Isso cria conflito direto entre:

  • semantica atual do tilemap no runtime;
  • e o contrato de packing/runtime asset bank que trata tile_id como indice valido do bank desde zero.

Problema

Precisamos decidir qual e a semantica correta para representar ausencia de tile em tilemaps.

Hoje o comportamento implicito e:

  • tile.id == 0 significa "nao desenhar";
  • portanto o tile de indice 0 no bank fica inutilizavel no caminho de tilemap;
  • sprites, por outro lado, nao carregam a mesma semantica implicita de vazio.

Isso deixa o modelo inconsistente:

  1. o mesmo tile_id nao significa a mesma coisa em todos os consumidores;
  2. o bank TileBank nao explicita reserva de tile_id = 0;
  3. o packer teria que compensar uma regra de consumidor que nao esta modelada no contrato do asset bank.

Pontos Criticos

  • tile_id deve representar um indice valido no bank, nao um sentinel escondido, sempre que possivel;
  • ausencia de tile e um conceito de tilemap/layer, nao necessariamente de bank asset;
  • usar indices fora da faixa como sentinel tende a piorar validacao e debug;
  • mudar o shape do tilemap pode ter custo de ABI/runtime, mas pode deixar o contrato mais honesto;
  • manter o comportamento atual preserva compatibilidade local, mas cristaliza uma semantica implicita fraca.

Opcoes

Opcao A - Manter tile.id == 0 como empty sentinel

O runtime segue tratando tile_id = 0 como ausencia de tile no tilemap.

Consequencia:

  • o primeiro tile real do bank precisaria comecar em 1 para o caminho de tilemap;
  • o packer precisaria compensar isso;
  • sprites e tilemaps continuariam com semanticas diferentes para o mesmo id.

Opcao B - Tornar vazio explicito no tilemap model

O tilemap passa a representar vazio explicitamente, por exemplo com:

  • Option<Tile>;
  • ou Tile { active/present, ... }.

Consequencia:

  • tile_id = 0 volta a ser um tile valido no bank;
  • ausencia de tile deixa de depender de valor especial do id;
  • o runtime fica semanticamente mais consistente.

Opcao C - Usar sentinel fora da faixa valida

O tilemap passa a tratar um tile_id >= tile_capacity como "empty".

Consequencia:

  • evita usar 0 como sentinel;
  • mas cria acoplamento ruim entre tilemap e capacidade do bank;
  • e torna a validacao mais fragil e menos didatica.

Sugestao / Recomendacao

Adotar Opcao B.

Ausencia de tile deve ser modelada explicitamente no tilemap/layer, e nao por um tile_id especial.

Direcao recomendada:

  1. tile_id deve significar apenas "indice do tile no bank";
  2. tile_id = 0 deve ser permitido como tile real;
  3. tilemaps devem ter vazio explicito no proprio modelo;
  4. o render do tilemap deve testar esse estado explicito, nao tile.id == 0.

Perguntas em Aberto

  1. Qual shape e melhor para o primeiro wave: Option<Tile> ou Tile com flag active/present?
  2. Essa mudanca afeta apenas o tilemap path ou tambem deve harmonizar outros consumidores do modelo Tile?
  3. Precisamos de estrategia de compatibilidade/migracao para codigo e testes que hoje assumem tile.id == 0 como vazio?

Criterio para Encerrar

Esta agenda pode ser encerrada quando houver decisao clara sobre:

  • como vazio e representado no tilemap;
  • se tile_id = 0 volta a ser indice valido universal do bank;
  • e quais pontos de spec/codigo do runtime precisam de propagacao.