Como as pessoas já adicionaram boas respostas, deixe-me responder a situações descobertas.
Se você está em uma posição em que concluiu a codificação do seu jogo e agora começa a codificar conquistas e acha muito complexo manter muitas variáveis e contagens e limpá-las em determinados eventos e coisas assim.
Você sempre pode criar uma classe (de preferência singleton) para receber todos os eventos. Agora liste todas as suas realizações. Em seguida, liste todos os eventos do jogo que precisam ser rastreados. Por exemplo, minha lista atual se parece com isso
MATAR INIMIGO - caminhar, balas MORTE DO JOGADOR - queda_off, saúde ENTER_ROOM, EXIT_ROOM etc.
Esses detalhes extras, como caminhar, balas, podem ser parâmetros. Agora, tenha uma função chamada fireEvent nessa classe de acompanhamento de conquistas. Pesquise todos os locais no código em que você precisa disparar eventos e chame essa função. Agora faça o resto do trabalho sujo na classe Conquistas. essa é a maneira mais segura de não perturbar o código e as realizações de código existentes. Funcionou muito rápido para mim.