PlayerGames

Hub central do ecossistema de gamificação PlayerGames para o Moodle — documentação completa.

English | Português

View on GitHub Download .zip

Moodle Plugin CI Moodle License Status PlayerGames Ecosystem Core Component

⚠️ Este plugin está em desenvolvimento ativo. Ainda não foi publicado no Diretório de Plugins do Moodle. Algumas funcionalidades descritas abaixo são planejadas e ainda não estão implementadas.

O PlayerGames (local_playergames) é o hub central do ecossistema de gamificação PlayerGames para o Moodle. Serve a quatro propósitos principais:

  1. Dashboard do Ecossistema — visão geral visual de todos os plugins Player instalados no site, com status, dependências e links de acesso rápido.
  2. Player Hub — plataforma de gamificação site-wide para estudantes e/ou outros usuários do Moodle (professores, managers, administradores), com XP, níveis, temporadas, missões, conquistas, avatares e streak diário. O administrador configura quais grupos participam.
  3. Minijogos Diários — minijogos de reforço de conceitos e um check-in diário, alimentados por cartuchos de conteúdo (JSON, opcionalmente gerados por IA via o plugin companheiro local_aihub) — funcionando como um loop de aprendizado estilo Duolingo.
  4. Bloco Companheiro de Sidebar — o block_playergames espelha o perfil do jogador (avatar, nível, XP, streak, jogos do dia, ranking) na página inicial do site e no Painel.

Use a barra lateral para ir a qualquer seção desta página.

Código-fonte: github.com/jeanlucio/moodle-local_playergames


✨ Funcionalidades

✅ Implementado

⏳ Em Desenvolvimento / Planejado

🤖 Cadeia de Provedores de IA

O armazenamento de chaves e o transporte com os provedores (Gemini, Groq, DeepSeek, compatível com OpenAI) vivem num plugin companheiro dedicado, o local_aihub. O PlayerGames em si só monta o prompt de geração do cartucho (tópico, idioma, quantidade de conceitos, dificuldade, categorias) e interpreta a resposta JSON da IA de volta em conceitos, então fica livre de gerenciamento de chaves e ainda oferece suporte à geração de cartuchos assistida por IA onde quer que o Hub esteja instalado.

Ordem de resolução

Prioridade Origem Observações
1 local_aihub Tentado primeiro quando instalado. Resolve chaves pessoais e depois chaves de site, entre os provedores Gemini / Groq / DeepSeek / compatível-com-OpenAI.
2 Moodle core_ai Fallback institucional, usado apenas se o Hub não estiver instalado ou não retornar uma fonte utilizável. Usa os provedores que o admin configurou em Administração do site → IA → Provedores de IA.

Uma falha real de provedor (ex.: uma chave inválida cadastrada no Hub) é preservada e exibida ao usuário — nunca é mascarada silenciosamente como “nenhuma fonte de IA disponível”.

Instalar o local_aihub é opcional. Sem ele, a geração de cartuchos via IA ainda funciona se o site tiver o core_ai configurado; o PlayerGames só perde a opção de chave pessoal (BYOK — cada professor trazendo sua própria chave Gemini/Groq/DeepSeek/OpenAI) que o Hub oferece.

API de integração para outros plugins

O cartridge\ai_generator expõe uma API pequena e estável que outros plugins do ecossistema podem chamar diretamente:

use local_playergames\cartridge\ai_generator;

$gen = new ai_generator();
if ($gen->has_key()) {
    // Prompt livre, roteado pela mesma cadeia usada na geração de cartuchos.
    $text = $gen->generate_text('Instrução de sistema opcional', 'Seu prompt aqui');
}

Toda geração de IA disparada pelo PlayerGames é marcada no próprio log de uso do Hub com o componente (local_playergames) e uma descrição curta do que foi gerado (ex.: o tópico do cartucho), então administradores do site conseguem ver o uso de IA por plugin consumidor a partir do relatório de admin do Hub.

📦 Formato do Cartucho

Os cartuchos de conteúdo são arquivos JSON que alimentam todos os minijogos. O mesmo pacote serve ao PlayerQuiz, PlayerGuess, PlayerFill e PlayerBattle:

{
  "name": "Fundamentos de Gamificação",
  "version": "1.0",
  "language": "pt_BR",
  "concepts": [
    {
      "term": "gamificação",
      "definition": "Uso de elementos de jogos em contextos não-lúdicos",
      "category": "fundamentos",
      "difficulty": 2
    }
  ]
}

🧠 Como o PlayerQuiz Funciona

O PlayerQuiz é o primeiro mini-jogo diário. Ele sorteia questões de múltipla escolha dos cartuchos ativos (e, opcionalmente, do Banco de Questões do Moodle) e as exibe uma de cada vez.

O fluxo da jogada

Como a jogada termina no primeiro acerto, o jogador raramente responde o pool inteiro — a maioria das questões da sessão é só um colchão que dá variedade e margem para errar antes de repetir.

Dois limites independentes (é aqui que muita gente se confunde)

Configuração Eixo Significado
Jogos por dia (xp_games_quiz) o dia Quantas jogadas valem XP por dia. Também define o teto diário de XP: XP por jogo × jogos por dia.
Questões por sessão (quiz_session_size) dentro de uma jogada Quantas questões são sorteadas para uma única jogada (o “baralho” daquela partida).

Exemplo — com XP por jogo = 25, jogos por dia = 3, questões por sessão = 20: o jogador pode concluir 3 jogadas hoje (teto de 75 XP), e cada jogada é montada a partir de um sorteio novo de 20 questões. Os dois números respondem perguntas diferentes: quantas partidas hoje vs qual o tamanho do baralho de cada partida.

Questões novas e repetições

Configurações do administrador

Administração do site → Plugins → Plugins locais → PlayerGames → Regras dos jogos

Configuração Padrão O que faz
Tempo por questão (segundos) 120 (2 min) Contagem regressiva por questão. Chegar a zero conta como erro e avança. 0 desativa o cronômetro.
Máximo de tentativas 0 (ilimitado) Erros (incluindo tempo esgotado) que encerram a jogada sem XP. 0 mantém o comportamento original — o jogo continua até o jogador acertar.
Cooldown ao falhar (minutos) 0 Quando uma jogada termina em falha, o quiz fica bloqueado por estes minutos. Persistido no servidor (recarregar a página não contorna). Só faz sentido junto com um limite de tentativas.
Questões por sessão 20 Tamanho do sorteio de cada jogada, escolhido em uma lista com teto (5–50).

Como cronômetro, tentativas e cooldown se encaixam

Por que o tamanho da sessão tem teto

Toda questão da sessão é renderizada no HTML da página de uma vez (o navegador apenas vai revelando uma a uma). Uma sessão muito grande formataria e enviaria centenas de questões que o jogador nunca verá — trabalho de servidor desperdiçado e página pesada. A lista com teto (máx. 50) mantém variedade de sobra sem esse custo. Sessões realmente grandes exigiriam outra arquitetura (carregar questões sob demanda), o que não é como o jogo funciona hoje.

🔡 Como o PlayerGuess Funciona

O PlayerGuess é um minijogo diário estilo Wordle: adivinhe um termo do cartucho ativo, letra por letra, dentro de um número limitado de tentativas.

O fluxo da jogada

Um conceito por dia, pipeline de atribuição compartilhado

Toda noite, uma tarefa agendada atribui um conceito aleatório ao PlayerGuess (e, de forma independente, ao PlayerQuiz) a partir dos cartuchos ativos no momento — o mesmo pipeline usado entre os minijogos diários. Especificamente para o PlayerGuess, apenas conceitos cujo termo:

são elegíveis. Esse filtro é aplicado de forma idêntica no momento da atribuição e novamente ao validar uma tentativa, então um termo que até se encaixa na faixa de comprimento mas contém, por exemplo, um hífen, nunca é atribuído a um dia de PlayerGuess.

Configurações do administrador

Administração do site → Plugins → Plugins locais → PlayerGames → Regras dos jogos

Configuração Padrão O que faz
Máximo de tentativas 6 Tentativas permitidas antes da rodada terminar em derrota e o termo ser revelado.
Comprimento mínimo do termo 4 Menor termo elegível para a atribuição diária.
Comprimento máximo do termo 8 Maior termo elegível para a atribuição diária.

Administração do site → Plugins → Plugins locais → PlayerGames → XP e recompensas

Configuração Padrão O que faz
XP por jogo do Guess 25 XP concedido numa rodada vencida.
Jogos de Guess por dia 1 Quantas vitórias por dia valem XP — atingido o limite, o jogo mostra “já jogou hoje”.

Estado da rodada e seus limites

A rodada em andamento (tentativas feitas até agora, se está finalizada, se foi vencida) fica guardada na sessão do usuário, não numa tabela de banco de dados. Ela reseta automaticamente se a rodada guardada não corresponder mais ao conceito atribuído hoje (um novo dia, ou um conceito reatribuído). Isso significa:

🦊 Avatares

O PlayerGames tem sua própria coleção de avatares emoji, desbloqueados permanentemente pelo maior nível que o jogador já alcançou — sem loja, sem upload de arquivo, apenas uma recompensa por faixa de nível.

Catálogo e faixas

O catálogo padrão tem 17 avatares emoji divididos em 4 faixas (5 na faixa 1, 4 em cada uma das faixas 2 a 4): 🤖 👾 🦊 🐱 🐶 (faixa 1), 🕵️ 🤺 🧚 🧜 (faixa 2), 🧝 🧙 🦸 🥷 (faixa 3), e 🧛 🦹 🐉 🦁 (faixa 4).

Regra de desbloqueio

Os desbloqueios são baseados no maior nível que o jogador já alcançou, para sempre — não no nível atual, e não restrito à temporada corrente. Toda vez que um jogador ganha XP suficiente para subir de nível, o PlayerGames registra o novo nível apenas se ele superar o melhor nível já guardado para aquele jogador; fechar uma temporada, que zera o XP de temporada, nunca tira um avatar já desbloqueado.

Limiares por faixa

Faixa Nível mínimo padrão
1 1
2 5
3 10
4 20

Admins podem alterar o nível mínimo de cada faixa independentemente (Administração do site → Plugins → Plugins locais → PlayerGames → Avatares).

Equipar e exibir

Um jogador pode equipar qualquer avatar já desbloqueado (ou desequipar, voltando à foto de perfil padrão do Moodle) num seletor agrupado por faixa — avatares bloqueados aparecem em tons de cinza junto com o nível exigido. O avatar equipado substitui a foto de perfil padrão no cartão de perfil do Player Hub e no widget do Bloco PlayerGames, e permanece sincronizado entre os dois, já que ambos leem e escrevem através do mesmo gerenciador de avatares.

📘 XP de Aprendizado

O XP de Aprendizado é um pool de XP separado e opcional que espelha o XP por curso ganho no block_playerhud de um estudante para dentro do PlayerGames, puramente para visibilidade entre cursos — nunca é somado ao XP de temporada e nunca afeta níveis, desbloqueios de avatar ou o ranking de temporada.

De onde vem

Quando o block_playerhud está instalado e um estudante ganha ou perde XP de curso, o PlayerGames escuta essa mudança e espelha a diferença no seu próprio total com janela de XP de aprendizado. Nada precisa ser configurado do lado do block_playerhud além de tê-lo instalado — a ponte é opcional e fica inerte se o block_playerhud não estiver presente.

A janela

O XP de Aprendizado não é um total vitalício: só conta o XP ganho dentro de uma janela móvel (padrão de 12 meses, configurável em meses; 0 significa ilimitado/vitalício). Os dados ficam guardados em blocos mensais, então a janela envelhece corretamente mês a mês, e uma tarefa agendada noturna recalcula o total com janela de cada usuário para corrigir qualquer desvio e descartar blocos que já saíram da janela.

Visibilidade

O XP de Aprendizado só é exibido quando ambas as condições são verdadeiras:

Diferente da maioria das outras funcionalidades voltadas ao estudante, a visibilidade não depende de o visualizador estar marcado como staff — um professor que também é um estudante genuíno ganhando XP do PlayerHUD em outro curso ainda vê o próprio XP de aprendizado.

Seu próprio ranking

O XP de Aprendizado tem seu próprio ranking opt-in separado — uma única lista top-50 (não dividida por staff/estudante como o ranking de temporada), controlada por seu próprio toggle de admin. Jogadores com XP com janela igual a zero são excluídos completamente em vez de ocupar uma posição, e cada jogador tem um toggle de opt-in independente do usado na visibilidade do ranking de temporada. A busca de posição para jogadores fora do top 50 segue a mesma regra de desempate do ranking de temporada (maior XP primeiro, depois quem chegou lá primeiro).

Onde aparece

Tanto a página do Player Hub quanto o widget de sidebar do Bloco PlayerGames leem do mesmo gerenciador e seguem as mesmas regras de visibilidade e ranking, então as duas telas estão sempre consistentes entre si.

🏆 Como o Ranking Funciona

O ranking de temporada é opt-in, dividido por grupo de participante, e mostra a um jogador sua própria posição mesmo fora do top 50 visível.

Opt-in e a lista top-50

Os jogadores escolhem se querem aparecer no ranking a partir do próprio perfil. A lista visível é o top 50 por XP de temporada, ordenada por XP decrescente → o momento em que atingiu esse XP crescente → id do usuário crescente — um desempate totalmente determinístico, então dois jogadores com o mesmo XP são ordenados por quem chegou lá primeiro.

Divisão staff / estudante

Os rankings são divididos em dois grupos: estudantes e staff (qualquer um com capacidade de edição de curso em pelo menos um curso, ou a flag de admin do site). Se um visualizador vê um grupo ou os dois depende do próprio papel e da configuração de participantes do site:

Sua própria posição, mesmo fora do top 50

Um jogador que optou por entrar no ranking mas não está no top 50 visível ainda vê sua posição exata — calculada com uma única consulta de contagem indexada usando a mesma regra de ordenação da lista visível, em vez de varrer o ranking inteiro.

Escopo

Esta página descreve o ranking de temporada (ligado ao XP de temporada e reiniciado quando uma temporada fecha). O XP de Aprendizado tem seu próprio ranking separado, único (não dividido por staff/estudante) e com seu próprio opt-in — veja aquela seção para detalhes.

🎓 Finalidade Educacional

O PlayerGames foi projetado para:

Indicado para:

🕹️ Ecossistema PlayerGames

O PlayerGames é o hub de um ecossistema mais amplo de gamificação. Juntos, esses plugins transformam o Moodle em uma experiência imersiva:

📦 Requisitos

Componente Versão
Moodle 4.5 – 5.2
PHP 8.1+

🛠️ Instalação e Configuração

⚠️ Este plugin ainda não está publicado no Diretório de Plugins do Moodle. Instale manualmente a partir deste repositório.

  1. Baixe o arquivo .zip ou clone este repositório.
  2. Extraia na pasta local/ do seu Moodle.
  3. Renomeie para playergames (se necessário). Caminho final: seu-moodle/local/playergames/
  4. Acesse Administração do site → Notificações para concluir a instalação.
  5. Vá em Administração do site → Plugins → Plugins locais → PlayerGames para configurar temporada, XP, avatares e regras dos jogos.
  6. Crie a primeira temporada na página Gerenciar Temporadas.
  7. Opcional: instale o local_aihub se quiser geração de cartuchos assistida por IA com chaves pessoais/de site — ver Cadeia de Provedores de IA.

📖 Como Usar

Para Administradores

  1. Instale o plugin e conclua o upgrade do Moodle.
  2. Opcionalmente instale o local_aihub se quiser geração de cartuchos assistida por IA com chaves pessoais/de site (ver Cadeia de Provedores de IA) — caso contrário, os cartuchos ainda podem ser criados manualmente ou gerados pelo core_ai do próprio Moodle.
  3. Crie a primeira temporada na página Gerenciar Temporadas, definindo nome, datas e as recompensas de XP por jogo e jogadas por dia.
  4. Opcionalmente ajuste a página Escada de Níveis — altere os limiares de XP e os títulos, restaure a escada padrão ou gere uma linear mais longa.
  5. Faça upload ou gere um cartucho de conteúdo na página Cartuchos.
  6. Acompanhe o impacto da gamificação no Engajômetro.

Para Professores

  1. Se o local_aihub estiver instalado, acesse a página Minhas Chaves de IA dele para configurar uma chave pessoal (opcional — as chaves de site funcionam se o admin as configurou).
  2. Use o hub PlayerGames ou qualquer plugin Player — os recursos de IA usarão automaticamente a cadeia de chaves configurada.

Para Estudantes

  1. Acesse o Player Hub para ver seu XP, nível, posição no ranking, streak e missões do dia.
  2. Jogue os minijogos diários para ganhar XP.
  3. Marque ou desmarque “Aparecer no ranking” no seu perfil para controlar sua visibilidade.

🧪 Testes Automatizados

O PlayerGames acompanha uma suíte PHPUnit que cobre o motor de gamificação, o pipeline de cartuchos, as tarefas agendadas, a privacidade e os eventos. Cada push no CI roda a matriz completa (Moodle 4.5 → 5.2, PostgreSQL e MariaDB).

PHPUnit — Testes de Unidade e Integração

Arquivo de teste Casos O que é coberto
cartridge/importer_test.php 10 Importação de conceito e quiz; inferência de tipo; clamp de dificuldade; dedup de categoria; erros de schema
cartridge/exporter_test.php 5 Estrutura do export concept/quiz e round-trip completo import→export incluindo metadados de raiz
cartridge/category_manager_test.php 7 CRUD de categoria, sortorder incremental, ensure idempotente, checagem de posse, conceito null ao excluir
cartridge/quiz_generator_test.php 10 Parsing da resposta de quiz, defaults de categoria/dificuldade, persistência em save_standalone
cartridge/ai_generator_test.php 5 Parser de conceitos: JSON encapsulado/puro/com fences, JSON inválido e ausência de conceitos; delegação à fachada do AI Hub com fallback para core_ai
hub/xp_manager_test.php 17 Limiares de nível, cap por jogo, recompensa de missão sem cap, evento de subida de nível, posição/desempate no ranking de temporada
hub/avatar_manager_test.php 10 Seed do catálogo padrão, limiares de faixa, rastreio do melhor nível vitalício, regras de desbloqueio/equipar, rejeição de equipar avatar bloqueado
hub/learning_xp_manager_test.php 22 Blocos mensais com janela, controle de visibilidade (independente do status de staff), opt-in e posição no ranking, correção no recálculo
hub/daily_play_manager_test.php 3 Múltiplas jogadas dividem o XP igualmente; jogada além da cota diária rejeitada; última jogada aparada no cap exato
hub/level_manager_test.php 8 Seed da escada, busca de XP/título, save com renumeração + piso zero, restaurar padrão, geração linear e limites
hub/checkin_manager_test.php 11 Insert do check-in + concessão de XP, idempotência, cap de temporada, avanço opcional de streak, elegibilidade de participante
hub/served_questions_test.php 3 Conjunto “já exibido” do dia agrupado por fonte, escopo idempotente, itens inválidos ignorados
hub/streak_manager_test.php 12 Início/continuação/reset de streak, consumo de freeze, processamento de quebra
hub/season_manager_test.php 8 Ciclo da temporada, resolução ativa/próxima, ativação exclusiva, snapshot, create_next
hub/mission_manager_test.php 7 Sync de missão, progresso/conclusão com recompensa de XP, resets diário e de check-in perdido
hub/achievement_manager_test.php 6 Sync de conquista, concessão (primeiro jogo/nível/todos os jogos no dia), idempotência
hub/title_manager_test.php 2 Clamp da chave nível→título e tradução
observer_test.php 5 game_completed aciona streak/missão/conquista; registra streak mesmo sem temporada; espelha mudanças de XP do block_playerhud no XP de Aprendizado
games/quiz_loader_test.php 12 Fonte de cartucho: filtro de completude, tamanho da sessão, só-ativos, filtro por id, metadados, sorteio aleatório, exclusão de questões já vistas e reuso do pool
games/quiz_settings_test.php 8 Configuração de cronômetro, máximo de tentativas e cooldown, e como interagem
games/guess_manager_test.php 7 Resolução do conceito diário, normalização do termo, feedback de letras estilo Wordle (incluindo letras duplicadas), validação da tentativa
games/season_game_config_test.php 7 Helpers de fonte; busca do registro habilitado; listagem por temporada; seed de defaults e preservação
external/set_avatar_test.php 3 Equipar/desequipar via o endpoint AJAX, rejeitando um avatar bloqueado
external/set_ranking_visibility_test.php 2 Toggle de opt-in/opt-out do ranking de temporada
external/set_learning_ranking_visibility_test.php 2 Toggle de opt-in/opt-out do ranking de XP de Aprendizado
task/assign_daily_games_test.php 4 Atribuição de conceito por jogo, idempotência, caso sem cartucho, filtro de elegibilidade do PlayerGuess
task/reset_daily_missions_test.php 1 Orquestração do reset diário de missões + quebra de streak
task/close_expired_seasons_test.php 2 Fecha temporada expirada; auto-renovação cria e ativa a próxima
task/purge_old_scores_test.php 2 Purga pela janela de retenção; no-op dentro da janela
task/recompute_learning_xp_test.php 2 Recálculo noturno da janela descarta blocos vencidos e corrige desvio de cache
privacy/provider_test.php 8 Metadata, contextos, userlist, export e as três rotas de deleção
local/access_test.php 13 Detecção de staff (admin de site, capacidade de edição de curso), resolução em lote de ids de staff, regras de visibilidade do hub
local/engagement_report_test.php 4 Métricas vazias, contagem de cursos, detecção de curso Player, divisão por escopo
ecosystem/plugin_registry_test.php 2 Estrutura do catálogo e componentes únicos
ecosystem/plugin_status_test.php 1 Status de instalação por componente; hub reportado como instalado
event/events_test.php 1 Os nove eventos disparam, são capturados e renderizam descrição
Total 232  
vendor/bin/phpunit --testsuite local_playergames

Behat — Testes de Aceitação

Arquivo de feature Cenários O que é coberto
play_quiz.feature 2 O fluxo de jogada do PlayerQuiz de ponta a ponta
php admin/tool/behat/cli/init.php
vendor/bin/behat --tags=@local_playergames --profile=chrome

🔎 Divulgação de Serviço de Terceiros

O PlayerGames inclui geração de cartuchos assistida por IA, de forma opcional. Isso é totalmente opcional — todo o conteúdo pode ser criado manualmente.

Arquitetura

A geração via IA é roteada pelo plugin companheiro local_aihub quando instalado, que é o dono do armazenamento de chaves e do transporte com o provedor; se o Hub não estiver instalado, o PlayerGames recorre ao subsistema core_ai do próprio Moodle, usando os provedores que o administrador do site configurou lá.

Provedores suportados (via local_aihub)

Esses serviços seguem seus próprios termos de uso e políticas de privacidade. A divulgação completa com os IDs exatos de modelo e destinos de dados está documentada na própria Divulgação de Serviço de Terceiros do local_aihub.

Transmissão de dados

Quando a geração via IA é usada, o prompt montado pelo PlayerGames (tópico, idioma, dificuldade, categorias e qualquer texto de referência opcional fornecido pelo professor) é passado para qualquer que seja a fonte que resolveu a requisição (o Hub ou o core_ai) para processamento. O PlayerGames:

Nenhuma comunicação externa ocorre sem ativação explícita de um recurso de IA.

Custo

Nenhum é exigido pelo próprio PlayerGames. Se o local_aihub estiver instalado, qualquer custo é o que o provedor cobrar através das chaves BYOK desse plugin; sem ele, o PlayerGames recorre ao core_ai do Moodle, que pode ser gratuito se o administrador do site tiver configurado um provedor institucional sem custo.

Credenciais de Demonstração

Não aplicável — nenhuma credencial é exigida para instalar ou usar o PlayerGames; a geração de cartuchos assistida por IA é totalmente opcional.

📄 Licença

Este projeto é licenciado sob a GNU General Public License v3 (GPLv3).

Copyright: 2026 Jean Lúcio

Suporte

Encontrou um bug ou tem alguma dúvida? Abra uma issue no rastreador de issues.

Mantenedor

Mantido por Jean Lúcio.