SM64CDPY

Crea un filtro de chat en Lua y aprende lógica de programación

Crea un filtro de chat para SM64CoopDX mientras aprendes tablas, funciones, bucles, condiciones, patrones de texto y eventos.

Dificultad
Principiante
Plataformas
Windows, Linux, macOS
Tiempo práctico
20 min
Disponible en
La mascota programadora de Retired64 explica un filtro de chat en Lua mediante un flujo de evento, lógica y resultado.

Un buen primer mod debe enseñar algo más que copiar un archivo terminado. En esta guía convertirás una idea sencilla en un programa pequeño: cuando un mensaje contenga una palabra configurada, reemplazar esa palabra completa con caracteres #.

El mod comunitario real que inspiró la lección es Roblox-Like Swear Filter. Su creador aparece acreditado como Gamecube, cuyo nombre de usuario es Blither Dev. Ambos nombres identifican a la misma persona. No reproduciremos la lista extensa del mod. Reconstruiremos la idea con términos neutrales para que entiendas su estructura y después diseñes tus propias reglas responsablemente.

Qué aprenderás

  • Una tabla de Lua almacena datos relacionados.
  • Una función transforma una entrada en una salida.
  • Un bucle aplica la misma regla a cada elemento.
  • Una condición decide si el mensaje original debe continuar.
  • Un hook conecta tu función con un evento de SM64CoopDX.
  • Un segundo valor de retorno comunica si algo cambió.

Antes de comenzar

Requisitos previos

  • SM64CoopDXSoftware

    Usa tu propia instalación funcional. Este tutorial solamente crea un archivo Lua.

  • Editor de textoSoftware

    Cualquier editor de texto plano que conserve la extensión .lua es suficiente.

  • Carpeta de modsPermisos

    Necesitas permiso para crear una carpeta y un archivo main.lua dentro de una ubicación compatible.

La referencia oficial indica que una carpeta de mod puede contener varios archivos Lua siempre que uno se llame main.lua. También documenta HOOK_ON_CHAT_MESSAGE: recibe el MarioState del remitente y el texto del mensaje. Devolver false impide que se envíe el mensaje original.

Documentacióngithub.com

Referencia oficial de hooks de SM64CoopDX

Colaboradores de SM64CoopDX

Define hook_event, HOOK_ON_CHAT_MESSAGE, sus parámetros y el comportamiento de false utilizado en esta guía.

Última verificación
30 de septiembre de 2026

Diseña el programa antes de escribirlo

Piensa en el mod como un flujo corto:

  1. Evento: SM64CoopDX entrega un mensaje nuevo al callback.
  2. Datos: una tabla contiene las palabras elegidas.
  3. Lógica: un bucle revisa cada palabra y sustituye coincidencias completas.
  4. Decisión: los mensajes intactos continúan normalmente.
  5. Resultado: los mensajes modificados se muestran filtrados y se detiene el original.

Esta separación evita mezclar las reglas de texto con la forma en que el juego muestra el chat.

Construye el mod en partes pequeñas

  1. Crea la carpeta y el archivo de entrada

    Crea chat-filter dentro de la carpeta mods y añade main.lua en su interior.

    Verificación: La ruta termina en chat-filter/main.lua.

  2. Comienza con una tabla pequeña

    Una tabla agrupa valores del mismo concepto:

    ArchivoUna tabla de reglaslua
    local blocked_words = {
      "spoiler",
      "secret",
    }

    Verificación: La tabla contiene solamente términos neutrales de prueba.

  3. Convierte una palabra en un patrón completo

    Esta función genera alternativas en mayúsculas y minúsculas. Los marcadores de frontera evitan que secret coincida dentro de una palabra más larga.

    ArchivoUna función auxiliar enfocadalua
    local function whole_word_pattern(word)
      local letters = string.gsub(word, "%a", function(letter)
          return string.format(
              "[%s%s]",
              string.lower(letter),
              string.upper(letter)
          )
      end)
    
      return "%f[%a]" .. letters .. "%f[%A]"
    end

    Verificación: La función auxiliar devuelve un patrón de Lua.

  4. Crea la función de transformación

    El bucle aplica la operación a cada palabra. string.gsub devuelve el texto nuevo y la cantidad de reemplazos.

    ArchivoUna función con dos resultadoslua
    local function filter_message(message)
      local result = message
      local changed = false
    
      for _, word in ipairs(blocked_words) do
          local replacement = string.rep("#", string.len(word))
          local count
    
          result, count = string.gsub(
              result,
              whole_word_pattern(word),
              replacement
          )
    
          if count > 0 then
              changed = true
          end
      end
    
      return result, changed
    end

    Verificación: La función devuelve el texto y un indicador de cambio.

  5. Conecta la lógica con el chat

    El callback deja pasar mensajes intactos. Si encuentra una coincidencia, crea la línea filtrada, reproduce un sonido documentado y devuelve false para detener el original.

    Archivochat-filter/main.lualua
    -- name: Learning Chat Filter
    -- description: A small chat filter built for learning Lua logic.
    
    local blocked_words = {
      "spoiler",
      "secret",
    }
    
    local function whole_word_pattern(word)
      local letters = string.gsub(word, "%a", function(letter)
          return string.format("[%s%s]", string.lower(letter), string.upper(letter))
      end)
      return "%f[%a]" .. letters .. "%f[%A]"
    end
    
    local function filter_message(message)
      local result = message
      local changed = false
    
      for _, word in ipairs(blocked_words) do
          local replacement = string.rep("#", string.len(word))
          local count
          result, count = string.gsub(result, whole_word_pattern(word), replacement)
    
          if count > 0 then
              changed = true
          end
      end
    
      return result, changed
    end
    
    local function on_chat_message(_sender, message)
      local filtered, changed = filter_message(message)
    
      if not changed then
          return
      end
    
      play_sound(SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource)
      djui_chat_message_create(filtered)
      return false
    end
    
    hook_event(HOOK_ON_CHAT_MESSAGE, on_chat_message)

    Verificación: La última línea registra HOOK_ON_CHAT_MESSAGE.

  6. Prueba una regla a la vez

    Prueba this is a spoiler, después spoilers y finalmente un mensaje sin palabras configuradas. Así observarás la coincidencia de palabras completas y el camino sin cambios.

    Verificación: El texto normal continúa y una palabra configurada se convierte en símbolos.

Lee la lógica como programador

blocked_words son los datos. whole_word_pattern prepara una regla. filter_message es la lógica que puedes razonar sin abrir el juego. on_chat_message es el límite de integración con la API de SM64CoopDX.

Cuando añades una palabra, modificas datos. Cuando cambias la coincidencia, modificas la función del patrón. Si cambia la API, revisas el callback del evento.

Mejora mediante experimentos

  • Cambia # por otro símbolo neutral.
  • Añade una sola palabra y predice el resultado antes de ejecutar el juego.
  • Devuelve la cantidad de reemplazos como tercer resultado.
  • Separa la tabla en otro archivo solamente cuando entiendas la versión actual.
  • Escribe casos de prueba: sin coincidencia, una coincidencia, mayúsculas y una palabra más larga.

No comiences pegando una lista enorme. Una tabla pequeña te permite comprender el algoritmo y descubrir errores.

Resultado esperado

Resultado esperado

Ahora tienes un mod dirigido por eventos con datos, transformación e integración claramente separados.

  • El mod aparece en la lista de SM64CoopDX
  • Los mensajes sin palabras configuradas continúan normalmente
  • Una palabra completa se reemplaza con la misma cantidad de símbolos
  • El patrón admite mayúsculas y minúsculas
  • El mensaje original se detiene solamente después de crear la línea filtrada

Qué aprender después

Ya utilizaste estructuras de datos, variables locales, transformación, iteración, condiciones, múltiples valores de retorno e integración por eventos. El siguiente paso útil no es una lista mayor, sino aprender a probar cada función con entradas predecibles y separar configuración de comportamiento.