Pitch: GoleRats, um app que transforma beber água em jogo
Todo app de lembrete de água que eu usei morreu na primeira semana. Eu instalava, ficava empolgado uns dias e depois esquecia que ele existia.
Então resolvi testar uma ideia: pegar as mecânicas que os jogos usam pra reter jogador e aplicar num hábito chato. Daí nasceu o GoleRats, um app Android (futuramente para IOS também) de hidratação. Neste post conto como ele funciona, as decisões de design que tomei e o que aprendi até agora.
O loop do app
Pensei o app em cima de quatro peças:
- Ação curta: registrar um gole leva um toque, em ml, litros ou copos, e a garrafa do dia vai enchendo;
- Recompensa diária: bateu a meta, o dia entra na ofensiva (streak), com recorde pessoal, gráfico da semana e calendário;
- Meta social: ranking com os amigos e ligas (da família, da firma, da academia), com placar semanal e mensal;
- Retenção: lembretes configuráveis que param sozinhos quando você bate a meta, e um resumo da semana toda segunda às 8h.
Decisões de design
O ranking conta dias de meta batida, não volume. Minha primeira ideia era ranquear por ml, mas aí ganharia quem tem o corpo maior ou quem exagera, e beber água demais também faz mal. Contando dias, cada um compete com a própria meta e o ranking fica justo. No empate, ganha quem chegou mais perto da meta em média.
A meta muda com o seu dia. Uma meta fixa é injusta, porque quem treinou ou pegou um dia de 35 °C precisa de mais água. A sugestão inicial usa o peso e a frequência de treino. No dia a dia, um toque em "Treinei hoje" sobe só a meta daquele dia. Na próxima versão, quem permitir a localização aproximada vai ter a meta ajustada sozinha nos dias quentes, pela previsão do tempo. E o ranking conta a meta do dia já com esses acréscimos, então ninguém sai prejudicado por ter treinado.
Não tem anti-cheat, e isso foi proposital. Não existe como verificar se a pessoa bebeu mesmo. Em vez de gastar tempo tentando resolver um problema sem solução, assumi: quem trapaceia só engana a si mesmo. Como as ligas são entre amigos, o próprio grupo faz esse papel.
Ninguém vê quanto você bebeu. Os amigos veem seus dias de meta batida e quanto da meta você cumpriu, em porcentagem, mas nunca o volume. Dá pra competir sem expor dados de saúde de ninguém.
Offline primeiro, conta opcional. Dá pra usar sozinho, sem cadastro, com tudo salvo no aparelho. A conta, que só pede um e-mail, serve pra guardar o histórico na nuvem, usar em outro celular e competir com os amigos.
Como construí
O app é feito em React Native com Expo, usando Expo Router pra navegação e TypeScript.
Tudo é gravado primeiro num SQLite local, e é por isso que o app funciona sem internet e sem conta. Quando a pessoa entra numa conta, um módulo de sincronização manda e busca as mudanças no Supabase (Postgres). O ranking, as ligas e o perfil dos amigos são funções SQL no próprio banco, com regras de acesso por linha (RLS) pra cada um só ver o que pode.
Os lembretes são notificações locais agendadas no aparelho. Os avisos sociais (pedido de amizade, convite de liga e o resumo da semana) são push, disparados pelo servidor. Pra builds e correções uso o EAS, que manda atualizações direto pro celular dos testadores sem passar de novo pela revisão da loja.
Algumas partes deram mais trabalho do que eu esperava:
- Juntar o uso offline com a conta. A pessoa usa o app uns dias sem cadastro e depois cria a conta, ou entra numa conta que já tinha dados em outro celular. Cada registro tem um ID gerado no aparelho e uma data de alteração, então dá pra juntar tudo sem duplicar, e quando os dois lados mudaram, vale a mudança mais recente. Registro apagado não some de verdade: ele ganha uma marca de "apagado" pra que a exclusão também chegue no outro aparelho.
- Mudar a meta sem reescrever o passado. Se você sobe a meta hoje, os dias antigos não podem passar a contar como meta não batida e quebrar a sua ofensiva. Por isso o app guarda a meta que valia em cada dia.
- A virada do dia. O "dia" de um registro é o dia no relógio da pessoa, não o do servidor. Senão, um gole às 23h podia cair no dia seguinte e bagunçar a ofensiva.
- Lembrete que sabe quando parar. Como o app é multiplataforma, já deixei pronto pro iOS, que aceita no máximo 64 notificações agendadas. Então o app agenda só os próximos dias e refaz a agenda sempre que é aberto. Quando você bate a meta, os lembretes restantes do dia são cancelados.
Uma coisa que aprendi sobre a Google Play
Eu não sabia disso antes de começar: conta pessoal de desenvolvedor criada recentemente não pode publicar direto na loja. Antes, a Google exige um teste fechado com um número mínimo de testadores participando por dias seguidos (hoje são 12 pessoas por 14 dias). Só depois disso você pode pedir acesso à produção.
Se você está pensando em publicar seu primeiro app, vale se planejar pra isso desde cedo, porque juntar testadores ativos leva mais tempo do que parece.
Estado atual e feedback
O app está nessa fase de teste fechado, só pra Android. Quem quiser testar pode se inscrever em https://golerats.zerox1b.dev.
Qualquer feedback ajuda, especialmente sobre:
- Se dá pra entender o app logo de cara;
- Se registrar a água é rápido o suficiente;
- Se o ranking motiva ou irrita;
- Se a ofensiva dá vontade de voltar no dia seguinte;
- Se a meta parece justa nos dias de treino e de calor;
- Bugs e travamentos.
A dúvida que ainda não resolvi
A ofensiva. O medo de perder a sequência funciona muito bem pra fazer a pessoa voltar, mas quando ela quebra no dia 40, a tendência é largar o app de vez. A mesma mecânica que retém acaba expulsando.
Estou pensando em algum tipo de proteção, tipo um congelamento que você ganha batendo a meta, ou num jeito de recuperar a sequência depois de quebrar. Quem já implementou streak em jogo ou app, como resolveu isso? Teve algum efeito colateral que eu deveria prever?