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
.luaes suficiente. - Carpeta de modsPermisos
Necesitas permiso para crear una carpeta y un archivo
main.luadentro 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.
Referencia oficial de hooks de SM64CoopDX
Define hook_event, HOOK_ON_CHAT_MESSAGE, sus parámetros y el comportamiento de false utilizado en esta guía.
Diseña el programa antes de escribirlo
Piensa en el mod como un flujo corto:
- Evento: SM64CoopDX entrega un mensaje nuevo al callback.
- Datos: una tabla contiene las palabras elegidas.
- Lógica: un bucle revisa cada palabra y sustituye coincidencias completas.
- Decisión: los mensajes intactos continúan normalmente.
- 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
Crea la carpeta y el archivo de entrada
Crea
chat-filterdentro de la carpetamodsy añademain.luaen su interior.Verificación: La ruta termina en chat-filter/main.lua.
Comienza con una tabla pequeña
Una tabla agrupa valores del mismo concepto:
local blocked_words = { "spoiler", "secret", }Verificación: La tabla contiene solamente términos neutrales de prueba.
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
secretcoincida dentro de una palabra más larga.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]" endVerificación: La función auxiliar devuelve un patrón de Lua.
Crea la función de transformación
El bucle aplica la operación a cada palabra.
string.gsubdevuelve el texto nuevo y la cantidad de reemplazos.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 endVerificación: La función devuelve el texto y un indicador de cambio.
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
falsepara detener el original.-- 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.
Prueba una regla a la vez
Prueba
this is a spoiler, despuésspoilersy 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.
