- Visão Geral
- Arquitetura do Projeto
- Estrutura de Pastas
- Tecnologias e Dependências
- Modelos de Dados
- Camada de Dados
- Camada de Lógica (Providers)
- Camada de UI
- Tema e Design System
- Fluxos Principais
- Como Executar
- Próximos Passos
LifeRPG é um aplicativo Flutter que gamifica tarefas do dia a dia, transformando atividades rotineiras em missões de RPG. O projeto permite que usuários:
- ✅ Criem e gerenciem missões (tarefas)
- 📊 Acompanhem progresso através de XP e níveis
- 🎯 Desenvolvam habilidades (skills) relacionadas às missões
- 💎 Ganhem pontos de recompensa
- 📈 Visualizem estatísticas e gráficos de progresso
O app funciona como um RPG onde:
- Missões = Tarefas do dia a dia
- XP (Experiência) = Progresso do jogador
- Level = Nível do jogador baseado no XP acumulado
- Skills = Habilidades que podem ser desenvolvidas
- Reward Points = Moeda virtual para recompensas
- Energy = Energia do jogador (HP)
O projeto segue uma arquitetura em camadas (Layered Architecture):
┌─────────────────────────────────────┐
│ UI Layer (Screens/Widgets) │
│ ───────────────────────────────── │
│ - Telas (Screens) │
│ - Componentes Reutilizáveis │
│ - Navegação │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Logic Layer (Providers) │
│ ───────────────────────────────── │
│ - PlayerProvider │
│ - MissionProvider │
│ - SkillProvider │
│ - State Management (Provider) │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Data Layer (Repositories) │
│ ───────────────────────────────── │
│ - PlayerRepository │
│ - MissionRepository │
│ - SkillRepository │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Database Layer (SQLite) │
│ ───────────────────────────────── │
│ - DatabaseHelper │
│ - Schema & Migrations │
└─────────────────────────────────────┘
- Separação de Responsabilidades: Cada camada tem uma responsabilidade específica
- Inversão de Dependências: Camadas superiores dependem de abstrações
- State Management: Provider para gerenciamento de estado reativo
- Repository Pattern: Abstração da camada de dados
lib/
├── main.dart # Ponto de entrada da aplicação
│
├── core/ # Funcionalidades centrais
│ ├── constants/
│ │ └── app_strings.dart # Constantes de strings
│ ├── theme/
│ │ └── app_theme.dart # Tema e cores da aplicação
│ └── utils/
│ └── xp_calculator.dart # Cálculos de XP e níveis
│
├── data/ # Camada de dados
│ ├── database/
│ │ └── database_helper.dart # Configuração do SQLite
│ ├── models/ # Modelos de dados
│ │ ├── player.dart # Modelo do jogador
│ │ ├── mission.dart # Modelo de missão
│ │ └── skill.dart # Modelo de habilidade
│ └── repositories/ # Repositórios (acesso aos dados)
│ ├── player_repository.dart
│ ├── mission_repository.dart
│ └── skill_repository.dart
│
├── providers/ # State Management (Provider)
│ ├── player_provider.dart
│ ├── mission_provider.dart
│ └── skill_provider.dart
│
└── ui/ # Interface do usuário
├── screens/ # Telas da aplicação
│ ├── main_screen.dart # Tela principal (navegação)
│ ├── missions/
│ │ ├── missions_list_screen.dart
│ │ ├── mission_editor_screen.dart
│ │ └── mission_form_screen.dart
│ └── skills/
│ └── skills_view.dart
│
└── widgets/ # Componentes reutilizáveis
├── common/
│ ├── app_drawer.dart # Menu lateral
│ ├── icon_picker_dialog.dart
│ ├── level_badge.dart
│ └── xp_bar.dart
├── mission/
│ ├── mission_card.dart # Card de missão
│ └── mission_list_item.dart
├── player/
│ └── player_stats_header.dart # Header com stats do jogador
└── skill/
└── skill_linear_item.dart
- Flutter (SDK ^3.10.4)
- provider (^6.1.5+1) - Gerenciamento de estado reativo
- sqflite (^2.4.2) - SQLite para mobile
- sqflite_common_ffi (^2.4.0+1) - SQLite para desktop (Linux/Windows/macOS)
- path_provider (^2.1.5) - Caminhos de diretórios
- path (^1.9.1) - Manipulação de caminhos
- google_fonts (^6.3.3) - Fontes do Google (Roboto)
- font_awesome_flutter (^10.12.0) - Ícones FontAwesome
- flutter_svg (^2.2.3) - Suporte a SVG
- fl_chart (^1.1.1) - Gráficos (RadarChart, etc)
- flutter_animate (^4.5.2) - Animações
- percent_indicator (^4.2.5) - Indicadores de progresso
- intl (^0.20.2) - Internacionalização e formatação
- uuid (^4.5.2) - Geração de UUIDs
- flutter_lints (^6.0.0) - Linting e análise de código
Representa o jogador principal do sistema.
class Player {
final int id; // ID único (sempre 1)
final String name; // Nome do jogador
final int totalXP; // XP total acumulado
final int level; // Nível atual
final int rewardPoints; // Pontos de recompensa
final String? avatarPath; // Caminho do avatar
final int currentEnergy; // Energia atual (HP)
final String themeMode; // Modo de tema
final DateTime createdAt; // Data de criação
final DateTime updatedAt; // Última atualização
}Características:
- Singleton: Apenas um jogador pode existir (id = 1)
- Level é calculado automaticamente baseado no
totalXP currentEnergyrepresenta a energia/HP do jogador
Representa uma tarefa/missão que o jogador pode completar.
class Mission {
final int? id; // ID único (null se nova)
final String title; // Título da missão
final String description; // Descrição detalhada
final int difficulty; // Dificuldade (1-5)
final int urgency; // Urgência (1-5)
final int fear; // Medo/Ansiedade (1-5)
final int energyRequired; // Energia necessária (1-5)
final int xpReward; // XP ganho ao completar
final int rewardPoints; // Pontos de recompensa
final String status; // 'active', 'completed', 'archived'
final DateTime? dueDate; // Data de vencimento
final int? estimatedDuration; // Duração estimada (minutos)
final bool isRecurring; // É recorrente?
final String? recurrenceType; // 'daily', 'weekly', 'monthly', etc
final int? parentMissionId; // ID da missão pai (subtasks)
final String? icon; // Caminho do ícone SVG
final String? emoji; // Emoji alternativo
final List<int> skillIds; // IDs das skills relacionadas
// ... timestamps
}Características:
- Suporta hierarquia (missões pai/filho para subtasks)
- Pode ser recorrente (diária, semanal, etc)
- Relacionamento many-to-many com Skills
- Atributos gamificados (difficulty, urgency, fear)
Representa uma habilidade que pode ser desenvolvida.
class Skill {
final int? id; // ID único
final String name; // Nome da habilidade
final String description; // Descrição
final int currentXP; // XP atual da skill
final int level; // Nível atual
final String color; // Cor (hex)
final String? icon; // Ícone
final bool isActive; // Está ativa?
// ... timestamps
}Características:
- Cada skill tem seu próprio XP e nível
- Skills ganham XP quando missões relacionadas são completadas
- Sistema de níveis independente do jogador
Singleton que gerencia a conexão com o banco SQLite.
Localização: lib/data/database/database_helper.dart
Responsabilidades:
- Inicialização do banco de dados
- Criação do schema (tabelas)
- Migrações (onUpgrade)
- Configuração de foreign keys
Schema do Banco:
-
Tabela
player- Armazena dados do jogador (singleton, id = 1)
-
Tabela
missions- Armazena todas as missões
- Foreign key para
parent_mission_id(subtasks) - Índices em
statuseparent_mission_id
-
Tabela
skills- Armazena habilidades
- Soft delete com
is_active
-
Tabela
mission_skills(Junction Table)- Relacionamento many-to-many entre missions e skills
- Foreign keys para ambas as tabelas
Cada repositório encapsula operações CRUD para seu modelo.
Localização: lib/data/repositories/player_repository.dart
Métodos principais:
get()- Obtém o jogador (cria se não existir)update(Player)- Atualiza dados do jogadoraddXP(int)- Adiciona XP e recalcula níveladdRewardPoints(int)- Adiciona pontos de recompensa
Lógica de XP:
- Usa
XPCalculatorpara calcular nível baseado no XP total - Atualiza automaticamente o nível quando necessário
Localização: lib/data/repositories/mission_repository.dart
Métodos principais:
insert(Mission)- Cria nova missãogetAll()- Lista todas as missõesgetByStatus(String)- Filtra por statusgetById(int)- Obtém missão específicagetWithSkills(int)- Obtém missão com skills relacionadasupdate(Mission)- Atualiza missãocomplete(int)- Marca como completadelete(int)- Remove missãolinkSkills(int, List<int>)- Vincula skills à missão
Localização: lib/data/repositories/skill_repository.dart
Métodos principais:
insert(Skill)- Cria nova skillgetAll()- Lista skills ativasgetById(int)- Obtém skill específicaupdate(Skill)- Atualiza skilldelete(int)- Soft delete (is_active = 0)addXP(int, int)- Adiciona XP à skill e recalcula nível
Providers gerenciam o estado da aplicação e fazem a ponte entre UI e dados.
Localização: lib/providers/player_provider.dart
Estado:
_player- Dados do jogador atual_isLoading- Estado de carregamento
Getters úteis:
player- Jogador atualtotalXP- XP totallevel- Nível atualxpForNextLevel- XP necessário para próximo nívelxpInCurrentLevel- XP no nível atualprogressToNextLevel- Progresso (0.0 a 1.0)
Métodos:
loadPlayer()- Carrega jogador do bancoupdatePlayer(Player)- Atualiza e recarrega
Localização: lib/providers/mission_provider.dart
Estado:
_missions- Lista de missões_isLoading- Estado de carregamento_error- Mensagem de erro
Getters:
missions- Todas as missõesactiveMissions- Missões ativascompletedMissions- Missões completas
Métodos:
loadMissions()- Carrega todas as missõesaddMission(Mission)- Adiciona nova missãocompleteMission(int)- Completa missão e distribui recompensasupdateMission(Mission)- Atualiza missãodeleteMission(int)- Remove missão
Lógica de Completar Missão:
- Marca missão como completa
- Adiciona XP ao jogador
- Adiciona reward points ao jogador
- Distribui XP proporcionalmente às skills relacionadas
Localização: lib/providers/skill_provider.dart
Estado:
_skills- Lista de skills_isLoading- Estado de carregamento
Métodos:
loadSkills()- Carrega todas as skillsaddSkill(Skill)- Adiciona nova skillupdateSkill(Skill)- Atualiza skilldeleteSkill(int)- Remove skill
Localização: lib/ui/screens/main_screen.dart
Responsabilidades:
- Tela principal com navegação lateral (Drawer)
- Gerencia qual tela está ativa via
IndexedStack - Mostra
PlayerStatsHeaderem todas as telas (exceto Settings/Help) - FloatingActionButton para criar missões (apenas na tela de Missions)
Navegação:
- Drawer lateral com 10 opções
- Índices: 0=Missions, 1=Map, 2=Rewards, 3=Inventory, 4=Skills, 5=Statistics, 6=Profile, 7=Shop, 8=Settings, 9=Help
Localização: lib/ui/screens/missions/missions_list_screen.dart
Funcionalidades:
- Lista todas as missões
- Filtros: Todas, Ativas, Completas, Arquivadas
- RefreshIndicator para atualizar
- Usa
MissionCardpara exibir cada missão
Localização: lib/ui/screens/missions/mission_editor_screen.dart
Funcionalidades:
- Formulário completo para criar/editar missões
- Sliders para Difficulty, Urgency, Fear
- Seleção de Skills, Parent Mission, Date Due, Repetition
- Picker circular para Reward Points
Localização: lib/ui/widgets/player/player_stats_header.dart
Componentes:
- Avatar do jogador
- Nome e título
- Level grande (amarelo/dourado)
- Reward Points
- Barra de XP (azul)
- Barra de HP/Energy (vermelha)
- TabBar com filtros: PLAN, ALL, NEXT, OVERDUE, TODAY, TOMORROW
Localização: lib/ui/widgets/mission/mission_card.dart
Layout:
- Faixa de prioridade colorida (esquerda)
- Ícone da missão (SVG/emoji/FontAwesome)
- Título e descrição
- Indicador de recorrência
- Reward points
- Barra de progresso (opcional)
- Botão "+" para subtasks
Localização: lib/ui/widgets/common/app_drawer.dart
Funcionalidades:
- Menu lateral com navegação
- Ícones SVG dos assets
- Destaque visual para item selecionado
- Header com logo do jogo
Localização: lib/core/theme/app_theme.dart
background: #212121 // Fundo escuro principal
surface: #303030 // Superfície de cards
primary: #03A9F4 // Azul principal (destaques)
accentRed: #F44336 // Vermelho (HP/Urgência)
accentAmber: #FFC107 // Amarelo (Level/XP)
textPrimary: #F5F5F5 // Texto principal
textSecondary: #BDBDBD // Texto secundário
border: #424242 // Bordas- Dark Mode por padrão
- Material 3 habilitado
- Visual Density: Compact (menos padding)
- Fonte: Roboto (via Google Fonts)
- Cards: Bordas arredondadas (12px), borda sutil
- Inputs: Fundo escuro, borda azul no foco
// Acessar cores
AppTheme.primary
AppTheme.accentRed
AppTheme.textPrimary
// Acessar tema
Theme.of(context).colorScheme.primary
Theme.of(context).cardThemeUser clica FAB
↓
MissionEditorScreen abre
↓
User preenche formulário
↓
User clica "Save"
↓
MissionProvider.addMission()
↓
MissionRepository.insert()
↓
Skills vinculadas (se houver)
↓
MissionProvider.loadMissions()
↓
UI atualiza automaticamente
User toca em MissionCard
↓
MissionProvider.completeMission()
↓
MissionRepository.complete()
↓
PlayerRepository.addXP()
↓
PlayerRepository.addRewardPoints()
↓
SkillRepository.addXP() (para cada skill)
↓
Providers notificam listeners
↓
UI atualiza (XP, Level, Skills)
main() executa
↓
MyApp cria Providers
↓
Providers chamam loadPlayer/loadMissions/loadSkills
↓
Repositories consultam banco
↓
Dados são populados nos Providers
↓
UI renderiza com dados
- Flutter SDK (gerenciado via FVM)
- FVM (Flutter Version Management)
- Dependências do sistema (para desktop)
-
Clone o repositório (se aplicável)
-
Instale as dependências:
fvm flutter pub get
-
Execute o app:
# Linux fvm flutter run -d linux # Android fvm flutter run -d android # iOS fvm flutter run -d ios
O banco SQLite é criado automaticamente na primeira execução:
- Mobile:
getDatabasesPath()retorna diretório do app - Desktop:
sqflite_common_ffié usado automaticamente
O DatabaseHelper._onCreate() cria:
- Um jogador padrão (id=1, name='Player')
- 5 skills padrão: Inteligência, Força, Saúde, Social, Criatividade
Localização: lib/core/utils/xp_calculator.dart
Fórmula de XP por Nível:
XP necessário para nível N = N * 100
Exemplos:
- Nível 1 → 2: 100 XP
- Nível 2 → 3: 200 XP
- Nível 3 → 4: 300 XP
- Total para nível 5: 100 + 200 + 300 + 400 = 1000 XP
Métodos:
xpForNextLevel(int level)- XP necessário para próximo nívelcalculateLevel(int totalXP)- Calcula nível baseado no XP totalxpInCurrentLevel(int totalXP, int level)- XP no nível atual
Skills usam fórmula similar, mas com cálculo independente:
- Cada skill tem seu próprio
currentXPelevel - XP é distribuído proporcionalmente quando missões são completadas
- Provider é usado para gerenciamento de estado
- Sempre use
Consumeroucontext.read<T>()para acessar providers - Providers notificam listeners automaticamente quando dados mudam
- Singleton Pattern para
DatabaseHelper - Foreign Keys habilitadas via
PRAGMA foreign_keys = ON - Soft Delete para Skills (
is_active = 0)
- SVG Icons em
assets/game-icons.net.svg/ - Use
SvgPicture.asset()para carregar - Sempre forneça
placeholderBuildereerrorBuilder
- Drawer para navegação principal
- IndexedStack para manter estado das telas
- Navigator.push() para telas modais (ex: MissionEditorScreen)
- Use
ListView.builderpara listas grandes IndexedStackmantém todas as telas em memória (trade-off)- Considere lazy loading para grandes volumes de dados
-
Filtros de Missões
- Implementar lógica de tabs no
PlayerStatsHeader(PLAN, ALL, NEXT, OVERDUE, TODAY)
- Implementar lógica de tabs no
-
Seleção de Skills
- Completar seletor de skills no
MissionEditorScreen
- Completar seletor de skills no
-
Seleção de Parent Mission
- Implementar dropdown para missões pai
-
Icon Picker
- Integrar
IconPickerDialogcom assets SVG
- Integrar
-
Telas Placeholder
- Implementar telas reais para: Map, Rewards, Inventory, Statistics, Profile, Shop
-
Sistema de Recompensas
- Tela de Rewards com itens compráveis
- Shop para gastar reward points
-
Gráfico Radar
- Completar implementação do RadarChart em
SkillsView
- Completar implementação do RadarChart em
-
Sistema de Energia
- Lógica de regeneração de energia
- Timer no
PlayerStatsHeader
-
Missões Recorrentes
- Lógica de recriação automática
- Streak tracking
-
Subtasks
- Implementar criação e visualização de subtasks
-
Testes
- Unit tests para repositories
- Widget tests para componentes principais
-
Tratamento de Erros
- SnackBars para erros do usuário
- Logging estruturado
-
Validações
- Validação de formulários mais robusta
- Mensagens de erro claras
-
Otimizações
- Cache de dados
- Debounce em buscas
- Game Icons - Ícones SVG usados no projeto
- Crie o arquivo em
lib/ui/screens/ - Adicione à lista
_pagesnoMainScreen - Adicione o título em
_titleForIndex() - Adicione item no
AppDrawer(se necessário)
- Adicione o campo no modelo (ex:
Mission) - Atualize
toMap()efromMap() - Atualize
copyWith() - Adicione coluna no
DatabaseHelper._onCreate() - Crie migration em
_onUpgrade()(se necessário)
- Crie classe estendendo
ChangeNotifier - Adicione estado privado
- Adicione getters públicos
- Adicione métodos que chamam
notifyListeners() - Registre no
MultiProvideremmain.dart
Este guia cobre os aspectos principais do projeto LifeRPG. Para dúvidas específicas, consulte o código-fonte ou adicione documentação inline conforme necessário.
Boa sorte no desenvolvimento! 🚀