Reutilizar código

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Después de crear algunos scripts, no pasa mucho tiempo antes de que quieras reutilizar algún código entre ellos. Dependiendo de la ubicación, ModuleScripts te permite reutilizar código entre scripts en diferentes lados del límite cliente-servidor o en el mismo lado del límite.

Puedes colocar scripts de módulo en cualquier lugar donde coloques scripts, pero ReplicatedStorage es una ubicación popular; almacenar scripts de módulo aquí te permite reutilizar código entre el servidor y los clientes.

Anatomía de un script de módulo

En Roblox Studio, agrega un script de módulo a ReplicatedStorage y renómbralo a PickupManager. Cada ModuleScript comienza con el siguiente código:


local module = {}
return module

Este código crea una tabla de Luau vacía y la devuelve a cualquier script que requiera el script de módulo.

El valor de retorno puede ser cualquier tipo de dato excepto nil, pero la mayoría de los scripts de módulo devuelven una función, una tabla o una tabla de funciones. Para generar su valor de retorno, los scripts de módulo pueden, por supuesto, ejecutar código arbitrario, lo que incluye requerir otros scripts de módulo.

El siguiente ejemplo devuelve una tabla con una sola función llamada getPickupBonus. Pégalo en el nuevo script de módulo:


-- ModuleScript en ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
común = 10,
no común = 20,
raro = 50,
legendario = 100
}
-- Agrega la función getPickupBonus a la tabla PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager

Agregar la función a una tabla no es estrictamente necesario; podrías simplemente devolver la función en sí, pero es un buen patrón a seguir; te da una sintaxis fácil de entender cuando llamas a la función desde otro script y te permite agregar fácilmente más funciones al script de módulo con el tiempo.

Requerir scripts de módulo

Para cargar un script de módulo, llamas a la función require(). En ReplicatedStorage, agrega un nuevo script y cambia su RunContext a Client. Luego, agrega el siguiente código para llamar a la función PickupManager.getPickupBonus:

Script del cliente en ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtener el valor devuelto por el ModuleScript
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
-- Llamar a una función del ModuleScript
local bonus = PickupManager.getPickupBonus("legendario")
print(bonus) --> 125

Almacenar scripts de módulo en ReplicatedStorage te permite compartir código entre el servidor y el cliente, por lo que puedes usar el mismo código para requerir el script desde ServerScriptService:

Script en ServerScriptService

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))

Cuando llamas a require() en un ModuleScript, se ejecuta una vez y devuelve un solo elemento como referencia. Llamar a require() de nuevo devuelve la misma referencia exacta, lo que significa que si modificas una tabla devuelta o un Instance, las llamadas posteriores a require() retornan esa referencia modificada. El módulo en sí no se ejecuta múltiples veces.

Si requieres un ModuleScript desde ambos lados del límite cliente-servidor, como en el ejemplo anterior, el ModuleScript devuelve una referencia única para cada lado.

Patrones

Los scripts de módulo tienen algunos patrones comunes que puedes usar para simplificar tu código y evitar trampas a medida que tu juego crece en tamaño y complejidad.

Compartir datos

Para asociar datos con objetos individuales, puedes asignar atributos a ellos o crear carpetas de Configuration con objetos de valor como StringValue o IntValue. Sin embargo, ambos enfoques son problemáticos si quieres agregar o modificar docenas de objetos o valores de datos. También, no almacenan tablas o funciones.

Si deseas modificar los mismos datos para múltiples copias del mismo objeto o reutilizar los mismos datos para diferentes objetos, almacena los datos en ModuleScripts. Es una forma más fácil para ti de reutilizar los datos en otros scripts, y puedes almacenar tablas y funciones.

El siguiente ejemplo de ModuleScript en ReplicatedStorage almacena los valores de configuración para una pistola genérica:

ModuleScript en ReplicatedStorage

local GunConfig = {}
GunConfig.MagazineSize = 20
GunConfig.AmmoCount = 100
GunConfig.Firerate = 600
GunConfig.Damage = {
["Cabeza"] = 50;
["Torso"] = 40;
["Cuerpo"] = 25;
}
return GunConfig

Eventos personalizados

Los eventos personalizados permiten que los scripts se comuniquen entre sí, pero tener que hacer un seguimiento de las referencias a objetos individuales BindableEvent puede desordenar tu código.

Puedes usar ModuleScripts para almacenar BindableEvents y proporcionar controladores de eventos personalizados que están directamente vinculados a los métodos del ModuleScript.

El siguiente ModuleScript en ReplicatedStorage tiene un evento personalizado que se activa cuando el interruptor cambia de estado:

ModuleScript en ReplicatedStorage

local Switch = {}
-- Creando un bindable para que cualquier script pueda escuchar cuando el interruptor fue cambiado
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch

El siguiente script del cliente en ReplicatedStorage conecta una función para llamar cuando el evento Switch.Changed se activa.

Script en ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("El estado del interruptor ahora es", newState)
end)
-- Probar el cambio unas cuantas veces
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()

Encapsulación

La encapsulación es la práctica de crear una capa de abstracción alrededor de objetos o lógica de scripting para ocultar la complejidad. Puedes usar ModuleScripts para encapsular objetos de Roblox con funciones personalizadas de Luau para simplificar el código.

Por ejemplo, puedes usar la encapsulación para:

  • Simplificar la comunicación entre redes con un solo objeto RemoteEvent.
  • Envolver el manejo de errores alrededor de servicios sensibles como DataStoreService.
  • Definir métodos personalizados para controlar o extender las características de los objetos de Roblox.

Es difícil hacer un seguimiento de docenas de objetos individuales RemoteEvent para implementar redes en un juego. Puedes usar un ModuleScript para encapsular un solo RemoteEvent para ayudar a simplificar este problema. Al incluir un argumento id único, aún puedes enviar diferentes mensajes de red mientras solo usas un solo RemoteEvent.

En el siguiente ejemplo, el ModuleScript llamado NetworkManagerClient encapsula el método RemoteEvent:FireServer() para incluir este argumento adicional id. Además, este ModuleScript hace referencia al objeto RemoteEvent en sí, por lo que no tienes que referenciarlo en otras partes de tu código. Solo necesitas requerir este ModuleScript para enviar mensajes de red y no necesitas tratar con objetos RemoteEvent en el resto de tu base de código.

El siguiente ModuleScript en ReplicatedFirst proporciona una función encapsulada que puedes llamar en tus scripts de cliente para enviar un mensaje de red:

Módulo de Red

-- ModuleScript en ReplicatedFirst llamado NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Encapsulando la función FireServer del objeto remoto
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient

El siguiente ModuleScript en ServerScriptService usa BindableEvents para que cada script se conecte a un ID específico. Cuando un cliente envía un mensaje de red, cada BindableEvent asociado con el ID especificado se activa.


-- ModuleScript en ServerScriptService llamado NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Vinculando el nuevo BindableEvent al id
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Conectando a
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Encontrando cada evento vinculable que coincide con el ID del evento remoto recibido
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer

El siguiente LocalScript envía un mensaje con el ID RequestA con un argumento opcional Hello.


-- LocalScript en ReplicatedFirst
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))
NetworkManagerClient.FireServer("RequestA", "Hello")

El siguiente Script se conecta al mensaje de red con ID RequestA e imprime una declaración con cualquier parámetro adicional cuando recibe la solicitud.


-- Script en ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Recibido RequestA de", player, ...)
end)
©2026 Roblox Corporation. Roblox, el logotipo de Roblox y "Powering Imagination" son algunas de nuestras marcas registradas y no registradas en los Estados Unidos y otros países.