Moon Flower Society > 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.
Posted June 27, 2026. Markdown. Tags: raspberry-pi, ia-local, dosbox, gpt2-basic, tamagotchi, retrocomputacao, terminal.
Revised Oct 24, 2026 (reorganization). "As seções sobre a fala do pet agora ficam juntas, na ordem em que rodam: prompt, chamada ao GPT2-BASIC, filtros e fallbacks."What changed | 1 revision
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 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:
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.
Algumas opções:
Minha escolha inicial seria Shellgotchi.
É curto, fácil de lembrar e deixa claro que o bicho mora no terminal.
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.
Nada de API externa como dependência central.
O projeto deve funcionar mesmo sem internet.
Internet pode ser usada como recurso opcional, por exemplo:
Mas o núcleo precisa continuar vivo offline.
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.
Este projeto não deve tentar ser:
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.
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
| 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 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.
Brutalmente: se o modelo tentar comandar o projeto, vira bagunça. Se ele só emprestar voz, vira charme.
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.
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.
$ 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."
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.
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.
{
"last_seen": "2026-06-27T23:10:00-03:00",
"hunger": 42,
"mood": 68,
"energy": 55,
"bond": 61
}
{
"date": "2026-06-27",
"type": "event",
"importance": 3,
"text": "Pablo alimentou Nix depois de muitas horas ausente."
}
{
"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.
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.
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.
A integração mais simples seria por arquivos.
INPUT.TXT.GPT2.EXE com alguma rotina de leitura.OUTPUT.TXT.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.
Como o modelo é pequeno, ele pode gerar porcaria.
Então o sistema precisa limpar.
Regras simples:
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.
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.
A primeira versão deve ser terminal puro.
/\_/\
( o.o ) Nix
> ^ <
Fome: ███████░░░ 70
Humor: ████░░░░░░ 40
Sono: █████░░░░░ 50
Vínculo: ██████░░░░ 60
Em Raspberry Pi com telinha OLED I2C:
E-paper combina muito com o projeto:
Uma rota simples:
http://raspberrypi.local:8787
Mostra:
| 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 |
| 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 |
| 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 |
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 é:
Se a meta for eficiência pura, use um modelo pequeno nativo.
Se a meta for encanto, DOSBox faz sentido.
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
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.
O Raspberry Pi vira um aparelho de mesa:
O pet mora em uma página local.
A interface web apenas manda comandos para o núcleo.
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
A primeira versão não deve tentar fazer tudo.
Sem GPT ainda.
Motivo: primeiro faça o jogo funcionar.
personality.yamlshellgotchi| 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 |
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 |
A estética ideal seria:
Exemplo:
╔════════════════════════════════════╗
║ NIX.EXE ║
║ estado: acordado ║
║ humor : levemente hostil ║
╚════════════════════════════════════╝
.-.
(o o) "eu sonhei com uma pasta vazia."
| O \
\ \
`~~~'
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
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:
Mas cuidado: ranking pode transformar algo poético em competição boba. Melhor manter leve.
O projeto deu certo se:
O projeto deu errado se:
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.
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:
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.
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á.
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.
View the original Markdown file
Ideas | What changed | RSS | About | Text version
Pablo Murad <pablomurad@pm.me>