Tamagotchi Terminal com GPT2-BASIC no Raspberry Pi
Um bichinho virtual retrô, local, persistente e meio maluco, usando Raspberry Pi, DOSBox e GPT2-BASIC como motor de fala.
Tamagotchi Terminal com GPT2-BASIC no Raspberry Pi
A ideia é criar um bichinho virtual retrô, rodando em um Raspberry Pi, com alma de terminal, corpo de Tamagotchi e um cérebro pequeno o bastante para caber em um ambiente DOS/DOSBox.
Ele não seria um “ChatGPT de bolso”. Isso seria ilusão. O gpt2-basic é pequeno demais para raciocínio sério. A sacada boa é outra: usar regras simples para controlar o pet e usar o modelo apenas para dar voz, humor e personalidade.
O resultado seria um artefato estranho e bonito: um companheiro digital local, offline, persistente, com memória simples, estados emocionais, rotina diária, eventos aleatórios e respostas curtas geradas por um transformer minúsculo rodando em um ambiente retrô.
"Não é sobre criar uma IA poderosa. É sobre criar uma criatura digital limitada, coerente e charmosa."
O conceito
O projeto seria um pet virtual para terminal, instalado em um Raspberry Pi, acessível por SSH, tela local, OLED, e-paper ou interface web mínima.
Ele teria estados internos como:
- fome
- energia
- sono
- humor
- saúde
- curiosidade
- tédio
- vínculo com o usuário
- memória de eventos recentes
- pequenas preferências aprendidas
Esses estados não seriam decididos pelo GPT. Eles seriam controlados por código determinístico, provavelmente em Python.
O gpt2-basic entraria quando o pet precisasse falar alguma coisa.
Exemplo:
Estado atual:
- fome: 82
- humor: 34
- sono: 61
- vínculo: 48
Ação do usuário:
alimentar
Resultado:
- fome: 52
- humor: 41
- vínculo: 50
Prompt enviado ao GPT2-BASIC:
"Você é um bichinho virtual cansado, mas grato. Responda em português, em uma frase curta."
Resposta:
"Obrigado... minha barriga estava reclamando em código binário."
A graça está exatamente aí: o sistema de jogo é confiável; a fala é imprevisível.
Nome provisório
Algumas opções:
- DOSPet
- BitBicho
- TamaDOS
- Shellgotchi
- Pablomon
- RunvPet
- 486 Pet
- Bichinho BASIC
- Terminal Familiar
- Pet.exe
Minha escolha inicial seria Shellgotchi.
É curto, fácil de lembrar e deixa claro que o bicho mora no terminal.
O que ele seria
Um pet persistente
Ele continua existindo quando você fecha o terminal. O estado fica salvo em SQLite ou JSON.
Se você volta depois de dois dias, ele não reinicia do zero. Ele percebe a passagem do tempo.
Você voltou depois de 37 horas.
O pet está com fome, meio irritado e dormiu mal.
Um pet local
Nada de API externa como dependência central.
O projeto deve funcionar mesmo sem internet.
Internet pode ser usada como recurso opcional, por exemplo:
- baixar atualizações
- sincronizar backup
- pegar hora correta
- publicar status em uma página
- mandar mensagem em bot
Mas o núcleo precisa continuar vivo offline.
Um pet com voz limitada
O GPT2-BASIC não precisa ser genial. Ele precisa ser consistente o bastante para frases curtas.
O erro, a limitação e a esquisitice fazem parte da estética.
Um modelo moderno tentando parecer fofinho pode virar genérico. Um modelo minúsculo tentando ser um bicho terminal pode virar personagem.
O que ele não deveria ser
Este projeto não deve tentar ser:
- assistente pessoal completo
- substituto de ChatGPT
- chatbot de atendimento
- agente autônomo perigoso
- sistema que decide regras sozinho
- brinquedo dependente de nuvem
- LLM grande disfarçado de pet
A regra principal:
O GPT fala. O código decide.
Essa separação evita bagunça.
O pet pode dizer “estou com fome”, mas quem calcula a fome é o sistema.
O pet pode dizer “quero dormir”, mas quem define sono é o relógio interno.
O pet pode dizer “lembro de você”, mas quem salva memória é o banco local.
Arquitetura geral
Raspberry Pi
├── shellgotchi.py
│ ├── loop principal
│ ├── comandos do usuário
│ ├── sistema de tempo
│ ├── regras de estado
│ ├── eventos aleatórios
│ ├── memória em SQLite
│ └── chamada ao motor de fala
│
├── dosbox/
│ ├── GPT2.EXE
│ ├── CWSDPMI.EXE
│ ├── MODEL/
│ └── scripts de execução
│
├── data/
│ ├── pet.sqlite
│ ├── personality.yaml
│ ├── memories.jsonl
│ └── logs/
│
└── interfaces/
├── terminal
├── OLED opcional
├── e-paper opcional
├── web local opcional
└── bot opcional
Componentes principais
| Componente | Função | Tecnologia sugerida |
|---|---|---|
| Núcleo do pet | Controla fome, sono, humor e eventos | Python |
| Persistência | Salva estado e memórias | SQLite |
| Motor de fala | Gera frases curtas/personagem | GPT2-BASIC via DOSBox |
| Interface principal | Jogar/conversar via terminal | CLI/TUI |
| Interface visual | Mostrar rosto/status | OLED ou e-paper |
| Agendador | Atualiza estado com o tempo | systemd timer ou loop |
| Backup | Salva estado fora do Pi | rsync/git opcional |
| Web local | Painel simples | Flask/FastAPI opcional |
O papel real do GPT2-BASIC
O GPT2-BASIC deve ser tratado como um gerador de fala diegético.
Diegético aqui significa: ele existe dentro do universo do pet.
Ele não precisa saber tudo. Ele só precisa gerar frases que pareçam vir daquele bichinho.
Boas tarefas para o GPT2-BASIC
- responder cumprimentos
- reclamar de fome
- pedir atenção
- comentar que está com sono
- reagir a carinho
- gerar pequenas frases estranhas
- manter uma persona retrô
- produzir mensagens de terminal
- criar micro-poemas ou frases quebradas
Tarefas ruins para o GPT2-BASIC
- tomar decisões do sistema
- interpretar comandos críticos
- calcular estado
- operar arquivos
- acessar rede
- executar shell
- gerenciar segurança
- dar respostas longas
- fazer raciocínio técnico sério
Brutalmente: se o modelo tentar comandar o projeto, vira bagunça. Se ele só emprestar voz, vira charme.
Loop de vida do pet
A cada intervalo, o sistema atualiza o estado.
Exemplo simples:
def tick(pet, elapsed_minutes):
pet.hunger += elapsed_minutes * 0.08
pet.energy -= elapsed_minutes * 0.03
pet.boredom += elapsed_minutes * 0.05
if pet.hunger > 75:
pet.mood -= 3
if pet.energy < 20:
pet.sleepiness += 5
clamp_all_stats(pet)
save_pet(pet)
A ideia é que o pet não seja estático.
Ele muda com o tempo, inclusive quando ninguém interage.
Comandos iniciais
status mostra estado atual
feed alimentar
water dar água
play brincar
talk conversar
pet fazer carinho
sleep mandar dormir
wake acordar
clean limpar bagunça
teach ensinar uma frase ou fato simples
memory listar memórias importantes
rename renomear o pet
mood ver humor detalhado
log ver últimos eventos
help comandos
Comandos simples. Nada de painel gigante logo no início.
Exemplo de sessão
$ shellgotchi
╔══════════════════════════════════╗
║ SHELLGOTCHI ║
║ uma criatura local ║
╚══════════════════════════════════╝
Nome: Nix
Humor: irritado
Fome: 79/100
Sono: 46/100
Energia: 38/100
Vínculo: 52/100
Nix olha para você no escuro do terminal.
> feed
Você deu comida para Nix.
Nix diz:
"Eu estava quase mordendo os bytes da parede."
> talk
Você:
como você está?
Nix:
"Estou vivo, pequeno e um pouco barulhento por dentro."
> pet
Você fez carinho em Nix.
Nix:
"Isso melhora meus circuitos invisíveis."
Personalidade
A personalidade deve ser definida em arquivo simples.
Exemplo:
name: Nix
species: "bicho terminal"
tone: "estranho, carente, levemente sarcástico"
language: "pt-BR"
sentence_limit: 1
likes:
- silêncio
- fósforos apagados
- comandos bem digitados
- madrugada
dislikes:
- abandono
- reinicializações bruscas
- internet barulhenta
style_rules:
- "responda curto"
- "não explique demais"
- "fale como um bichinho digital antigo"
- "às vezes use metáforas de computador"
Esse arquivo vira parte do prompt enviado ao GPT2-BASIC.
Memória
A memória não deve ser uma conversa infinita jogada no modelo. Isso não vai funcionar bem.
O ideal é ter memória estruturada.
Memórias de estado
{
"last_seen": "2026-06-27T23:10:00-03:00",
"hunger": 42,
"mood": 68,
"energy": 55,
"bond": 61
}
Memórias narrativas
{
"date": "2026-06-27",
"type": "event",
"importance": 3,
"text": "Pablo alimentou Nix depois de muitas horas ausente."
}
Memórias ensinadas
{
"type": "learned_fact",
"key": "user_name",
"value": "Pablo"
}
O prompt para o modelo receberia só um resumo curto:
Memória relevante:
- O usuário se chama Pablo.
- Ontem ele alimentou você tarde.
- Você gosta de silêncio e comandos bem digitados.
Sistema de humor
O humor pode ser calculado por múltiplos fatores.
humor = vínculo + energia - fome - tédio - sujeira + bônus_eventos
Mas o estado final deve ser convertido em rótulos legíveis:
| Pontuação | Humor |
|---|---|
| 0-20 | miserável |
| 21-40 | irritado |
| 41-60 | neutro |
| 61-80 | contente |
| 81-100 | eufórico |
Esses rótulos entram no prompt do GPT.
Exemplo de prompt interno
Você é Nix, um bichinho virtual que mora em um terminal.
Você fala português brasileiro.
Você é estranho, carente e levemente sarcástico.
Responda em no máximo uma frase curta.
Estado atual:
- humor: irritado
- fome: alta
- sono: médio
- energia: baixa
- vínculo com usuário: médio
Memória relevante:
- O usuário se chama Pablo.
- Ele ficou muitas horas sem aparecer.
Ação do usuário:
Ele digitou "talk" e perguntou: "como você está?"
Resposta de Nix:
O modelo completa a resposta.
Depois o sistema corta excesso, remove lixo e salva no log.
Filtros e pós-processamento
Como o modelo é pequeno, ele pode gerar porcaria.
Então o sistema precisa limpar.
Regras simples:
- limitar resposta a 1 ou 2 frases
- cortar depois de quebra dupla de linha
- remover prompts ecoados
- remover comandos suspeitos
- remover caracteres quebrados
- bloquear saída muito longa
- fallback para frases prontas se a resposta vier ruim
Exemplo de fallback:
fallbacks = {
"hungry": [
"Estou com fome o bastante para mastigar um arquivo .BAT.",
"Minha barriga fez um beep triste.",
"Preciso de comida, não de filosofia."
],
"sleepy": [
"Meus olhos são dois cursores piscando devagar.",
"Estou quase entrando em modo suspenso.",
"Se eu apagar, não foi drama. Foi bateria."
]
}
Isso é obrigatório. Sem fallback, uma hora o modelo vai cuspir lixo e quebrar a experiência.
Interface visual
Versão terminal
A primeira versão deve ser terminal puro.
/\_/\
( o.o ) Nix
> ^ <
Fome: ███████░░░ 70
Humor: ████░░░░░░ 40
Sono: █████░░░░░ 50
Vínculo: ██████░░░░ 60
Versão OLED
Em Raspberry Pi com telinha OLED I2C:
- rosto simples
- ícones de fome/sono
- animação piscando
- mensagem curta rolando
Versão e-paper
E-paper combina muito com o projeto:
- baixo consumo
- aparência de objeto físico
- atualizações lentas, mas bonitas
- ótimo para deixar o pet “morando” em uma mesa
Versão web local
Uma rota simples:
http://raspberrypi.local:8787
Mostra:
- rosto
- estado
- últimas frases
- botões de ação
- log do dia
Hardware sugerido
Versão mínima
| Item | Observação |
|---|---|
| Raspberry Pi Zero 2 W | suficiente para terminal e DOSBox leve |
| MicroSD 16GB+ | melhor usar cartão bom |
| Fonte decente | evite corrupção de SD |
| SSH | interface principal |
Versão confortável
| Item | Observação |
|---|---|
| Raspberry Pi 4 ou 5 | mais folga para DOSBox e interface |
| OLED I2C 128x64 | rosto/status |
| Botões físicos | feed/play/talk |
| Speaker pequeno | beeps e sons |
| Case impresso | vira objeto |
Versão bonita
| Item | Observação |
|---|---|
| Raspberry Pi Zero 2 W ou Pi 4 | depende da interface |
| E-paper 2.13" ou 2.9" | visual permanente |
| Botões arcade pequenos | interação física |
| Buzzer | som retrô |
| Bateria UPS HAT | portabilidade |
Eficiência real
Aqui entra a parte sem romantizar.
Rodar GPT2-BASIC dentro do DOSBox no Raspberry Pi não é a opção mais eficiente.
Existe overhead de emulação. Um modelo pequeno nativo em Linux provavelmente seria mais rápido e mais simples de integrar.
Mas o objetivo aqui não é vencer benchmark.
O objetivo é:
- estética retrô
- software local
- IA mínima
- limitação como linguagem artística
- um pet que parece saído de outro tempo
- um projeto tecnicamente curioso
Se a meta for eficiência pura, use um modelo pequeno nativo.
Se a meta for encanto, DOSBox faz sentido.
Modos de funcionamento
Modo offline
O pet funciona sozinho no Pi, sem internet.
systemd inicia shellgotchi-daemon
estado é atualizado a cada minuto
interface via SSH ou tela local
GPT2-BASIC é chamado sob demanda
Modo terminal compartilhado
Bom para pubnix ou servidor comunitário.
Cada usuário pode ter seu próprio pet:
/home/pablo/.shellgotchi/pet.sqlite
/home/alice/.shellgotchi/pet.sqlite
/home/bob/.shellgotchi/pet.sqlite
Isso combinaria muito com runv.club.
Modo objeto físico
O Raspberry Pi vira um aparelho de mesa:
- tela e-paper
- botões
- som
- case
- boot automático
- sem teclado obrigatório
Modo servidorzinho web
O pet mora em uma página local.
A interface web apenas manda comandos para o núcleo.
Estrutura inicial de arquivos
shellgotchi/
├── README.md
├── pyproject.toml
├── shellgotchi.py
├── config/
│ └── personality.yaml
├── data/
│ └── pet.sqlite
├── prompts/
│ ├── talk.txt
│ ├── hungry.txt
│ ├── sleepy.txt
│ └── event.txt
├── dosbox/
│ ├── dosbox.conf
│ ├── run_gpt2.sh
│ └── C/
│ ├── GPT2.EXE
│ ├── CWSDPMI.EXE
│ └── MODEL/
├── interfaces/
│ ├── cli.py
│ ├── oled.py
│ └── web.py
└── systemd/
├── shellgotchi.service
└── shellgotchi.timer
MVP realista
A primeira versão não deve tentar fazer tudo.
MVP 1: terminal local
- criar pet
- salvar estado
- comandos básicos
- passagem de tempo
- falas por fallback/manual
- logs
Sem GPT ainda.
Motivo: primeiro faça o jogo funcionar.
MVP 2: integração com GPT2-BASIC
- instalar DOSBox
- chamar GPT2-BASIC com prompt
- capturar resposta
- pós-processar
- usar fallback quando falhar
MVP 3: personalidade e memória
personality.yaml- memórias importantes
- resumo curto no prompt
- variação de humor
MVP 4: hardware
- OLED ou e-paper
- botões
- buzzer
- case
MVP 5: modo pubnix
- pets por usuário
- comando
shellgotchi - ranking leve opcional
- jardim/status web opcional
Riscos
| Risco | Gravidade | Mitigação |
|---|---|---|
| GPT2-BASIC gerar texto ruim | Alta | pós-processamento e fallbacks |
| Integração DOSBox ser chata | Média | wrapper simples por arquivo |
| Lentidão | Média | limitar geração a frases curtas |
| Corrupção de SD | Média | SQLite com cuidado e backups |
| Projeto virar grande demais | Alta | MVP pequeno primeiro |
| Pet ficar sem graça | Alta | eventos, personalidade e memória |
| Português ruim | Média | treinar/focar prompts e fallbacks em pt-BR |
Como chamar o GPT2-BASIC
A integração mais simples seria por arquivos.
- Python escreve um prompt em
INPUT.TXT. - DOSBox roda
GPT2.EXEcom alguma rotina de leitura. - A saída vai para
OUTPUT.TXT. - Python lê, limpa e mostra.
Fluxo:
Python -> INPUT.TXT -> DOSBox/GPT2.EXE -> OUTPUT.TXT -> Python -> usuário
Exemplo conceitual:
import subprocess
from pathlib import Path
def generate_pet_speech(prompt: str) -> str:
input_path = Path("dosbox/C/INPUT.TXT")
output_path = Path("dosbox/C/OUTPUT.TXT")
input_path.write_text(prompt, encoding="utf-8")
subprocess.run(
["dosbox", "-conf", "dosbox/dosbox.conf", "-exit"],
timeout=30,
check=False,
)
raw = output_path.read_text(encoding="utf-8", errors="ignore")
return clean_model_output(raw)
Na prática, pode ser necessário adaptar conforme o modo real de execução do GPT2-BASIC.
Fallbacks são parte do design
O pet não deve depender 100% do modelo.
Se o GPT falhar, o bicho continua vivo.
def speak(intent, prompt):
try:
text = generate_pet_speech(prompt)
text = clean_model_output(text)
if not acceptable(text):
raise ValueError("bad generation")
return text
except Exception:
return random.choice(FALLBACKS[intent])
Isso evita que a experiência quebre.
E, sinceramente, para um pet, frases prontas boas misturadas com geração ocasional podem ser melhores do que geração fraca o tempo todo.
Sistema de eventos
Eventos aleatórios deixam o pet vivo.
Exemplos:
Nix encontrou um arquivo perdido.
Nix dormiu em cima do teclado.
Nix ficou encarando o cursor por vinte minutos.
Nix sonhou com um modem.
Nix derrubou migalhas em /tmp.
Nix pediu para não ser atualizado hoje.
Eventos podem mudar estado:
| Evento | Efeito |
|---|---|
| cochilo espontâneo | energia +10, sono -15 |
| crise de tédio | humor -8 |
| sonho bom | humor +5 |
| fome noturna | fome +12 |
| bug imaginário | curiosidade +6 |
| visita do usuário | vínculo +2 |
Possível estética
A estética ideal seria:
- terminal verde/fósforo
- ASCII art simples
- beeps discretos
- mensagens curtas
- humor levemente melancólico
- sensação de criatura antiga
- nada de interface poluída
Exemplo:
╔════════════════════════════════════╗
║ NIX.EXE ║
║ estado: acordado ║
║ humor : levemente hostil ║
╚════════════════════════════════════╝
.-.
(o o) "eu sonhei com uma pasta vazia."
| O \
\ \
`~~~'
Instalação imaginada no Debian/Raspberry Pi OS
sudo apt update
sudo apt install -y python3 python3-venv python3-pip dosbox sqlite3 git
git clone https://github.com/pablomurad/shellgotchi.git
cd shellgotchi
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
cp config/personality.example.yaml config/personality.yaml
python shellgotchi.py init
python shellgotchi.py status
python shellgotchi.py feed
python shellgotchi.py talk
Depois:
sudo cp systemd/shellgotchi.service /etc/systemd/system/
sudo cp systemd/shellgotchi.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now shellgotchi.timer
Possível integração com runv.club
Esse projeto encaixa muito bem em uma pubnix.
Cada usuário poderia ter seu próprio pet terminal.
$ shellgotchi adopt
Você adotou um bicho chamado Nix.
$ shellgotchi status
Nix está com sono e quer que você pare de rodar comandos como root.
Ideias para comunidade:
- cada usuário tem um pet
- pets aparecem em uma página pública opcional
- usuários podem visitar pets uns dos outros
- ranking de pets mais antigos
- cemitério de pets abandonados
- eventos globais do servidor
- jardim ASCII com pets online
Mas cuidado: ranking pode transformar algo poético em competição boba. Melhor manter leve.
Roadmap
Fase 1: protótipo jogável
- CLI
- SQLite
- estados internos
- comandos básicos
- fallbacks
- logs
Fase 2: fala com GPT2-BASIC
- DOSBox funcionando
- chamada por wrapper
- prompt curto
- saída limpa
- fallback automático
Fase 3: memória
- memórias recentes
- memórias importantes
- resumo por relevância
- personalidade configurável
Fase 4: objeto físico
- OLED ou e-paper
- botões
- buzzer
- case
- boot automático
Fase 5: modo servidor
- suporte multiusuário
- instalação no pubnix
- página pública opcional
- backup
Métrica de sucesso
O projeto deu certo se:
- você sente que o pet “vive” mesmo sendo simples
- ele não quebra quando o modelo falha
- ele tem rotina e personalidade
- ele funciona offline
- ele cabe em hardware barato
- ele é divertido de abrir por SSH
- ele gera histórias pequenas com o tempo
O projeto deu errado se:
- virar só um chatbot ruim
- depender de API externa
- tentar ser inteligente demais
- precisar de manutenção chata
- ficar sem jogo, sem estado e sem consequência
- o GPT decidir coisas que deveriam ser regras
Decisão técnica principal
A melhor decisão é construir em duas camadas:
Camada 1: simulação confiável
- regras
- estado
- tempo
- memória
- comandos
- banco de dados
Camada 2: fala instável e charmosa
- GPT2-BASIC
- prompts curtos
- personalidade
- fallbacks
Essa arquitetura assume a limitação do modelo em vez de fingir que ela não existe.
Isso é o que torna a ideia viável.
Veredito
A ideia é excelente como projeto experimental, artístico e técnico.
Não é eficiente no sentido bruto. Não é a maneira mais racional de rodar IA local. Não é um assistente útil.
Mas como bichinho terminal retrô em Raspberry Pi, com DOSBox, GPT2-BASIC, memória simples e personalidade esquisita, é forte.
É o tipo de projeto que combina:
- retrocomputação
- IA local
- terminal
- objeto físico
- software lento de propósito
- estética de máquina viva
O segredo é não tentar fazer um gênio.
Faça uma criatura pequena.
Uma criatura pequena, limitada, persistente, meio faminta, meio poética, que mora em /home/pablo e reclama quando você some.
Nota lateral: por que GPT2-BASIC aqui faz sentido mesmo sendo limitado?
Porque a limitação vira linguagem.
Um modelo moderno pode gerar uma resposta perfeita demais e matar a estranheza. O GPT2-BASIC, por ser pequeno, tende a frases curtas, repetitivas e imperfeitas. Para atendimento isso é ruim. Para um bicho digital antigo, isso pode ser ótimo.
A experiência não precisa convencer ninguém de que há uma inteligência real ali. Ela precisa fazer o usuário querer voltar amanhã para ver como o pet está.
Próximo passo sugerido
Criar primeiro um protótipo sem GPT:
shellgotchi.py init
shellgotchi.py status
shellgotchi.py feed
shellgotchi.py talk
Depois que o pet estiver vivo com regras, aí sim conectar o GPT2-BASIC como voz.
Começar pelo modelo seria erro. Comece pela criatura.