How to call functions or fire remote events from tables in modulescripts?

Specifically, I’m trying to write a dialogue script that allows calling functions. I want to write it this way so I can, for example, start a cutscene or display an image after a line of dialogue is displayed. However, because of the way I have written it, I can’t do the usual module.test = function() or module.test() ways of calling a function from module scripts, because if I try those methods, what happens is when I require the module script and send it to the client, before the client even displays the dialogue the game runs any functions inside the dialogue module even if I haven’t even written a way to call it.

I’ve been stuck on this for a little while and I feel like I won’t be able to progress developing my game if I can’t find a workaround. Any and all help is appreciated. Thanks.

--DialogueInfo Module Script

local DialogueInfo = {}

local avatar = {
	Hod = 6855319380;
	Yesod = 6855343573
}

local events = {
	CameraOverhead = game.ReplicatedStorage.CameraTopDown,
	CameraCutscene = game.ReplicatedStorage.CameraCutscene
}

--Dialogue 
DialogueInfo.Dialogue = {
	[1] = {
		Name = "TemplateR6";
		Avatar = {avatar.Hod, avatar.Yesod};
		diaText = "testing dialogue",
		Trigger = events.CameraCutscene
	};
	[2] = {
		Name = "Name change test";
		Avatar = {avatar.Hod, avatar.Yesod};
		diaText = "testing dialogue 2",
		Trigger = {}
	};
	[3] = {
		Name = "TemplateR6";
		Avatar = {avatar.Yesod, avatar.Hod};
		diaText = "testing dialogue 3",
		Trigger = {}
	};
	[4] = {
		Name = "TemplateR6";
		Avatar = {avatar.Hod, avatar.Yesod};
		diaText = "Trigger test"; 
		Trigger = {}
	}
 	

}

--DialogueServer Server Script
local repstorage = game:GetService("ReplicatedStorage")
local TalkStart = repstorage:WaitForChild("TalkStart")





for i, v in pairs(game.Workspace["World Actors"]:GetChildren()) do
	if v:FindFirstChild("ProximityPrompt") then
		if v.CanSpeak.Value == true then
			v.ProximityPrompt.Triggered:Connect(function(player)
				v.CanSpeak.Value = false
				v.ProximityPrompt.Enabled = false
				local diainfo = require(v.DialogueInfo)
				local scene = "placeholder" --get the module for day/scene tracker and send to client
				TalkStart:FireClient(player, diainfo, scene, v)
			end)
		end
	end
	game.ReplicatedStorage.TalkEnd.OnServerEvent:Connect(function()
		v.ProximityPrompt.Enabled = true
		v.CanSpeak.Value = true
	end)
end



--DialogueClient Local Script

--Services--
local uis = game:GetService("UserInputService")
local tweenservice = game:GetService("TweenService")
local repstorage = game:GetService("ReplicatedStorage")
local plr = game.Players.LocalPlayer
local char = plr.Character
local TalkEnd = repstorage:WaitForChild("TalkEnd")

--Gui vars--
local main = script.Parent.Main
local dialogueframe = main.DialogueFrame
local nameframe = main.NameFrame
local portrait1 = script.Parent.Portrait1
local portrait2 = script.Parent.Portrait2

local speaking = false  --debounce





game.ReplicatedStorage.TalkStart.OnClientEvent:Connect(function(diainfo, scene, v)  --Receives the RemoteEvent containing the npc name, dialogue info, and scene
	
--Functions setup
--TODO: Require the module script for tracking the day and scene and display dialogue accordingly

local function typewriter(text, label)
	speaking = true
	print("typewrite start")
	label.Text = ""


	for i = 1, #text do
		label.Text = string.sub(text, 1, i)
		repstorage.AudioFolder.SFX.Tick:Play()
		wait(0.01)
		
	end
	speaking = false
end



local function nextDialogue(text, scene)
	
	print("Dialogue start")
	local currentdialogue = 1

	dialogueframe.TextLabel.Text = ""

	nameframe.TextLabel.Text = text.Dialogue[currentdialogue].Name
	typewriter(diainfo.Dialogue[currentdialogue].diaText, dialogueframe.TextLabel)
	
	repstorage.AudioFolder.SFX.MenuClick:Play()

	uis.InputEnded:Connect(function(key, processed)
		if key.UserInputType == Enum.UserInputType.MouseButton1 or key.KeyCode.EnumType == Enum.KeyCode.Space then
				if speaking == false then
				currentdialogue = currentdialogue + 1
				
				
				--End dialogue conditions
				if text.Dialogue[currentdialogue] == nil then
					char.Cutscene.Value = false
					script.Parent.Enabled = false
					TalkEnd:FireServer()
					
					
					print("end")
				else
					nameframe.TextLabel.Text = text.Dialogue[currentdialogue].Name
					print(currentdialogue)
					--dialogueframe.TextLabel.Text = text.Dialogue[currentdialogue].diaText
					typewriter(diainfo.Dialogue[currentdialogue].diaText, dialogueframe.TextLabel)
					
					
				end
				
				
			end
		end
	end)
end


--The actual script start

repstorage.AudioFolder.SFX.MenuDecision:Play()
script.Parent.Enabled = true
dialogueframe.TextLabel.Text = ""
char.Cutscene.Value = true
nextDialogue(diainfo, scene)




end)


1 Like

Are you talking about firing something like this? I couldn’t read everything you wrote because my attention span short :skull:

Yeah, that. Sorry if the script is long. I don’t know how I can fire those events from outside this module script but in a way where they’re fired when specific dialogue is displayed. I can’t put functions inside these tables either, at least with how I’ve written things. If I do that, the functions fire way too early on dialogue line one.

1 Like

You’d do something like this:

local Module = require(PATH.TO.MODULE)

module.Dialogue[1].Trigger:FireServer()
1 Like

Can’t believe it was staring me in the face the whole time. Thanks man!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.