Anchor & Gate — Especificação Técnica
Este documento define a especificação técnica completa para Anchor e Gate, blocos avançados de topologia que permitem expansão interdimensional de redes.
Status da especificação: aprovada em 14/02/2026; reconciliada com o código em 10/09/2026 Estado da implementação: parcial; transporte existe, mas as invariantes T5 Link e a regressão completa estão pendentes
Visão Geral
Anchor:
- Teleporta payloads dentro da mesma rede (extensão de grafo)
- "Fiber Gourmet" interdimensional
- Custo: 4x-8x Port convencional
Gate:
- Portal entre redes distintas via rede intermediadora LINK
- Permite redes externas atravessarem dimensões
- Custo: 8x-16x Port convencional
Anchor — Especificação Completa
Conceito
Anchor é um bloco que cria um "túnel" no grafo da rede, permitindo que payloads sejam teleportados instantaneamente entre dois pontos, mesmo em dimensões diferentes.
Analogia: Fiber conecta blocos adjacentes (1 bloco de distância). Anchor conecta blocos distantes (distância ilimitada).
Requerimentos
- Rede: Tipo LINK (T4 + Singularidade Link)
- Craft: 2x Anchor por receita (sempre em par)
- Materiais: T4 Core + Singularidade Link + outros (a definir)
Custo Energético
Fórmula:
Custo por par = Base Port Cost × Multiplicador
Multiplicadores (configuráveis via datapack):
- Mesma dimensão: 4.0
- Interdimensional: 8.0
Exemplo (T4):
- T4 Port base: 320 FE/t
- Anchor (mesma dim): 1280 FE/t por par
- Anchor (interdim): 2560 FE/t por par
Observações:
- Custo é standby apenas (não varia com transferências)
- Ambos os Anchors do par consomem energia (split 50/50 ou total em cada?)
- Se um Anchor ficar sem energia, link fica inativo
Linking
Processo:
- Player equipa Tuning Key em modo Link
- Right-click em Anchor A
- Tuning Key armazena: UUID, BlockPos, Dimension
- Feedback: "Anchor selected at [x, y, z] @ dimension_name"
- Visual: Partículas PORTAL ao redor do Anchor A (placeholder)
- Right-click em Anchor B
- Cria link bidirecional A ↔ B
- Feedback: "Anchors linked! [x1, y1, z1] ↔ [x2, y2, z2]"
- Visual: Partículas PORTAL conectando os dois pontos (se visíveis)
- Ambos Anchors armazenam UUID/Pos do par
Deslinkar:
- Shift + Right-click com Tuning Key (modo Link) em qualquer Anchor do par
- Feedback: "Anchor unlinked"
- Ambos voltam ao estado não-linkado
Validações:
- Ambos Anchors devem estar na mesma rede (mesmo Controller)
- Não pode linkar Anchor já linkado (precisa deslinkar primeiro)
- Distância ilimitada (apenas custo energético limita viabilidade)
BlockEntity (WeaveAnchorBlockEntity)
Campos:
// Link state
private UUID linkedAnchorId; // UUID do Anchor par
private BlockPos linkedAnchorPos; // Posição do par
private ResourceKey<Level> linkedAnchorDim; // Dimensão do par
private boolean isLinked; // Se está linkado
// Management
private boolean isEnabled = true; // Controller pode desligar
private UUID controllerId; // Controller desta rede
// Cached data
private int energyCostPerTick; // Calculado baseado em dimensão
Métodos:
public void linkTo(UUID anchorId, BlockPos pos, ResourceKey<Level> dim);
public void unlink();
public boolean isLinked();
public BlockPos getLinkedPosition();
public ResourceKey<Level> getLinkedDimension();
// Management
public void setEnabled(boolean enabled);
public boolean isEnabled();
public int getEnergyCost(); // Calculado: portCost × (sameDim ? 4 : 8)
NBT Persistence:
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
if (linkedAnchorId != null) {
tag.putUUID("linkedAnchorId", linkedAnchorId);
tag.putLong("linkedAnchorPos", linkedAnchorPos.asLong());
tag.putString("linkedAnchorDim", linkedAnchorDim.location().toString());
}
tag.putBoolean("isLinked", isLinked);
tag.putBoolean("isEnabled", isEnabled);
if (controllerId != null) {
tag.putUUID("controllerId", controllerId);
}
}
Integração com WeaveGraph
Binding (BFS):
// Durante BFS, ao encontrar Anchor:
if (anchor.isLinked() && anchor.isEnabled()) {
NodePosition anchorPos = new NodePosition(x, y, z);
NodePosition linkedPos = anchor.getLinkedPosition();
// Adiciona aresta virtual no grafo
graph.addEdge(anchorPos, linkedPos);
// Continua BFS a partir do Anchor linkado
// (mesmo que esteja em outra dimensão!)
queue.add(linkedPos);
}
Payload Transfer:
- Payloads movem Port → Fiber → Anchor A
- Anchor A detecta linkedAnchorPos
- Payload "teleporta" instantaneamente para Anchor B
- Anchor B → Fiber → Port (continua normalmente)
Consideração de Dimensão:
- BFS cruza dimensões através de Anchors linkados
- Controller precisa acessar múltiplos Levels para binding completo
- Runtime precisa gerenciar Anchors cross-dimension
Gerenciamento via Controller
UI do Controller (Marco 5) mostra:
┌─────────────────────────────────────┐
│ Anchors (2 pairs) │
├─────────────────────────────────────┤
│ ✓ Anchor #1 │
│ Linked to: [100, 64, 200] │
│ @ minecraft:overworld │
│ Cost: 1280 FE/t │
│ [Disable] │
├─────────────────────────────────────┤
│ ✗ Anchor #2 (DISABLED) │
│ Linked to: [-50, 100, 300] │
│ @ minecraft:the_nether │
│ Cost: 2560 FE/t (not consuming) │
│ [Enable] │
└─────────────────────────────────────┘
Comandos:
setAnchorEnabled(UUID anchorId, boolean enabled)getAnchorStatus(UUID anchorId)→{isLinked, linkedPos, cost, isEnabled}
Visual & Audio
Block Model:
- Textura distinta de Fiber (cores diferentes, glow)
- Não tem direção específica (conecta em qualquer face)
- Estado visual: LINKED vs UNLINKED (textura/glow diferente?)
Partículas (Placeholder):
- Quando linkado: PORTAL particles ao redor do bloco
- Quando payload passa: burst de partículas
Som:
- Link criado: som de portal (placeholder)
- Payload passa: whoosh sound (placeholder)
Gate — Especificação Completa
Conceito
Gate é um portal que conecta duas redes externas distintas através de uma rede intermediadora LINK. Permite que redes externas (qualquer tipo: Flow, Density, etc) atravessem dimensões usando a infraestrutura de uma rede LINK.
Analogia: Anchor estende a própria rede. Gate conecta redes diferentes.
Arquitetura de Três Redes
┌────────────────────────────────────┐
│ REDE EXTERNA A │
│ (Controller A, T4+Flow, 8 canais) │
│ Processa Items/Energy/Fluids │
└─────────────┬──────────────────────┘
│ Fiber → NORTH de Gate IN
┌─────────────▼──────────────────────┐
│ REDE INTERMEDIADORA │
│ (Controller B, T4+Link, 24 canais) │
│ Não processa payloads │
│ Apenas sustenta Gates │
│ │
│ ┌──────┐ ┌──────┐ │
│ │Gate │ │Gate │ │
│ │IN │ ←link→ │OUT │ │
│ └──────┘ └──────┘ │
│ Overworld Nether │
└─────────────┬──────────────────────┘
│ Fiber → NORTH de Gate OUT
┌─────────────▼──────────────────────┐
│ REDE EXTERNA A (continua) │
│ (mesmo Controller A) │
│ Processa Items/Energy/Fluids │
└────────────────────────────────────┘
Regras Críticas:
- Rede intermediadora não vê payloads da rede externa
- Gates apenas "estendem" o grafo da rede externa
- Rede externa tem grafo único que atravessa Gates
- Controller da rede externa controla ambos os lados do Gate
Requerimentos
Rede Intermediadora:
- Tipo LINK (T4 + Singularidade Link)
- Mínimo: Controller + 2 Gates (IN + OUT) + Fibers conectando
Rede Externa:
- Qualquer tipo (Flow, Density, Normal)
- Conecta via Fiber na face NORTH dos Gates
- Não pode usar Port na conexão (regra de segurança)
Craft:
- Resultado: 2x Gate (1 IN + 1 OUT marcados? Ou genéricos?)
- Materiais: T4 Core + Singularidade Link + outros (a definir)
Custo Energético
Fórmula:
Custo por par = Base Port Cost × Multiplicador
Multiplicadores (configuráveis via datapack):
- Mesma dimensão: 8.0
- Interdimensional: 16.0
Exemplo (T4):
- T4 Port base: 320 FE/t
- Gate (mesma dim): 2560 FE/t por par
- Gate (interdim): 5120 FE/t por par
Quem paga:
- Rede intermediadora paga o custo dos Gates
- Rede externa não paga nada (apenas usa o portal)
Consumo de Canais
Rede Intermediadora:
- 1 par de Gates = 1 canal (fixo)
- Exemplo: T4 Link (24 canais) = max 24 pares de Gates
- Canais usados pela rede externa NÃO contam aqui!
Rede Externa:
- Usa seus próprios canais normalmente (ex: T4 Flow = 8 canais)
- Pode usar 100% dos canais para transfers
- Não consome canais da intermediadora
Cálculo Exemplo:
Intermediadora: T4 Link, 24 canais
- 10 pares de Gates = 10 canais usados
- 14 canais livres para mais Gates
Externa: T4 Flow, 8 canais
- 7 canais usados para payloads (Items/Energy)
- 1 canal livre
- NÃO afeta canais da intermediadora!
Placement e BlockState
FACING Property:
public static final EnumProperty<Direction> FACING = BlockStateProperties.HORIZONTAL_FACING;
// Determina qual face é NORTH (rede externa)
Placement Rule:
- NORTH fica oposto à direção do player (como Furnace)
- Exemplo:
- Player olhando SOUTH → Gate coloca com FACING=SOUTH (NORTH real = SOUTH)
- Player olhando EAST → Gate coloca com FACING=EAST (NORTH real = EAST)
Conexões por Face:
Direction north = state.getValue(FACING);
if (checkingFace == north) {
// Face NORTH: aceita APENAS Fiber de rede externa
// NÃO aceita Port (validação no bind)
return WeaveConnectionKind.FIBER; // Visual especial?
} else {
// Outras 5 faces: aceitam Fiber de alimentação (rede intermediadora)
return WeaveConnectionKind.FIBER;
}
Linking
Processo:
- Player equipa Tuning Key em modo Link
- Right-click em Gate IN
- Tuning Key armazena: UUID, BlockPos, Dimension
- Feedback: "Gate IN selected at [x, y, z] @ dimension_name"
- Visual: Partículas PORTAL na face NORTH
- Right-click em Gate OUT
- Cria link bidirecional IN ↔ OUT
- Feedback: "Gates linked! IN [x1, y1, z1] ↔ OUT [x2, y2, z2]"
- Visual: Efeito de portal na face NORTH de ambos
- Ambos Gates armazenam UUID/Pos do par
Deslinkar:
- Shift + Right-click com Tuning Key (modo Link) em qualquer Gate do par
- Feedback: "Gates unlinked. External network disconnected."
- Ambos voltam ao estado não-linkado
- Rede externa: trecho pós-Gate OUT desconecta do grafo
Validações:
- Ambos Gates devem estar na mesma rede intermediadora (mesmo Controller)
- Gates devem ser tipo LINK (não funciona em redes normais)
- Não pode linkar Gate já linkado (precisa deslinkar primeiro)
- Ao linkar, verifica se há Fiber na face NORTH de ambos
BlockEntity (WeaveGateBlockEntity)
Campos:
// Link state
private UUID linkedGateId; // UUID do Gate par
private BlockPos linkedGatePos; // Posição do par
private ResourceKey<Level> linkedGateDim; // Dimensão do par
private boolean isLinked; // Se está linkado
// External network detection
private UUID externalNetworkId; // UUID da rede externa (se conectada)
private boolean hasExternalNetwork; // Se rede externa está conectada
// Management
private boolean isEnabled = true; // Controller intermediador pode desligar
private UUID controllerId; // Controller da rede intermediadora
// Cached data
private int energyCostPerTick; // Calculado baseado em dimensão
private int channelsConsumed = 1; // Sempre 1 por par
Métodos:
public void linkTo(UUID gateId, BlockPos pos, ResourceKey<Level> dim);
public void unlink();
public boolean isLinked();
public BlockPos getLinkedPosition();
public ResourceKey<Level> getLinkedDimension();
// External network
public Direction getExternalFace(); // Retorna NORTH (relativo ao FACING)
public boolean hasExternalNetwork();
public UUID getExternalNetworkId();
// Management
public void setEnabled(boolean enabled);
public boolean isEnabled();
public int getEnergyCost(); // Calculado: portCost × (sameDim ? 8 : 16)
public int getChannelsConsumed(); // Sempre 1
NBT Persistence:
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
if (linkedGateId != null) {
tag.putUUID("linkedGateId", linkedGateId);
tag.putLong("linkedGatePos", linkedGatePos.asLong());
tag.putString("linkedGateDim", linkedGateDim.location().toString());
}
tag.putBoolean("isLinked", isLinked);
tag.putBoolean("isEnabled", isEnabled);
if (controllerId != null) {
tag.putUUID("controllerId", controllerId);
}
if (externalNetworkId != null) {
tag.putUUID("externalNetworkId", externalNetworkId);
}
tag.putBoolean("hasExternalNetwork", hasExternalNetwork);
}
Integração com WeaveGraph
Binding (Rede Intermediadora):
// Durante BFS da rede intermediadora:
if (block instanceof WeaveGateBlock) {
// Gates fazem parte do grafo intermediador (5 faces)
// Mas face NORTH NÃO adiciona ao grafo intermediador
Direction externalFace = gate.getExternalFace(); // NORTH
for (Direction dir : Direction.values()) {
if (dir == externalFace) {
continue; // Pula face NORTH (rede externa)
}
// Adiciona outras 5 faces ao grafo intermediador
checkAndAddNeighbor(pos.relative(dir));
}
}
Binding (Rede Externa):
// Durante BFS da rede externa:
if (block instanceof WeaveGateBlock) {
// Se Gate está linkado e enabled:
if (gate.isLinked() && gate.isEnabled()) {
// Adiciona aresta virtual para o Gate OUT
NodePosition gateInPos = new NodePosition(x, y, z);
NodePosition gateOutPos = gate.getLinkedPosition();
// Payload "teleporta" através do par de Gates
graph.addEdge(gateInPos, gateOutPos);
// Continua BFS a partir do Gate OUT (outra dimensão!)
queue.add(gateOutPos);
}
}
Payload Transfer:
- Payload chega: Port → Fiber → Gate IN (face NORTH)
- Gate IN verifica: isLinked() && isEnabled()
- Se sim: payload "teleporta" para Gate OUT
- Gate OUT: payload sai pela face NORTH → Fiber → Port (rede externa continua)
Estados Operacionais
| Estado Intermediadora | Gates | Rede Externa (trecho pós-Gate) |
|---|---|---|
| OFFLINE | Inativos | Desconectado do grafo |
| BOOTING | Ativando | Aguardando binding |
| ONLINE | Ativos | Conectado, payloads fluem |
| RECONFIGURING | Mantém link | Mantém conexão (sem transfers) |
| BROWNOUT | Link interrompido | Desconecta do grafo |
| COLLAPSE | Link interrompido | Desconecta do grafo |
| REBOOT | Inativos | Aguardando reconexão |
Reconexão:
- Quando intermediadora volta ONLINE → Gates reativam
- Rede externa rebinda (BFS inclui trecho pós-Gate novamente)
- Payloads voltam a fluir normalmente
Gerenciamento via Controller
UI do Controller Intermediador (Marco 5) mostra:
┌─────────────────────────────────────┐
│ Gates (2 pairs, 2/24 channels) │
├─────────────────────────────────────┤
│ ✓ Gate Pair #1 │
│ IN: [100, 64, 200] @ overworld │
│ OUT: [100, 64, 200] @ the_nether │
│ External network: Connected │
│ Cost: 5120 FE/t │
│ Channels: 1 │
│ [Disable] │
├─────────────────────────────────────┤
│ ✗ Gate Pair #2 (DISABLED) │
│ IN: [200, 70, 300] @ overworld │
│ OUT: [200, 70, 300] @ the_end │
│ External network: Disconnected │
│ Cost: 0 FE/t (not consuming) │
│ Channels: 1 (reserved) │
│ [Enable] │
└─────────────────────────────────────┘
Comandos:
setGateEnabled(UUID gateId, boolean enabled)getGateStatus(UUID gateId)→{isLinked, linkedPos, externalConnected, cost, channelsUsed}
Visual & Audio
Block Model:
- Textura portal-like (diferente de Fiber/Anchor)
- Face NORTH: Marca visual CLARA (textura diferente, glow, frame)
- Outras faces: textura de "alimentação" (conecta rede intermediadora)
- Estado visual: LINKED vs UNLINKED
Partículas (Placeholder):
- Face NORTH quando linkado: PORTAL particles
- Quando payload passa: burst intenso de partículas
Som:
- Link criado: som de portal forte (placeholder)
- Payload passa: whoosh + portal sound (placeholder)
Regras Avançadas
Cascata de Gates:
Rede A (Flow) → Gate → Rede B (LINK) → Gate → Rede C (Flow)
↑
intermediadora
- Rede B (LINK) pode ser:
- Intermediadora para conectar A e C
- E ao mesmo tempo: externa de outra rede LINK D
- Permite topologias complexas de múltiplas camadas
Múltiplos Pares:
- Uma rede intermediadora pode ter N pares de Gates (limitado por canais)
- Cada par funciona independentemente
- Custo energético e canais são somados
Segurança:
- Rede externa não pode usar Port na face NORTH do Gate
- Validação durante binding: se detectar Port → erro/aviso
- Motivo: prevenir bugs de capability proxy e loops
Datapack Configuration
Arquivo: data/weave_network/anchor_gate/costs.json
{
"anchor": {
"standby_cost_multiplier_same_dim": 4.0,
"standby_cost_multiplier_cross_dim": 8.0,
"allow_interdimensional": true,
"max_link_distance": -1
},
"gate": {
"standby_cost_multiplier_same_dim": 8.0,
"standby_cost_multiplier_cross_dim": 16.0,
"consumes_channel": true,
"max_pairs_per_network": -1
}
}
Valores:
-1= ilimitado0+= valor específico
Inventário da implementação recuperada
| Capacidade | Estado em setembro de 2026 |
|---|---|
| Blocos, BlockEntities, UUID, posição, dimensão e persistência NBT | Implementado; regressão de mundo pendente. |
| Modelos e texturas placeholder | Implementado; acabamento visual pendente. |
| Link e unlink pela Debug Wrench | Implementado; validações precisam de regressão. |
| Link pela Tuning Key | Planejado; o item ainda não possui o fluxo de gameplay. |
| Travessia de Anchor e Gate no BFS | Parcial; existe, mas Anchor ainda atravessa sem exigir rede T5 Link em todo o caminho. |
| Transferência multidimensional de payloads | Parcialmente validado; itens funcionaram em teste manual, demais payloads estão pendentes. |
| Custos de standby e configuração por datapack | Implementado; contagem de pares válidos e dump precisam de correção. |
| Sustentação do Gate por rede intermediadora Link | Parcial; a entrada possui validação, mas os dois extremos e o lifecycle ainda não estão cobertos. |
| Enable/disable pelo Controller | Planejado junto da interface do Controller. |
| Partículas, sons e feedback final | Planejado. |
Notas de Implementação
Cross-Dimension Binding
Desafio: BFS precisa acessar múltiplos Levels para atravessar Anchors/Gates interdimensionais.
Solução:
// WeaveRuntime mantém cache de Levels
private Map<ResourceKey<Level>, ServerLevel> levelCache = new HashMap<>();
// Durante binding, ao encontrar Anchor/Gate cross-dim:
ServerLevel targetLevel = server.getLevel(targetDim);
BlockEntity targetBE = targetLevel.getBlockEntity(targetPos);
// Continua BFS no targetLevel
Payload Transfer Cross-Dimension
Desafio: Payload precisa "teleportar" entre dimensões.
Solução:
- Payload é representado como dados (ItemStack, FluidStack, int energy)
- Schedulers transferem dados entre Ports
- Anchors/Gates apenas "estendem" o grafo
- Não há transferência física, apenas lógica no grafo
Exemplo:
Port A (Overworld) → Scheduler detecta rota → Port B (Nether)
Rota: Port A → Fiber → Anchor A → [teleport] → Anchor B → Fiber → Port B
Scheduler executa: extract(Port A) → insert(Port B)
Performance
Considerações:
- BFS cross-dimension pode ser custoso (múltiplos Levels carregados)
- Cache de grafos cross-dimension
- Limite prático: custo energético impede N infinito de Anchors/Gates
- Datapack pode limitar max_link_distance ou max_pairs_per_network
Conclusão
Anchor e Gate são blocos avançados que expandem dramaticamente as possibilidades de topologia de rede, permitindo redes interdimensionais e conexão entre redes distintas. A implementação foca em:
- Simplicidade conceitual: Anchor = Fiber gourmet, Gate = Portal entre redes
- Custo energético: Limita uso excessivo (4x-16x Port)
- Flexibilidade: Datapack configurável, sem hardcoding
- Robustez: Estados operacionais bem definidos, reconexão automática
Próximo: fechar as invariantes e a matriz de payloads do Marco 1 — Integridade técnica da rede.