Jogo #11

Tucano Bonito

Volatilidade
Grid
RTP

Tucano Bonito — Game Design Document (GDD)

Versão: 1.0 Data: 2026-04-03 Mercado: Paraná, Brasil (Regulação Lottopar) Referência Global: Bonanza (Big Time Gaming) / Great Rhino Megaways


1. Identificação do Jogo

Campo Valor
Nome do Jogo Tucano Bonito
Código Interno PROJETO_11
Tipo de Slot Dynamic Reels / Megaways
Número de Bobinas 6 Bobinas Verticais + 1 Tracker Horizontal
Tamanho da Grade Variável (2-7 símbolos por bobina)
Máximo de Caminhos 117.649 Ways
Denominações Suportadas R$ 0,10 a R$ 10,00
RTP Alvo 90% (Rua) / 94% (Standard) / 97% (VIP)
Volatilidade Extrema
Hit Frequency 20%
Jackpot Progressivo Não

2. Tema e Identidade Visual

2.1 Narrativa Temática

Tucano Bonito é uma celebração da biodiversidade tropical do Brasil. O jogo transpõe o jogador para a selva vibrante, onde tucanos coloridos, araras azuis e frutas exóticas dominam o cenário. Diferente dos slots tradicionais de 5 linhas que parecem "chatos" aos olhos dos jogadores modernos, Tucano Bonito oferece ação frenética com até 117.649 caminhos de ganho mudando a cada giro.

2.2 Paleta de Cores

2.3 Elementos Visuais Principais

2.4 Animações Principais


3. Estrutura Mecânica

3.1 Layout e Configuração

A grade de Tucano Bonito é revolucionária em sua flexibilidade:

``` [Tracker Horizontal - Acima das Colunas 2,3,4,5]

[R1-H1] [R2-H1] [R3-H1] [R4-H1] [R5-H1] [R6-H1] [R1-H2] [R2-H2] [R3-H2] [R4-H2] [R5-H2] [R6-H2] [R1-H3] [R2-H3] [R3-H3] [R4-H3] [R5-H3] [R6-H3] [R1-H4] [R2-H4] [R3-H4] [R4-H4] [R5-H4] [R6-H4] [R1-H5] [R2-H5] [R3-H5] [R4-H5] [R5-H5] [R6-H5] [R1-H6] [R2-H6] [R3-H6] [R4-H6] [R5-H6] [R6-H6] [R1-H7] [R2-H7] [R3-H7] [R4-H7] [R5-H7] [R6-H7] ```

Altura Variável: - Altura Mínima: 2 símbolos - Altura Padrão: 4 símbolos - Altura Expandida: 5-6 símbolos - Max Megaways: 7 símbolos por bobina

3.2 Sistema de Caminhos (Ways to Win)

Diferente de slots com linhas fixas, Tucano Bonito calcula Ways dinamicamente.

Fórmula: ``` Total Ways = Altura(R1) × Altura(R2) × Altura(R3) × Altura(R4) × Altura(R5) × Altura(R6)

Mínimo: 2 × 2 × 2 × 2 × 2 × 2 = 64 Ways Máximo: 7 × 7 × 7 × 7 × 7 × 7 = 117.649 Ways ```

Condição de Vitória: Um símbolo igualdade deve aparecer em bobinas adjacentes (sem quebra). A quantidade de caminhos vencedores é calculada pelo produto das posições disponíveis.

Exemplo: - Símbolo: Arara Azul - Posições: R1 (2 posições), R2 (3 posições), R3 (1 posição), [quebra em R4] - Ways Vencedoras: 2 × 3 × 1 = 6 ways - Payout: 6 × Valor(Arara para 3 símbolos)

3.3 Mecanismo de Cascata (Tumble Mechanics)

Quando uma vitória é alcançada:

  1. Explosão: Símbolos vencedores explodem em partículas
  2. Queda: Símbolos acima caem para preencher o vazio
  3. Entrada: Novos símbolos caem do topo (do Phantom Buffer)
  4. Re-verificação: Sistema verifica novamente se há vitórias (cascata)
  5. Continuação: Se houver vitória, multiplicador de cascata aumenta em +1x
  6. Parada: Cascata termina quando nenhuma vitória é encontrada

Multiplicador de Cascata: - 1ª Cascata: ×1 (base) - 2ª Cascata: ×2 - 3ª Cascata: ×3 - ... até 15+ª Cascata: ×15


4. Tabela de Símbolos e Paytable

4.1 Paytable Completo (em função da aposta)

Símbolo 6 Símbolos 5 Símbolos 4 Símbolos 3 Símbolos Função
Tucano Real 50x 25x 10x 2x Premium. Paga mesmo com 2 símbolos.
Arara Azul 7.5x 2.5x 2x 1x Símbolo Alto. Raro nas primeiras bobinas.
Sapo Dourado 2x 1.5x 1x 0.5x Símbolo Médio. Sustém o jogo base.
Frutas (Açaí, Caju, Buriti) 1.5x 0.8x 0.5x 0.2x Símbolos Baixos. Bloqueadores de espaço.
Ovo de Ouro (Wild) Substitui qualquer símbolo (apenas no Tracker).
Letras B-O-N-U-S (Scatter) Gatilho 4+ Inicia Free Spins.

4.2 Notas sobre o Paytable

  1. Tucano Real: Único símbolo que paga com apenas 2 símbolos (1x aposta). Estratégia psicológica para criar esperança em giros que "quase" alcançam o bônus.

  2. Frutas em Stack: As frutas baixas aparecem frequentemente em "blocos" (stacks) de 3-4 símbolos para facilitar conexões com outros símbolos premium.

  3. Wild Raro: O Ovo de Ouro (Wild) aparece apenas no Tracker, centralizando a ação no meio da tela. Aumenta o "wow factor" quando aparece.

  4. Scatter: 4 ou mais letras (em qualquer ordem) ativam Free Spins. Não precisam estar adjacentes.


5. Mecanismo de Bônus: "Voo Livre"

5.1 Gatilho e Ativação

5.2 Multiplicador Infinito

Este é o coração do jogo:

Inicial: Multiplicador = 1x 1ª Cascata: Multiplicador = 2x 2ª Cascata: Multiplicador = 3x ... 15ª+ Cascata: Multiplicador = 16x+ (sem limite teórico)

Fórmula de Cálculo: Prêmio Final = Soma(Vitórias de Cascata) × Multiplicador Final

Exemplo Prático: - Giro 1: Ganha R$ 2,00 (sem cascata, Mult 1x). Resultado: R$ 2,00 - Giro 2: Ganha R$ 5,00 com 1 cascata (Mult 2x). Resultado: R$ 10,00 - Giro 3: Ganha R$ 8,00 com 3 cascatas (Mult 4x). Resultado: R$ 32,00 - ... - Giro 12: Ganha R$ 50,00 com 8 cascatas (Mult 10x). Resultado: R$ 500,00

Total do Bônus: R$ 2 + R$ 10 + R$ 32 + ... + R$ 500 = R$ 1.500+

5.3 Segurança e Caps

Embora teoricamente ilimitado, o multiplicador é controlado internamente:


6. Integração com Pool Finito (Lottopar)

6.1 Modelo de Pré-Determinação

Em um sistema regulado como Lottopar, o resultado final é pré-determinado antes da renderização. O jogo deve entregar um prêmio específico (ex: R$ 250,00).

Processo:

  1. Recebimento do Prêmio: Servidor retorna "Prêmio Final = R$ 250,00"
  2. Seleção de Template: Motor escolhe um template de altura que permita alcançar este valor
  3. Construção de Cenários: Motor simula milhões de combinações de bônus internamente
  4. Ajuste de Altura: A altura de cada rolo em cada giro grátis é ajustada para que o multiplicador + ganhos resultem em R$ 250,00
  5. Renderização: O jogo renderiza a sequência que entrega o resultado esperado

6.2 Algoritmo de Construção de Cenário (Reverse Scenario Builder)

```python def build_bonus_script(final_prize, num_spins=12): remaining_prize = final_prize bonus_script = []

for spin in range(num_spins):
    current_multiplier = spin + 1  # Começa em 1x

    # Quanto esta cascata deve pagar (antes de multiplicar)?
    spin_win = remaining_prize / (num_spins - spin)

    # Escolher altura das bobinas para alcançar este valor
    reel_template = select_template(spin_win)

    # Guardar configuração
    bonus_script.append({
        "spin": spin,
        "reel_config": reel_template,
        "base_win": spin_win,
        "multiplier": current_multiplier,
        "final_win": spin_win * current_multiplier
    })

    remaining_prize -= spin_win * current_multiplier

return bonus_script

```


7. Análise de RTP e Volatilidade

7.1 Curva de Volatilidade

RTP Hit Frequency Volatilidade Usado Em
90% 18% Extrema Rua (Denominação baixa)
94% 20% Extrema Standard (Denominação média)
97% 22% Extrema VIP (Denominação alta)

7.2 Diferenciadores por RTP

RTP 90% (Rua - Denominação R$ 0,10 a R$ 1,00): - Megaways raramente passa de 2.000 formas - Alturas ficam em 2-3 símbolos na maioria - Bônus com multiplicador máx 12x - Near miss frequente (jogo mostra "quase" valor alto)

RTP 94% (Standard - Denominação R$ 2,00 a R$ 5,00): - Megaways oscila entre 5.000 e 20.000 formas - Maior variedade de templates - Bônus com multiplicador máx 18x - Equilíbrio entre sustentação e prêmios

RTP 97% (VIP - Denominação R$ 10,00): - Megaways frequentemente atinge 50.000+ formas - Alturas altas (6-7 símbolos) mais comuns - "Max Megaways" (7-7-7-7-7-7) pode aparecer mesmo sem vitória, apenas para mostrar potencial - Bônus com multiplicador máx 25x+ - Maior potencial de Big Wins


8. Comportamento do Tracker (Bobina Horizontal)

8.1 Posicionamento e Funcionalidade

``` [Tracker contém 4 posições acima das colunas 2, 3, 4, 5]

     [T2] [T3] [T4] [T5]
     ---- ---- ---- ----
     [R2-1][R3-1][R4-1][R5-1]
     [R2-2][R3-2][R4-2][R5-2]
     ...

```

Regra Matemática: Um símbolo no Tracker conta como estando no topo da coluna correspondente. Logo: - Se R2 tem 4 símbolos e T2 tem 1 símbolo = R2 funciona com 5 símbolos para fins de Ways

8.2 Movimento do Tracker

8.3 Símbolos Únicos do Tracker


9. Máximo Potencial de Ganho (Max Win)

9.1 Cálculo do Max Win Teórico

Max Win = Maior Payout Possível (Tucano 6+) × Max Ways × Max Multiplier (Bônus) Max Win = 50x × 117.649 Ways × 25x Multiplier Max Win = 147.311.250x de aposta (teoricamente)

9.2 Max Win Prático (Caps Lottopar)

Lottopar limita o máximo pagável por aposta:

RTP Cap por Aposta
90% R$ 50.000
94% R$ 100.000
97% R$ 250.000

Assim, em uma aposta de R$ 10,00, o máximo observável seria: - RTP 90%: R$ 50.000 (5.000x) - RTP 94%: R$ 100.000 (10.000x) - RTP 97%: R$ 250.000 (25.000x)


10. Feature Buy (Compra de Bônus)

10.1 Implementação no Pool Finito

A "Compra de Bônus" é uma funcionalidade opcional que permite ao jogador "forçar" a entrada no bônus pagando um custo alto.

Mechanics: ``` Aposta Base: R$ 1,00 Multiplicador de Compra: 100x Custo Total: R$ 100,00

Fluxo: 1. Jogador clica em "Comprar Bônus" 2. Débito de R$ 100,00 3. Requisição de aposta de R$ 100,00 ao servidor Lottopar 4. Servidor retorna um prêmio (Ex: R$ 300,00) 5. Jogo força entrada no bônus com 4 Scatters visíveis 6. Jogo distribui R$ 300,00 ao longo do bônus de forma que o total bata com o retorno ```

10.2 Risco e Mitigação

Risco: Se o bilhete sorteado for R$ 0,00 (extremamente raro), o jogador paga R$ 100,00 e ganha Zero.

Mitigação: - Definir um piso de retorno mínimo (ex: 5x a aposta = R$ 500,00) - Ou deixar clara a natureza de risco nas termos de uso

10.3 Garantia Mínima Recomendada

Para evitar frustração, recomenda-se:

Se Prêmio Sorteado < 10x Custo de Compra: Prêmio Final = 10x Custo de Compra

Assim, mesmo no pior caso, o jogador ganha 10x (R$ 1.000,00 em uma compra de R$ 100,00).


11. Simulação Financeira (30 Dias / 1 Máquina)

11.1 Parâmetros de Simulação

Parâmetro Valor
Denominação Média R$ 2,00
Aposta Média 20 créditos = R$ 40,00
Giros por Hora 60 giros
Horas de Operação Diária 12 horas
Dias no Mês 30 dias

11.2 Projeção de Coin-In e GGR

Giros Mensais = 60 giros/hora × 12 horas × 30 dias = 21.600 giros Coin-In = 21.600 giros × R$ 40 = R$ 864.000 GGR (6% esperado) = R$ 51.840

11.3 Fluxo de Caixa Esperado

Semana Coin-In GGR Observações
1 R$ 216.000 R$ 12.960 Ramp-up inicial
2 R$ 216.000 R$ 12.960 Estável
3 R$ 216.000 R$ 12.960 Pico se bônus dispara
4 R$ 216.000 R$ 12.960 Manutenção
Total R$ 864.000 R$ 51.840 6% GGR

12. Design de Som (Soundscape)

12.1 Música Ambiente

12.2 SFX (Sound Effects)

Evento Som Descrição
Giro Base Rolos girando Som de rolos tradicionais, mas acelerado
Rolo Parando Clique nítido Cada rolo tem tom progressivo (C, D, E, F...)
Pequena Vitória Sino suave 1-2 cascatas
Cascata "Squish" de fruta Cada símbolo que cai soa como fruta suculenta explodindo
Max Megaways Sirene futurista Quando 7-7-7-7-7-7 aparece
Multiplicador +1 Nota ascendente Toque de sintetizador
Big Win Fanfarra Música clássica de circo acelerar até crescendo
Bônus Entrada Trompete de ouro Announces Free Spins

12.3 Volume e Dinâmica


13. Conformidade Lottopar (PR Regulation)

13.1 Requisitos Cumpridos

13.2 Documentação Obrigatória


14. Guia de Desenvolvimento

14.1 Linguagens Recomendadas

14.2 Checklist de Implementação


15. Glossário de Termos

Termo Definição
Ways Caminhos de ganho calculados pelo produto das alturas das bobinas
Megaways Sistema de ways dinâmicas (117.649 máximo)
Tracker Bobina horizontal acima das colunas 2-5
Cascata Explosão de símbolos + queda + re-verificação
Multiplicador Fator aplicado ao ganho durante o bônus (começa em 1x, +1 a cada cascata)
Pool Finito Sistema de pré-determinação Lottopar
Phantom Buffer Área de memória (7x14) com símbolos de reposição para cascatas
RTP Return to Player (porcentagem teórica paga ao longo do tempo)
Hit Frequency Frequência de vitórias (giros com ganho)
Feature Buy Opção de pagar para entrar imediatamente no bônus

Documentação Completa Assinada Documento Versão 1.0 — Apto para Desenvolvimento Data: 2026-04-03

Tucano Bonito — Technical Design Document (TDD)

Versão: 1.0 Data: 2026-04-03 Arquitetura: Megaways Engine com Pool Finito Integration Plataforma: Lottopar (PR Regulation)


1. Visão Geral Técnica

Tucano Bonito implementa um motor Megaways adaptatado para operar dentro do framework regulado Lottopar. Diferente de um RNG puro, cada giro é pré-determinado pelo servidor, que escolhe a altura das bobinas e distribui símbolos para alcançar um prêmio específico.

Arquitetura em Camadas: ┌──────────────────────────────────────┐ │ Front-end (HTML5/WebGL) │ │ - Renderização de Grade │ │ - Animações (Cascatas, etc) │ └──────────────┬──────────────────────┘ │ JSON RPC ┌──────────────▼──────────────────────┐ │ VltCore (C#/.NET Core) │ │ - Pool Finito Builder │ │ - Reel Strip Manager │ │ - Payout Engine │ └──────────────┬──────────────────────┘ │ TCP/SSL ┌──────────────▼──────────────────────┐ │ Lottopar Server (Regulado) │ │ - Gerador de Bilhetes │ │ - Validador de Resultados │ └──────────────────────────────────────┘


2. Reel Strip Configuration

2.1 Definição de Reel Strips

Cada bobina tem um "strip" (fita) contendo símbolos em ordem. A altura variável significa que cada giro pode usar um subset diferente do strip.

Reel 1 (Esquerda) - Premium Focus: ``` [Tucano, Arara, Sapo, Fruta1, Fruta2, Tucano, Arara, Sapo, Fruta1, Tucano, Arara, Fruta2, Sapo, Tucano, Arara, Fruta1, Sapo, Fruta2, Tucano, Arara]

Tamanho: 20 posições Peso do Tucano: 4/20 (20% - mais frequente para iniciar combos) Peso da Arara: 4/20 Peso do Sapo: 4/20 Peso Frutas: 8/20 ```

Reel 2-5 (Meio) - Balanced: ``` [Sapo, Fruta1, Fruta2, Tucano, Arara, Sapo, Fruta1, Arara, Tucano, Fruta2, Sapo, Tucano, Arara, Fruta1, Sapo, Fruta2, Arara, Tucano, Fruta1, Sapo]

Tamanho: 20 posições Pesos distribuídos uniformemente ```

Reel 6 (Direita) - Premium Heavy: ``` [Tucano, Tucano, Arara, Sapo, Fruta1, Tucano, Arara, Tucano, Fruta2, Sapo, Tucano, Arara, Fruta1, Tucano, Sapo, Fruta2, Tucano, Arara, Tucano, Fruta1]

Tamanho: 20 posições Peso do Tucano: 8/20 (40% - máximo para finalizar combos) ```

Tracker (Horizontal): ``` [Ovo de Ouro, Sapo, Fruta1, Fruta2, Sapo, Ovo de Ouro, Fruta1, Fruta2, Sapo, Ovo de Ouro, Ovo de Ouro, Sapo, Fruta1, Ovo de Ouro, Sapo, Fruta2]

Tamanho: 16 posições Peso do Wild (Ovo): 4/16 (25% - raro mas impactante) ```

2.2 Seleção Dinâmica de Height

O servidor não escolhe símbolos aleatoriamente. Ele escolhe um Template de Altura baseado no prêmio que precisa entregar:

Template Library:

Nome Alturas (R1-R6) Total Ways Uso
MINIMALIST 2-3-2-3-2-2 144 Giros perdedores rápidos
STANDARD 4-4-4-4-4-4 4.096 Giros com pequenas vitórias
EXPANDED 5-6-5-6-5-6 15.000+ Giros médios
MAX_MEGA 7-7-7-7-7-7 117.649 Eventos visuais de alto impacto

Seleção de Template (Pseudocódigo):

python def select_template(prize_to_deliver): """ Seleciona template baseado no prêmio esperado """ if prize_to_deliver < 2.0: # Muito baixo return MINIMALIST elif prize_to_deliver < 10.0: return STANDARD elif prize_to_deliver < 50.0: return EXPANDED else: # Para prêmios altos, pode usar MAX_MEGA # (aumenta chance de bônus ser acionado) return [EXPANDED, MAX_MEGA] # Mix


3. Algoritmo de Ways Calculator

3.1 Validação de Combinações

Uma vez que os símbolos estão dispostos, o motor calcula quais combinações pagam:

```python def calculate_ways(grid, reel_heights): """ grid: matriz [6][max_height] com símbolos reel_heights: array de alturas reais de cada rolo

Retorna: lista de combinações vencedoras
"""
winning_combos = []

# Para cada símbolo premium
for symbol_id in PAYABLE_SYMBOLS:
    # Verificar se existe em R1
    if symbol_exists_in_reel(symbol_id, grid[0]):
        # Contar quantas posições em R1
        count_r1 = count_symbol(symbol_id, grid[0])

        # Verificar R2
        if symbol_exists_in_reel(symbol_id, grid[1]):
            count_r2 = count_symbol(symbol_id, grid[1])

            # Verificar R3
            if symbol_exists_in_reel(symbol_id, grid[2]):
                count_r3 = count_symbol(symbol_id, grid[2])

                # Continuar até quebra
                # Se alcançar R6, é vitória completa
                if all_reels_connected(symbol_id, grid, 6):
                    ways = count_r1 * count_r2 * count_r3 * ...
                    payout = ways * PAY_TABLE[symbol_id][num_of_reels]
                    winning_combos.append({
                        'symbol': symbol_id,
                        'ways': ways,
                        'payout': payout
                    })

return winning_combos

```

3.2 Exemplo Prático

Situação na Tela: R1 R2 R3 R4 R5 R6 -- -- -- -- -- -- Arara Arara Arara Sapo ... ... Sapo Sapo Sapo ... ... ... Fruta Fruta Fruta ... ... ...

Cálculo: - Símbolo: Arara - Posições em R1: 1 - Posições em R2: 1 - Posições em R3: 1 - Posições em R4: 0 (Sapo, não Arara - quebra!) - Ways: 1 × 1 × 1 = 1 way - Payout (3 símbolos): 1 × 2.5x = 2.5x aposta


4. Pool Finito Integration (Scenario Builder)

4.1 Fluxo de Integração com Lottopar

┌─────────────────┐ │ Jogador aperta │ │ "SPIN" │ └────────┬────────┘ │ ┌────────▼────────────────────┐ │ VltCore envia requisição: │ │ { │ │ "game_id": "TUCANO", │ │ "player_id": "xxx", │ │ "bet_amount": 40.00 │ │ } │ └────────┬────────────────────┘ │ TCP/SSL ┌────────▼──────────────────────────┐ │ Lottopar Server: │ │ 1. Gera bilhete aleatório │ │ 2. Extrai prêmio do bilhete │ │ 3. Valida prêmio contra RTP │ │ 4. Retorna: "prize": 85.00 │ └────────┬──────────────────────────┘ │ ┌────────▼────────────────────┐ │ VltCore recebe prêmio: │ │ "prize": 85.00 │ └────────┬────────────────────┘ │ ┌────────▼────────────────────────────┐ │ Scenario Builder: │ │ 1. Seleciona template (STANDARD) │ │ 2. Popula símbolos para R$ 85,00 │ │ 3. Retorna grid + reel_heights │ └────────┬──────────────────────────────┘ │ ┌────────▼────────────────────┐ │ Front-end renderiza: │ │ - Grade com símbolos │ │ - Animação de reels │ │ - Cálculo de ways │ │ - Exibição de payout │ └────────────────────────────┘

4.2 Reverse Scenario Builder (Core Algorithm)

Este é o coração da integração. Dado um prêmio, como construir uma grade que pague exatamente este prêmio?

```python def build_winning_grid(target_prize, rtp_curve): """ target_prize: Ex: 85.00 (em reais) rtp_curve: Tabela de frequências de símbolo para este RTP

Retorna: grid (matriz), reel_heights (array), payout (confirmação)
"""

# Passo 1: Decompor prêmio em componentes menores
components = decompose_prize(target_prize)
# Exemplo: [
#     {"symbol": "Tucano", "ways": 6, "payout": 50},
#     {"symbol": "Arara", "ways": 7, "payout": 35}
# ]

# Passo 2: Inicializar grade vazia
grid = [[EMPTY] * 7 for _ in range(6)]

# Passo 3: Plantar sementes (winning symbols)
for component in components:
    plant_cluster(
        grid,
        component['symbol'],
        component['ways'],
        random_position()
    )

# Passo 4: Preencher resto com bloqueadores
fill_with_blockers(grid)

# Passo 5: Validar que nenhuma outra vitória foi criada
validate_no_accidental_wins(grid)

# Passo 6: Confirmar payout
calculated_payout = calculate_ways(grid)
assert abs(calculated_payout - target_prize) < 0.01

return grid, reel_heights, calculated_payout

```

4.3 Estratégia de Bloqueadores (Checkerboard)

Para garantir que nenhuma vitória acidental ocorra, usamos padrão de tabuleiro:

```python def fill_with_blockers(grid): """ Preenche espaços vazios com padrão alternado que previne conexões acidentais """ for row in range(len(grid)): for col in range(len(grid[row])): if grid[row][col] == EMPTY: # Padrão alternado (A, B, A, B...) symbol = BLOCKER_A if (row + col) % 2 == 0 else BLOCKER_B grid[row][col] = symbol

return grid

```

Exemplo visual: ``` Antes: [T, T, , , , , ] [T, T, , , , , ] [, , , , , , ] [, , , , , , ] [, , , , , , ] [, , , , , , ] [, , , , , , _]

Depois (com bloqueadores): [T, T, A, B, A, B, A] [T, T, B, A, B, A, B] [A, B, A, B, A, B, A] [B, A, B, A, B, A, B] [A, B, A, B, A, B, A] [B, A, B, A, B, A, B] [A, B, A, B, A, B, A] ```

Resultado: Nenhum símbolo "A" ou "B" conecta 5+, impossibilitando vitória acidental.


5. Cascata e Reações (Tumble Physics)

5.1 Motor de Cascata

```python class CascadeEngine: def init(self, grid, phantom_buffer): self.grid = grid # 7x7 viewport self.phantom = phantom_buffer # 7x14 (acima) self.cascades = [] self.total_multiplier = 1

def process_cascade(self):
    """
    Loop de cascata até não haver mais vitórias
    """
    cascade_index = 0

    while True:
        cascade_index += 1

        # 1. Detectar clusters vencedores
        winning_clusters = self.find_winning_clusters()

        if not winning_clusters:
            break  # Sem mais vitórias

        # 2. Registrar cascata
        cascade_event = {
            "cascade_num": cascade_index,
            "winning_clusters": winning_clusters,
            "multiplier": cascade_index + 1,  # 1x, 2x, 3x...
            "payout": sum(c.payout for c in winning_clusters)
        }
        self.cascades.append(cascade_event)

        # 3. Explodir símbolos
        self.explode_clusters(winning_clusters)

        # 4. Cair símbolos (gravity)
        self.apply_gravity()

        # 5. Repor do Phantom Buffer
        self.replenish_from_phantom()

    return self.cascades

def find_winning_clusters(self):
    """
    Usa Flood Fill para detectar clusters
    """
    visited = [[False] * 7 for _ in range(7)]
    clusters = []

    for row in range(7):
        for col in range(7):
            if not visited[row][col]:
                cluster = self.flood_fill(row, col, visited)
                if len(cluster) >= 5:  # Min cluster size
                    clusters.append(cluster)

    return clusters

def flood_fill(self, row, col, visited):
    """
    Algoritmo clássico de Flood Fill (Paint Bucket)
    """
    if row < 0 or row >= 7 or col < 0 or col >= 7:
        return []
    if visited[row][col]:
        return []

    symbol = self.grid[row][col]
    if symbol == EMPTY or symbol == BLOCKER:
        return []

    visited[row][col] = True
    cluster = [(row, col)]

    # Verificar 4 vizinhos
    for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
        cluster.extend(
            self.flood_fill(row + dr, col + dc, visited)
        )

    return cluster

def explode_clusters(self, clusters):
    """
    Remove símbolos vencedores da grade
    """
    for cluster in clusters:
        for row, col in cluster:
            self.grid[row][col] = EMPTY

def apply_gravity(self):
    """
    Símbolos caem para preencher vazios
    """
    for col in range(7):
        # Compactar coluna
        non_empty = []
        for row in range(7):
            if self.grid[row][col] != EMPTY:
                non_empty.append(self.grid[row][col])

        # Preencher de cima para baixo
        for row in range(7):
            if row < 7 - len(non_empty):
                self.grid[row][col] = EMPTY
            else:
                self.grid[row][col] = non_empty[row - (7 - len(non_empty))]

def replenish_from_phantom(self):
    """
    Puxar símbolos do Phantom Buffer acima
    """
    for col in range(7):
        # Contar vazios no topo
        empty_count = 0
        for row in range(7):
            if self.grid[row][col] == EMPTY:
                empty_count += 1
            else:
                break

        # Puxar do phantom
        for i in range(empty_count):
            symbol = self.phantom[14 - 1 - i][col]  # Pull from bottom of phantom
            self.grid[i][col] = symbol

        # Scroll phantom para cima (simular novo drop)
        self.phantom.pop()  # Remove última linha
        self.phantom.insert(0, self.generate_new_symbols(col))

```


6. Phantom Buffer (Extended Grid)

6.1 Arquitetura do Phantom Buffer

``` Memory Layout (Column View): ┌─────────────────────────────────┐ │ Phantom Buffer (7x14) - Above │ │ [P0,0] [P0,1] ... [P0,13] │ │ [P1,0] [P1,1] ... [P1,13] │ │ ... │ │ [P13,0][P13,1]... [P13,13] │ ├─────────────────────────────────┤ │ Viewport (7x7) - Visible │ │ [V0,0] [V0,1] ... [V0,6] │ │ [V1,0] [V1,1] ... [V1,6] │ │ ... │ │ [V6,0] [V6,1] ... [V6,6] │ └─────────────────────────────────┘

Total Memory: 7 x 21 = 147 slots por coluna ```

6.2 Preenchimento do Phantom Buffer

Quando símbolos caem durante cascatas, eles vêm do Phantom Buffer. O buffer deve ser pré-populado durante a construção da grade:

```python def build_phantom_buffer_content(target_prize, cascades_expected): """ Pré-computa conteúdo do phantom buffer para garantir que cascatas entregarão o prêmio correto """

phantom = [[EMPTY] * 7 for _ in range(14)]
remaining_prize = target_prize

for cascade in range(cascades_expected):
    prize_for_this_cascade = remaining_prize / (cascades_expected - cascade)

    # Selecionar símbolos que renderizarão este prêmio
    symbols = select_symbols_for_prize(prize_for_this_cascade)

    # Popular linha do phantom
    for col in range(7):
        phantom[cascade][col] = symbols[col]

    remaining_prize -= prize_for_this_cascade

# Preencher resto aleatoriamente
for row in range(cascades_expected, 14):
    for col in range(7):
        phantom[row][col] = random_non_winning_symbol()

return phantom

```


7. Feature Buy (Compra de Bônus)

7.1 Fluxo de Implementação

Player clica "Comprar Bônus" │ ▼ ┌────────────────────────────┐ │ VltCore verifica saldo: │ │ Custo = 100x aposta base │ │ = 100 × R$ 1,00 = R$ 100 │ └────────┬───────────────────┘ │ Débito validado ▼ ┌────────────────────────────┐ │ Envia aposta de R$ 100 │ │ para Lottopar Server │ └────────┬───────────────────┘ │ Retorna: prêmio ▼ ┌────────────────────────────┐ │ Prêmio retornado: R$ 450 │ │ (exemplo) │ └────────┬───────────────────┘ │ ▼ ┌────────────────────────────┐ │ Construir Bônus Script: │ │ - Forçar 4 Scatters │ │ - Distribuir R$ 450 em 12 │ │ giros com multiplicador │ └────────┬───────────────────┘ │ ▼ ┌────────────────────────────┐ │ Animar entrada no bônus │ │ Executar 12 giros grátis │ └────────────────────────────┘

7.2 Construtor de Script de Bônus

```python def build_bonus_script(feature_buy_prize, num_spins=12): """ Dado um prêmio (ex: R$ 450), distribui em N giros com multiplicador crescente """

bonus_script = []
remaining = feature_buy_prize

for spin_num in range(num_spins):
    multiplier = spin_num + 1  # 1x, 2x, 3x...

    # Cálculo de quanto este giro deve "ganhar" antes de multiplicar
    base_win = remaining / (num_spins - spin_num)

    # Selecionar template de altura que renderize este ganho
    reel_template = select_template(base_win)

    # Construir grid para este giro
    grid = build_grid_for_prize(base_win, reel_template)

    # Calcular cascatas
    cascades = process_cascades(grid)

    spin_script = {
        "spin_num": spin_num + 1,
        "reel_heights": reel_template,
        "grid": grid,
        "cascades": cascades,
        "base_win": base_win,
        "multiplier": multiplier,
        "final_win": cascades_total(cascades) * multiplier
    }

    bonus_script.append(spin_script)
    remaining -= spin_script["final_win"]

# Validação final
total_distributed = sum(s["final_win"] for s in bonus_script)
assert abs(total_distributed - feature_buy_prize) < 0.01

return bonus_script

```


8. Tracker (Top Reel) Implementation

8.1 Física do Tracker

O Tracker é uma bobina horizontal que desliza sobre as colunas 2, 3, 4, 5:

```python class TrackerMechanics: def init(self): self.tracker_symbols = [] # 4 posições self.tracker_position = 0 # 0-15 (posição no strip)

def spin_tracker(self):
    """
    Tracker gira junto com os rolos verticais
    """
    # Selecionar 4 símbolos consecutivos do tracker strip
    start_pos = random.randint(0, 11)  # 16 - 4 = 12

    self.tracker_symbols = [
        TRACKER_STRIP[start_pos + i] for i in range(4)
    ]

    return self.tracker_symbols

def apply_tracker_to_grid(self, grid):
    """
    Símbolos do tracker contam como estando
    no topo da coluna correspondente
    """
    # Tracker está sobre colunas 2, 3, 4, 5 (índices 1, 2, 3, 4)
    for tracker_col in range(4):
        grid_col = tracker_col + 1

        # Inserir símbolo do tracker como "virtual row 0"
        # Na prática, quando calculamos ways, contamos tracker também
        symbol = self.tracker_symbols[tracker_col]
        if symbol != EMPTY:
            # Este símbolo "contribui" para as ways
            grid[0][grid_col] = symbol

def handle_tracker_cascades(self, winning_clusters):
    """
    Se um símbolo do tracker participa de uma vitória,
    ele é removido e símbolos deslizam da direita
    """
    for cluster in winning_clusters:
        for row, col in cluster:
            if row == -1:  # Sinal especial para tracker
                # Remover símbolo do tracker
                tracker_col = col - 1  # Converter índice
                self.tracker_symbols[tracker_col] = EMPTY

    # Deslizar símbolos restantes para a esquerda
    self.tracker_symbols = [s for s in self.tracker_symbols if s != EMPTY]

    # Repor um novo símbolo da direita
    new_symbol = TRACKER_STRIP[random.randint(0, 15)]
    self.tracker_symbols.append(new_symbol)

```

8.2 Integração com Grid

```python def calculate_ways_with_tracker(grid, tracker): """ Ways calculator que leva em conta tracker """

# Aplicar tracker logicamente
effective_grid = [row[:] for row in grid]  # Deep copy

# Tracker coluna 2 (índice 1) tem símbolo tracker.symbols[0]
# Tracker coluna 3 (índice 2) tem símbolo tracker.symbols[1]
# etc...

# Quando verificamos ways, contamos como se o tracker
# adicionasse uma posição extra ao topo

for symbol_id in PAYABLE_SYMBOLS:
    # Para cada símbolo, contar em qual coluna aparece
    appearances = []

    for col in range(6):
        count = 0

        # Contar no grid normal
        for row in range(7):
            if effective_grid[row][col] == symbol_id:
                count += 1

        # Se tracker tem este símbolo nesta coluna, +1
        if col >= 1 and col <= 4:
            tracker_col = col - 1
            if tracker.tracker_symbols[tracker_col] == symbol_id:
                count += 1

        appearances.append(count)

    # Calcular ways (produto das contagens)
    # ...resto do cálculo normal...

```


9. RTP Curve Implementation

9.1 Tabelas de RTP

python RTP_CURVES = { "90": { "name": "Rua (Baixa Denominação)", "denominations": [0.10, 0.20, 0.50], "hit_frequency": 0.18, "max_multiplier": 12, "max_ways": 20000, "max_win_cap": 50000, "symbol_distribution": { "Tucano": 0.12, "Arara": 0.15, "Sapo": 0.18, "Frutas": 0.55 } }, "94": { "name": "Standard", "denominations": [2.00, 3.00, 5.00], "hit_frequency": 0.20, "max_multiplier": 18, "max_ways": 50000, "max_win_cap": 100000, "symbol_distribution": { "Tucano": 0.14, "Arara": 0.16, "Sapo": 0.20, "Frutas": 0.50 } }, "97": { "name": "VIP (Alta Denominação)", "denominations": [10.00], "hit_frequency": 0.22, "max_multiplier": 25, "max_ways": 117649, "max_win_cap": 250000, "symbol_distribution": { "Tucano": 0.16, "Arara": 0.18, "Sapo": 0.22, "Frutas": 0.44 } } }

9.2 Seleção de RTP em Runtime

```python def determine_rtp_for_spin(denomination, player_status): """ Escolhe qual RTP usar para este jogador/máquina """

if denomination <= 0.50:
    return "90"  # Rua
elif denomination <= 5.00:
    return "94"  # Standard
else:
    return "97"  # VIP

```


10. Payload JSON para Cliente

10.1 Estrutura de Resposta de Giro

```json { "spin_id": "SPIN_2026040312345", "timestamp": "2026-04-03T14:23:45.123Z", " "reel_config": { "heights": [4, 5, 4, 5, 4, 6], "total_ways": 7200, "template": "STANDARD_02" },

"initial_grid": [ [ {"id": 1, "symbol": "Tucano"}, {"id": 2, "symbol": "Arara"}, ... ], ... ],

"winning_combinations": [ { "symbol": "Arara", "count": 4, "ways": 8, "payout": 20.00 } ],

"cascades": [ { "cascade_num": 1, "removed_symbols": [[0,0], [0,1], [1,0], [1,1]], "new_symbols_grid": [ [ {"id": 3, "symbol": "Sapo"}, ... ] ], "new_winning_combos": [ { "symbol": "Sapo", "count": 5, "ways": 12, "payout": 15.00 } ], "multiplier": 2 } ],

"total_win": 35.00, "bonus_triggered": false } ```

10.2 Payload de Bônus

json { "bonus_session_id": "BONUS_2026040312346", "trigger_type": "free_spins", "num_spins": 12, "spins": [ { "spin_num": 1, "reel_heights": [6, 6, 5, 6, 5, 6], "grid": [...], "cascades": [...], "multiplier": 1, "spin_win": 5.00, "total_with_multiplier": 5.00 }, { "spin_num": 2, "reel_heights": [7, 7, 6, 7, 6, 7], "grid": [...], "cascades": [...], "multiplier": 2, "spin_win": 12.50, "total_with_multiplier": 25.00 }, ... ], "total_bonus_win": 1500.00 }


11. Hardware Specifications

11.1 Cabinet Requirements

Componente Especificação
CPU Intel i5-9400 ou equivalente
RAM 8GB DDR4
GPU NVIDIA GTX 1050 Ti (2GB VRAM)
Storage 256GB SSD
Display Principal 32" Full HD (1920x1080), 60Hz, IPS
Display Secundário 7" Touch (Opção de Menu)
Speaker Stereo 2x10W RMS
Conexão Ethernet 1Gbps
Alimentação PSU 500W, UPS backup

11.2 Requisitos de Software


12. SAS 6.02 / G2S Protocol

12.1 Integração SAS (Slot Accounting System)

Tucano Bonito deve reportar eventos ao controlador SAS da máquina:

Eventos Reportados via SAS 6.02: ├─ Machine Cash In/Out ├─ Meters Update (Coin-In, Coin-Out, Jackpots) ├─ Door Open/Close ├─ Ticket Printed ├─ Error Codes └─ Game Round Details

12.2 G2S (Game to System) Protocol

Comunicação com o sistema de supervisão:

G2S Events: ├─ "gamePlay.gameStarted" - Início de giro ├─ "gamePlay.gameEnded" - Fim de giro com resultado ├─ "bonusPlay.bonusStarted" - Entrada em bônus ├─ "bonusPlay.bonusEnded" - Fim do bônus ├─ "meters.meterClosed" - Fechamento de metro └─ "cabinet.systemError" - Erro crítico


13. Validação e Testes

13.1 Cheklist de QA

13.2 Regressão Matemática

```python def regression_test_rtp(num_spins=50000, rtp_target=0.94): """ Testa se RTP observado bate com esperado """ total_coin_in = 0 total_coin_out = 0

for _ in range(num_spins):
    spin_result = run_spin()
    total_coin_in += spin_result.bet_amount
    total_coin_out += spin_result.payout

observed_rtp = total_coin_out / total_coin_in
margin = abs(observed_rtp - rtp_target) / rtp_target

assert margin < 0.02, f"RTP deviation: {margin*100:.2f}%"
print(f"✓ RTP Test Passed: {observed_rtp:.4f} vs {rtp_target:.4f}")

```


14. Performance Optimization

14.1 Object Pooling

Criar e destruir objetos Unity durante cascatas causa lag:

```csharp public class SymbolPool { private Queue pool = new Queue(); private int poolSize = 60;

public Symbol GetSymbol()
{
    if (pool.Count > 0)
        return pool.Dequeue();
    else
        return Instantiate(symbolPrefab);
}

public void ReturnSymbol(Symbol sym)
{
    sym.gameObject.SetActive(false);
    pool.Enqueue(sym);
}

} ```

14.2 Asset Optimization


15. Debugging Tools

15.1 Developer Mode

```python

CMD + Shift + D para entrar em debug mode

Permite:

- Clicar na grade para mudar símbolos manualmente

- Forçar entrada em bônus

- Inspeccionar reel strips e paytable

- Ver valores de RTP em tempo real

```


Conclusão

Este TDD fornece especificação completa para implementação do Tucano Bonito. A integração com Pool Finito da Lottopar é crítica; todo resultado deve ser pré-determinado e validável.

Data de Conclusão: 2026-04-03 Status: Pronto para Desenvolvimento

Prompts de Geração de Arte IA

Clique em qualquer prompt para copiar. Os prompts abaixo são otimizados para Midjourney v6, DALL-E 3, e Stable Diffusion.

🎨 Cenário Principal
Proporção: 16:9
Professional slot game art, Brazilian rainforest canopy, ultra-detailed environment, immersive 3D background, lush vegetation and natural elements, tropical, colorful, vibrant, cinematic lighting with golden hour sun rays, color palette: tropical green, vibrant orange, bright yellow, depth of field creating focal point on game area, hyper-realistic textures, trending on ArtStation, Unreal Engine 5 quality, vibrant and saturated colors, --ar 21:9 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🏷️ Logo/Título
Proporção: 16:9
Logo design for "Tucano Bonito", ornate and elegant typography, bold letters with gold leaf embossing, luxurious gradient background transitioning from tropical green to vibrant orange, intricate decorative borders with toucan motifs, 3D dimensional effect with shadow depth, cinematic lighting, professional branding, high contrast, designed for high-visibility gaming cabinet, --ar 16:9 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎰 Símbolo 1
Proporção: 1:1
Premium game symbol for slot machine, toucan creature highly detailed, photorealistic rendering, vibrant colors emphasizing tropical green, vibrant orange, bright yellow, centered composition with transparent background, dramatic lighting with golden highlights, intricate feather/fur textures, 3D depth, game-ready asset, --ar 1:1 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎰 Símbolo 2
Proporção: 1:1
Game symbol: tropical flowers, ornate design with tropical green, vibrant orange, bright yellow color scheme, highly detailed intricate patterns, luxurious appearance, centered on clean background, dimensional shadow effect, professional slot machine graphics, golden accents, --ar 1:1 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎰 Símbolo 3
Proporção: 1:1
Collectible symbol: Brazilian rainforest, sparkling crystal or gem-like appearance, tropical green and vibrant orange dominant colors, glowing effect with light rays, highly detailed with reflective surfaces, centered composition, professional gaming asset quality, --ar 1:1 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎰 Símbolo 4
Proporção: 1:1
Bonus trigger symbol, colorful feathers, animated energy radiating from center, multiple layers of glow effects in bright yellow, ornate frame decoration, detailed fine art illustration, professional casino game quality, shimmering and ethereal, --ar 1:1 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎰 Símbolo 5
Proporção: 1:1
Premium scatter symbol, luxurious golden coin with fruit imagery, embossed surface detail, reflection and dimension, surrounded by floating particles and light, rich tropical green, vibrant orange, bright yellow palette, high-end game graphics, professional quality, --ar 1:1 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🎁 Tela de Bônus
Proporção: 16:9
Bonus round screen for slot game, explosive energy and celebration theme, multiple layers of special effects, tropical green, vibrant orange, bright yellow dominant colors, dramatic lighting with particle effects, progress bars and multiplier counters visible, luxurious animation frames, cinematic composition, game-ready quality, professional casino graphics, --ar 16:9 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
🖥️ Mockup UI
Proporção: 16:9
Complete game UI mockup for slot machine cabinet, professional layout with reels center stage, tropical green, vibrant orange, bright yellow theme throughout, game statistics visible (RTP, lines, bet), ornate frame decoration, luxury gaming interface, clear typography, buttons and controls well-positioned, premium aesthetic, high contrast readability, arcade cabinet quality, --ar 16:9 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado
Tela de Carregamento
Proporção: 21:9
Splash art loading screen for slot game, dramatic cinematic scene featuring toucan, intense tropical, colorful, vibrant atmosphere, tropical green, vibrant orange, bright yellow color palette, volumetric lighting effects, large title text with "Tucano Bonito", game studio logo placement, trending on gaming platforms, highly detailed and professionally rendered, advertisement-quality, --ar 21:9 --quality 2 --style raw
Dica: Use --no 'text, watermark, logo' para melhor resultado