O PlayerWords é uma atividade de adivinhação de palavras para o Moodle. O estudante adivinha uma palavra oculta letra por letra dentro de um número configurável de tentativas, recebendo feedback visual em cores e símbolos a cada chute.
👈 Use a barra lateral para pular direto a qualquer seção desta página.
✨ Funcionalidades
- 🟩 Jogo de adivinhação de palavras: Feedback por letra com código de cores + símbolos (posição correta, posição errada, ausente). Cada tentativa é uma linha de caixas individuais por letra — clique em qualquer uma para corrigir uma letra específica sem reescrever a palavra inteira, ou mova entre as caixas com as setas esquerda/direita do teclado, a mesma convenção de campos de código de verificação (2FA) — e a digitação pelo teclado físico funciona mesmo antes de clicar numa caixa.
- 📖 Integração com Glossário: Importa conceitos de um ou todos os glossários do curso como pool de palavras, usando as definições como dicas.
- ✂️ Divisão de conceitos com várias palavras (opcional, desligado por padrão): Um conceito do glossário com várias palavras (ex.: “Sistema Operacional”) pode ser dividido em candidatas separadas de uma palavra só. Desligado por padrão para favorecer a qualidade das dicas — quando desativado, esse conceito simplesmente não entra no pool, em vez de gerar palavras isoladas que nem sempre fazem sentido sozinhas para adivinhar.
- 🚧 Stopwords configuráveis: Uma lista de palavras separadas por vírgula, por atividade (ex.: “de, da, e”), para ignorar ao dividir um conceito de glossário com várias palavras em candidatas — assim um conceito como “Reino dos Países Baixos” ainda gera o termo relevante em vez de sortear “dos” como palavra isolada. Só relevante quando a divisão de conceitos acima está ativada.
- 🤖 Geração de palavras por IA (Opcional): Gera candidatas a palavra e dica para um tópico livre via Central de IA (
local_aihub) ou fallback para ocore_aido Moodle. A resposta é tratada como entrada não confiável — só termos de um único token, puramente alfabéticos e dentro do comprimento configurado são salvos, e entram no pool pendentes de aprovação do professor. - ✍️ Pool de palavras manual: O professor pode adicionar, editar, aprovar e excluir palavras diretamente na página de gerenciamento.
- 🔀 Modos de palavra: Palavra aleatória por rodada (padrão) ou sequência compartilhada — todos os estudantes recebem as mesmas palavras na mesma ordem.
- 🚧 Restringir palpites ao banco de palavras (opcional): Quando ativado, um palpite só é aceito se corresponder a uma das palavras já aprovadas no banco da atividade; qualquer outra combinação de letras do tamanho certo é rejeitada sem consumir uma tentativa. Desativado por padrão — qualquer combinação de letras do tamanho certo é aceita, seja palavra real ou não. Trava assim que a atividade já tem uma nota real registrada, junto com as demais configurações que afetam a pontuação.
- 🎲 Rotação de palavras: No modo aleatório, a mesma palavra nunca se repete na rodada seguinte para um estudante, a menos que seja a única palavra restante no pool.
- 🚫 Prevenção de duplicatas: O mesmo texto de palavra só pode existir uma vez no pool da atividade, não importa qual fonte a adicionou — uma palavra manual bloqueia uma importação do glossário que colida com ela (e vice-versa), então o sorteio nunca fica enviesado por uma palavra duplicada sem querer.
- 🔤 Validação de palavra manual: Uma palavra adicionada ou editada manualmente precisa conter só letras; o formulário rejeita números, espaços e caracteres especiais na hora, em vez de aceitar silenciosamente uma palavra que o jogo nunca conseguiria sortear de verdade.
- 🧩 Aviso de conceito fragmentado: Um conceito de glossário com várias palavras (ex.: “Segunda Guerra Mundial”) dividido em várias entradas de palavra única é sinalizado na tabela de gerenciamento de palavras, já que cada palavra irmã ainda carrega a definição inteira do conceito original como dica.
- 🔍 Contagem ao vivo de palavras elegíveis: O formulário de configurações mostra, ao vivo via AJAX, quantas palavras caem dentro do intervalo de comprimento configurado — contra o banco real ao editar uma atividade já existente, ou uma prévia do conteúdo do glossário selecionado ao criar uma atividade nova — então o professor nunca publica um intervalo que esvazia o banco silenciosamente.
- ⚠️ Aviso de palavras inativas: A tela do jogo avisa quem gerencia a atividade, pelo nome, quais palavras aprovadas estão atualmente fora de jogo — fora do intervalo de comprimento configurado, ou com caractere que o jogo não consegue usar — junto com uma contagem permanente de palavras ativas. Um estudante nunca vê isso.
- 🎯 Rastreio de vezes sorteada: A tabela de gerenciamento de palavras mostra quantas vezes cada palavra já foi sorteada numa rodada, contado ao vivo a partir do histórico de tentativas — sem nenhum passo de recálculo.
- 💡 Dica oculta (com opção de desativar): A dica é escondida por padrão; o estudante precisa clicar em “Revelar dica” (com custo opcional em itens via PlayerHUD). O professor pode desativar completamente o mecanismo de revelar dica para a atividade — o botão de revelar dica então nunca aparece, mesmo para palavras que têm uma dica configurada.
- 🏳️ Desistir: O estudante pode abandonar a rodada a qualquer momento — a palavra correta é revelada imediatamente.
- ⏱️ Tempo de recarga configurável: Intervalo mínimo entre rodadas (minutos, horas ou dias), sempre recalculado a partir da configuração atual da atividade — uma mudança do professor vale imediatamente, mesmo para quem já está em cooldown.
- 🔢 Limite de rodadas: O professor pode limitar o total de rodadas por estudante (1–10 ou ilimitado). O estudante vê um contador de rodadas jogadas (ex.: “3 / 10” ou “3 / ∞”) no lobby e após cada rodada.
- 🛡️ Integridade do limite de rodadas: Uma rodada abandonada no meio (aba fechada, sessão perdida) continua contando para o limite — reservada assim que começa, não só quando termina, então nunca dá um reroll de graça.
- 🔡 Correspondência sem acentos: Acentuação é sempre ignorada ao comparar chute e palavra-alvo.
- ⌨️ Seleção de acento no teclado virtual: Segurar uma tecla com variantes acentuadas (a maioria das vogais, além de C, N e S) no teclado virtual abre um popup com essas variantes, igual ao padrão de teclado de celular — arrastar o dedo escolhe a variante, soltar confirma. Cobre diacríticos de português, espanhol, francês, italiano e alemão (incluindo Ç, Ñ e ß); alfabetos fora desse conjunto (nórdicas, eslavas, turco, islandês…) são uma possível adição futura, ainda não cobertos. Puramente estético: a correspondência do chute continua sempre insensível a acentos.
- ⌨️ Teclado reflete o histórico de tentativas: As teclas do teclado virtual ficam coloridas com o melhor estado (certo, presente ou ausente) já visto pra aquela letra em qualquer tentativa da rodada. “Ç” e “C” sempre ficam sincronizadas entre si, já que contam como a mesma letra pro jogo.
- ✅ Revelação com ortografia real: Ao vencer, perder ou desistir da rodada, a palavra é exibida com sua acentuação verdadeira do banco de palavras, mesmo que o chute vencedor tenha sido digitado sem acento.
- 📊 Métodos de avaliação: Maior nota, média, primeira tentativa, última tentativa ou média sobre todas as rodadas exigidas.
- ⚖️ Modo de pontuação configurável: Escolha Binária (tudo ou nada) ou Linear (proporcional às tentativas poupadas) de forma independente para a nota e para o ranking — veja Nota e Ranking. Trava assim que a atividade registra uma nota real, garantindo que toda rodada seja pontuada sob as mesmas regras.
- 🧮 Transparência de avaliação: O estudante vê o método de avaliação ativo antes de jogar e sua nota atual computada após cada rodada, do mesmo jeito que o Quiz do Moodle comunica seu método de avaliação.
- 📋 Integração com o livro de notas: Notas gravadas automaticamente ao final de cada rodada.
- ✅ Regra de conclusão personalizada: Número mínimo de tentativas realizadas, avaliada e aplicada imediatamente após cada rodada.
- 🔄 Suporte a “Redefinir curso”: Limpa as tentativas dos estudantes e reseta as notas da atividade, restrito ao curso alvo.
- 🏆 Ranking Top 5: Classificação por atividade, limitada de propósito aos 5 primeiros — nunca um ranking público da turma inteira — com uma linha extra (“outsider”) pra um estudante mais abaixo ver sua posição real. Respeita
SEPARATEGROUPS. - 📋 Registro de tentativas: O estudante pode conferir cada rodada já concluída — palavra, tentativas usadas, tempo, nota e data — além da sua nota atual computada, a qualquer momento pelo toolbar. Quem pode gerenciar a atividade também vê essa mesma página (incluindo as próprias tentativas, se houver), além de um relatório separado com todos os estudantes, numa tabela paginada, ordenável e filtrável por estudante — veja Nota e Ranking.
- 🗑️ Exclusão de tentativas: No relatório com todos os estudantes, quem gerencia a atividade pode excluir tentativas individualmente ou em lote (com seleção de página inteira). A nota do estudante afetado é recalculada automaticamente, inclusive destravando configurações da atividade que ficam travadas assim que existe uma nota real registrada, caso todas as tentativas dele sejam removidas. Itens do PlayerHUD já concedidos não são revertidos automaticamente — um aviso na própria página informa isso quando a atividade concede itens por vitória.
- ❓ Ajuda no jogo: Uma página de ajuda dedicada explica as cores do feedback das letras, tentativas, dicas, temporizador e o método de avaliação da atividade.
- 👋 Acolhimento na primeira visita: O modal “Como jogar” abre sozinho na primeiríssima vez que um usuário visita qualquer atividade PlayerWords no site — uma única vez, para sempre, valendo para o site inteiro em vez de por curso ou por atividade — e nunca mais se repete depois disso; o ícone de ajuda no toolbar sempre reabre sob demanda.
- ♿ Acessibilidade: Contraste WCAG AA em todos os estados da grade; indicadores não visuais (✓ correto, ~ presente); cada célula tem seu próprio
aria-label, incluindo a posição enquanto ainda vazia; região viva anuncia mudanças de estado para leitor de tela. - ⚡ Powered por AJAX: Toda transição de rodada (chute, dica, desistência, timeout, iniciar, nova rodada) acontece sem recarregar a página.
- 🔔 Feedback por toast: Resultados do fluxo da rodada (vitória, derrota, saldo insuficiente no PlayerHUD) aparecem como notificações toast breves e que se fecham sozinhas, em vez de diálogos bloqueantes, mantendo o estudante na rodada.
- 🎮 Integração com PlayerHUD (Opcional): Exige itens do inventário para iniciar uma rodada ou revelar a dica, com consumo atômico em ordem FIFO. O saldo atual do estudante em relação à quantidade exigida é sempre mostrado antes da ação, e o botão fica desabilitado — não só rejeitado depois do clique — quando falta item; um custo que aponta pra um item excluído ou de outro curso é dispensado em vez de travar o estudante. Também pode conceder um item a cada rodada vencida; seguindo a mesma regra antifarm do próprio PlayerHUD, nenhum XP é concedido por esse item enquanto a atividade permitir rodadas ilimitadas — o item continua sendo entregue, só sem XP — e o XP potencial dessa concessão é refletido no “Total XP no jogo” do próprio PlayerHUD.
- 🛡️ Integração segura entre cursos: Toda referência a item do PlayerHUD é validada contra a instância do bloco do próprio curso, nunca um item obsoleto ou de outro curso — mesmo depois de backup/restauração ou duplicação de curso. As configurações preservam um item desabilitado ou excluído como uma opção claramente rotulada, em vez de zerar o campo silenciosamente.
- 🔔 Aviso de dependência do PlayerHUD: Quando o PlayerHUD está instalado no site mas ainda não foi adicionado ao curso atual, o formulário de configurações explica que a integração vai aparecer assim que o bloco for adicionado. Quando o plugin block_playerhud não está instalado em lugar nenhum do site, o administrador vê um aviso equivalente na própria página de configurações do plugin — mesmo espírito da divulgação que
filter_playerhudeavailability_playerhudjá fazem, sem tornar o PlayerHUD uma exigência obrigatória de instalação. - 📦 Backup & Restauração: Suporte completo ao backup Moodle 2, incluindo a ação “Duplicar atividade”, pool de palavras, tentativas, remapeamento de ids de usuário/glossário, e remapeamento seguro de itens do PlayerHUD (descartado, em vez de mantido apontando pro item de outro curso, quando não faz parte da mesma restauração).
- 🔐 Privacy API: Compatível com LGPD/GDPR — exportação e exclusão completas de dados pessoais armazenados.
🎓 Finalidade Educacional
O PlayerWords foi projetado para:
- Reforçar o aprendizado de conceitos trabalhados no curso ou disciplina
- Fomentar o aprendizado lúdico e baseado em jogos
- Simplificar e tornar mais intuitivos os processos de aprendizagem e avaliação
- Colaborar para o atingimento de objetivos educacionais em cursos e disciplinas
- Fomentar metodologias ativas como a utilização de games na educação e a gamificação
- Apoiar a prática de recuperação — o estudante precisa lembrar o conceito antes de ver qualquer resposta, uma das técnicas com maior evidência de eficácia para retenção de longo prazo
- Estimular a prática espaçada — o tempo de recarga configurável entre rodadas faz o estudante retornar ao conteúdo em sessões distintas, alinhando-se aos princípios da repetição espaçada
Indicado para:
- Qualquer curso que trabalhe com conceitos expressos em palavras ou termos
- Cursos gamificados com o ecossistema PlayerGames
- Avaliação formativa e reforço de autoestudo
- Estratégias de reforço de engajamento
🕹️ Ecossistema PlayerGames
O PlayerWords faz parte do ecossistema de gamificação PlayerGames para Moodle. Sua principal integração direta é com o bloco PlayerHUD:
-
Bloco PlayerHUD (Opcional, v1.7.1+): Configure custos em itens para iniciar uma rodada ou revelar a dica, e uma concessão de item por rodada vencida.
-
PlayerGroup (Compatível): Grupos padrão do Moodle — criados manualmente ou pela atividade PlayerGroup — são respeitados pelo filtro
SEPARATEGROUPSdo ranking.
Veja o hub do PlayerGames para a família completa de plugins.
🧩 Integração Opcional: Central de IA
A funcionalidade opcional de Geração de palavras por IA do PlayerWords pode usar o Central de IA (local_aihub, do mesmo autor, parte dos serviços compartilhados do ecossistema PlayerGames). Quando o Central de IA está instalado, qualquer chave pessoal ou do site que um professor ou administrador já tenha configurado lá fica automaticamente disponível para o PlayerWords — sem precisar reconfigurar a chave. O PlayerWords nunca contata um provedor de IA diretamente; sem o Central de IA instalado, ele recorre ao subsistema core_ai do próprio Moodle, roteando para o provedor que o administrador do site tiver configurado lá.
👉 https://github.com/jeanlucio/moodle-local_aihub
📦 Requisitos
| Componente | Versão |
|---|---|
| Moodle | 4.5 – 5.2 |
| PHP | 8.1+ |
| PlayerHUD (opcional) | v1.7.1+ |
🛠️ Instalação e Configuração
- Baixe o arquivo
.zipou clone este repositório. - Extraia na pasta
mod/do seu Moodle. - Renomeie para
playerwords(se necessário). Caminho final:seu-moodle/mod/playerwords/ - Acesse Administração do site > Notificações para concluir a instalação.
- Adicione uma atividade PlayerWords a qualquer curso.
Este plugin não tem configurações de nível de site para o administrador ajustar — toda
configuração é feita pelo professor ao adicionar a atividade a um curso, conforme explicado
em Como Usar logo abaixo. Se o block_playerhud não estiver instalado no site, a
própria página de configurações do plugin em Administração do site → Plugins → Módulos de
atividade → PlayerWords mostra um aviso informativo sobre isso — não há nada a configurar
ali de qualquer forma.
📖 Como Usar
- Adicione uma atividade PlayerWords ao seu curso.
- Configure:
- Faixa de comprimento de palavras e máximo de tentativas
- Tempo de recarga entre rodadas e limite de rodadas
- Se dicas são permitidas
- Modo de palavras (aleatório ou sequência compartilhada)
- Método de nota e configurações do livro de notas
- Fontes de palavras (manual, Glossário), fonte de glossário e uma lista de stopwords para ignorar ao dividir conceitos com várias palavras (todos opcionais) — a geração por IA fica sempre disponível na página Gerenciar palavras, independente dessas caixas de fonte
- Custos em itens do PlayerHUD e concessão por vitória (opcional, quando o bloco PlayerHUD está presente)
- Acesse Gerenciar palavras para adicionar, gerar com IA, aprovar, editar ou excluir palavras.
- Os estudantes jogam diretamente na página da atividade — chutando, revelando dicas e desistindo de rodadas, sem recarregar a página. O toolbar da própria página dá acesso às regras (ajuda), ao registro de tentativas e ao ranking.
- Notas e ranking são atualizados automaticamente após cada rodada.
🧮 Nota e Ranking
O PlayerWords calcula uma nota e um total de ranking a partir das mesmas rodadas terminadas, mas os dois são configurados de forma totalmente independente — o professor pode manter a nota simples e ainda assim recompensar jogadas eficientes no ranking, ou o contrário.
Os dois são totalmente opcionais, e cada um liga/desliga por conta própria:
- Nota: deixe o campo padrão
Notacomo Nenhuma pra rodar a atividade sem avaliação nenhuma — nenhuma nota é calculada ou gravada no livro de notas, e as configuraçõesMétodo de avaliação/Pontuação da notasomem do formulário. - Ranking: deixe
Mostrar rankingcomo Não pra esconder o ranking em todo lugar — no jogo, na página dedicada de ranking, e na coluna extra do registro de tentativas — e a configuraçãoPontuação do rankingsome do formulário também.
Desligar um nunca afeta o outro: uma atividade pode ter nota sem ranking, ranking sem nota, os dois, ou nenhum dos dois.
A pontuação por rodada decide quanto vale uma única rodada, escolhida separadamente para a
nota e para o ranking (configurações Pontuação da nota / Pontuação do ranking, ambas com
padrão Binária). A nota usa a nota máxima configurada da atividade como base; o
ranking sempre usa sua própria base fixa de 100 pontos, totalmente independente da nota —
mesmo numa atividade sem nota nenhuma (Nota = Nenhuma, o padrão do formulário), o ranking
continua funcionando normalmente:
| Modo | Uma rodada vencida vale… | Uma rodada perdida, desistida ou com tempo esgotado |
|---|---|---|
| Binária (padrão) | A base cheia (nota da atividade, ou 100 pontos fixos no ranking) | Zero |
| Linear | Base cheia nas duas primeiras tentativas, depois uma fração proporcional às tentativas poupadas: base × (max_attempts − tentativas_usadas + 1) / (max_attempts − 1) |
Zero |
O modo linear dá pontuação cheia nas duas primeiras tentativas — um segundo palpite certeiro não é tratado como menos merecedor que um acerto de primeira, já que este é um jogo educativo não punitivo, não uma disputa de sorte — e só a partir daí distribui as tentativas restantes proporcionalmente, nunca zerando totalmente uma vitória: até vencer na última tentativa permitida ainda rende uma fração positiva. Exemplo com 6 tentativas — a coluna de nota assume uma nota máxima 100, mas a coluna de ranking vale exatamente assim em qualquer atividade, mesmo sem nota nenhuma configurada:
| Tentativas usadas | Nota (base 100) | Ranking (base 100, sempre) |
|---|---|---|
| 1 | 100,00 | 100,00 |
| 2 | 100,00 | 100,00 |
| 3 | 80,00 | 80,00 |
| 4 | 60,00 | 60,00 |
| 5 | 40,00 | 40,00 |
| 6 | 20,00 | 20,00 |
| Não completou | 0,00 | 0,00 |
Com Máximo de tentativas igual a 2 ou menos, o modo Linear fica numericamente idêntico ao
Binário — toda tentativa permitida já cai dentro do platô de pontuação cheia.
Combinar várias rodadas numa nota final é uma configuração separada, Método de avaliação
(maior nota, média, primeira tentativa, última tentativa ou média sobre todas as rodadas
exigidas). Funciona igual independente de a pontuação por rodada acima ser Binária ou Linear: só
agrega o valor que cada rodada já registrou.
O ranking é a soma dos pontos de ranking de todas as rodadas terminadas de um estudante
(SUM), ordenado do maior para o menor; empates são desfeitos por menos tentativas usadas em
média, depois menos tempo gasto em média. Só aparece quando o professor liga “Mostrar ranking”, e
nunca revela uma rodada ainda em andamento.
Só os 5 primeiros aparecem — de propósito, não é bug: tanto o mini-ranking dentro do jogo quanto a página dedicada limitam a lista a 5 linhas, pra evitar expor o ranking da turma inteira publicamente. Um estudante mais abaixo continua vendo exatamente onde está: uma linha extra, separada por “…”, mostra sua posição e pontuação reais, sem revelar a colocação de mais ninguém abaixo do 5º lugar. Quem pode gerenciar a atividade (professor editor, gerente) nunca aparece no ranking, mesmo que jogue a atividade — a mesma regra que exclui suas próprias tentativas do registro de tentativas abaixo.
“Mostrar ranking” só controla a exibição, não a coleta de dados: os pontos de ranking são calculados e gravados em toda rodada terminada, esteja a configuração ligada ou desligada naquele momento. Ligá-la depois que os estudantes já jogaram revela o total acumulado desde o início da atividade, não só os pontos ganhos a partir da mudança — nada se perde, e não é preciso “recuperar” nada ao desligar e ligar de novo.
Trava ao registrar a nota: assim que a atividade registra uma nota real para qualquer
estudante, Máximo de tentativas e Pontuação da nota travam — do mesmo jeito que o Moodle já
trava o campo “Nota máxima” de uma atividade avaliada assim que existem notas reais. Isso garante
que toda rodada já registrada para aquela atividade foi pontuada sob exatamente as mesmas regras
de nota durante toda a vida da atividade.
Pontuação do ranking trava separadamente, assim que existe qualquer tentativa finalizada —
não espera uma nota real, porque os pontos de ranking já são calculados e gravados em toda rodada
terminada independente de Nota ou Mostrar ranking estarem ligados (ver acima). Uma atividade
sem nota nenhuma, só com ranking, já acumula histórico real desde a primeira rodada; travar o modo
de pontuação assim que esse histórico existe evita a mesma inconsistência de escala que a trava
acima evita para a nota.
Registro de tentativas: cada estudante pode conferir suas próprias rodadas passadas — palavra, tentativas usadas, tempo, nota da rodada e (quando o ranking está ligado) pontos no ranking — numa página dedicada do toolbar. Quem pode gerenciar a atividade também vê essa mesma página, incluindo as próprias tentativas caso já tenha jogado a atividade. O relatório de todos os estudantes vive numa página separada, visível só para quem gerencia a atividade: uma tabela com as tentativas de todos os estudantes, 30 linhas por página, ordenável clicando em qualquer cabeçalho de coluna, e filtrável para um único estudante. Assim como no ranking, esse relatório nunca inclui as próprias tentativas de quem gerencia.
Excluir tentativas reverte essas travas quando elas deixam de se aplicar. No relatório com
todos os estudantes, quem gerencia a atividade pode excluir tentativas de um estudante
individualmente ou em lote. A exclusão realmente limpa a nota daquele estudante em vez de deixar
um valor obsoleto para trás, então se todas as tentativas de todos os estudantes forem removidas,
Máximo de tentativas e Pontuação da nota destravam de novo exatamente como
grade_item::has_grades() espera — do mesmo jeito que aconteceria numa atividade nunca jogada.
Pontuação do ranking segue a mesma lógica direto contra a tabela de tentativas, independente de
a nota estar ligada.
🧪 Testes Automatizados
O PlayerWords inclui uma suíte PHPUnit cobrindo lógica de negócio, consultas ao repositório, web services e conformidade com a Privacy API, além de uma suíte Behat cobrindo o jogo, a integração com o PlayerHUD e os relatórios de ponta a ponta num navegador real. Todo push de CI executa a matriz completa (Moodle 4.5 → 5.x, PostgreSQL e MariaDB).
PHPUnit — Testes Centrais
| Arquivo de teste | Casos |
|---|---|
backup_restore_test.php |
6 |
cross_instance_security_test.php |
4 |
lib_grant_potential_test.php |
6 |
lib_reset_userdata_test.php |
4 |
lib_supports_test.php |
2 |
completion/custom_completion_test.php |
7 |
privacy/provider_test.php |
30 |
lib_update_grades_test.php |
2 |
mod_form_test.php |
3 |
lib_grade_item_update_test.php |
2 |
| Subtotal | 66 |
Testes de Lógica de Negócio (tests/local/)
| Arquivo de teste | Casos |
|---|---|
ai_word_generator_test.php |
17 |
attempts_history_service_test.php |
23 |
gameplay_service_test.php |
20 |
hud_service_test.php |
28 |
intro_service_test.php |
5 |
ranking_service_test.php |
9 |
round_presenter_test.php |
46 |
round_service_test.php |
61 |
view_page_service_test.php |
22 |
word_normalizer_test.php |
16 |
words_repository_test.php |
65 |
| Subtotal | 312 |
Testes de Web Services (tests/external/)
| Arquivo de teste | Casos |
|---|---|
count_eligible_words_test.php |
6 |
count_glossary_candidates_test.php |
5 |
end_round_test.php |
6 |
new_round_test.php |
5 |
reveal_hint_test.php |
8 |
start_round_test.php |
7 |
submit_guess_test.php |
10 |
| Subtotal | 47 |
| Total Geral | 425 |
vendor/bin/phpunit --testsuite mod_playerwords
Cobertura de linhas geral (moodle-coverage, PHPUnit + Xdebug): 90%.
Behat — Testes de Ponta a Ponta
| Arquivo de feature | Cenários |
|---|---|
mod_playerwords_smoke.feature |
1 |
mod_playerwords_gameplay.feature |
7 |
mod_playerwords_playerhud.feature |
4 |
mod_playerwords_reports.feature |
5 |
mod_playerwords_settings.feature |
4 |
mod_playerwords_toolbar.feature |
9 |
| Subtotal | 30 |
Ver o detalhamento completo de cada teste e a tabela de cobertura →
🔐 Segurança e Conformidade
- Controle de acesso por capabilities (
mod/playerwords:view,mod/playerwords:addinstance) - Proteção com
require_sesskey()em todas as ações POST; chamadas AJAX são validadas pelo dispatchercore/ajaxdo Moodle - Validação no servidor dos limites de rodadas e tempo de recarga, sempre recalculados a partir da configuração atual
- Timeout de rodada é revalidado contra o prazo real do servidor (com pequena tolerância de latência de rede), em vez de confiar apenas no cronômetro do cliente
- Validação de charset do chute — apenas letras Unicode aceitas
- Palavras geradas por IA são tratadas como entrada não confiável: só termos de um único token, alfabéticos e dentro do comprimento configurado são salvos, entrando pendentes de aprovação do professor
- O estado de sessão da rodada é isolado por instância de atividade e por usuário — um id de palavra ou chave de sessão de uma atividade nunca é aceito por outra
- Um palpite errado nunca vaza a palavra correta nem sua definição; a palavra só é revelada quando a rodada realmente termina
- Compatível com a API externa do Moodle
- Privacy API completamente implementada (LGPD/GDPR)
🔒 Divulgação de Serviço de Terceiros
A geração de palavras por IA é opcional e vem desativada por padrão. Quando um professor a
usa, o tema da atividade (nunca dados de estudante ou registros de tentativa) é enviado através
do Central de IA (local_aihub) — usando a chave própria (BYOK) do usuário ou do site,
se o plugin estiver instalado — ou, como alternativa, através do subsistema de IA nativo do
Moodle (core_ai), que roteia para o provedor configurado pelo administrador do site. O
PlayerWords nunca contata um provedor de IA diretamente; a requisição e sua
divulgação/consentimento são de responsabilidade exclusiva do local_aihub ou do core_ai. Se
nenhum dos dois estiver instalado ou configurado, a fonte de palavras por IA fica indisponível e
todas as outras funcionalidades continuam funcionando normalmente.
- Custo: Nenhum é exigido pelo próprio PlayerWords. Se usada, qualquer custo é o que o
provedor cobrar através de uma chave BYOK no
local_aihub, ou nenhum custo via um provedorcore_aigratuito/institucional que o administrador do site já tenha configurado. - Chaves de API / credenciais: Não são configuradas no PlayerWords. Obtenha e configure uma
chave pessoal ou do site dentro do Central de IA (
local_aihub), ou peça ao administrador do site para configurar um provedorcore_ai. - Credenciais de demonstração: Não aplicável — nenhuma credencial é exigida para instalar ou usar o PlayerWords; a geração por IA é totalmente opcional.
📄 Licença
Este projeto é licenciado sob a GNU General Public License v3 (GPLv3).
Copyright: 2026 Jean Lúcio