For your purpose, I think events as mentioned by chivenos is the proper solution, but there is more than one way to do this, so I wanted to bring up the other way for anyone else who finds this thread and maybe has a slightly different use case.
If one script needs to explicitly call a function in another script, you can use Lua modules. Modules are scripts that return some value and allow other scripts to access that value. It's incredibly powerful when building libraries and stuff that needs to be used by a bunch of different scripts (text manipulation tools, commonly used game logic, etc.)
local public = {} -- table that we will return to whatever script asks for it. This will contain all of our instance functions.
function public.formatNumber(number)
number = tostring(number)
return number:reverse():gsub("(%d%d%d)", "%1,"):reverse():sub((#number-2)%3%2 + 1) -- Places commas in thousands spots.
end
function public.notify(player, text)
print(text) -- in a real implementation, you'd have all the long UI transition code and whatever here, so you can implement notifications from scripts that do other crazy things with 1 line of code, making the code more readable.
end
return public -- this says that after our script has finished putting together the table of 'public' functions, we're going to send back our table to anything that asks for it. If you don't put this here, the script won't know to return the table called "public" and it will return nil by default.
So now we've got a basic module that we can access from other scripts, but you're probably wondering, how? Well, the process differs for every Lua application you use. Usually in a console app you'll use the command require("whatever.lua"). In Core, it's a bit different because there are no real "filesystem" accessors. In Core's case, we're gonna use an ID generated specifically for the script
Go ahead and copy that MUID, and then paste it into the require() statement like so:
local moduleLibrary = require("56C095EC35B21005:MyModule")
Congratulations! You've accessed your first module! Now let's call some code from it.
print(moduleLibrary.formatNumber(50000000)) -- should print 50,000,000
Now, this code is accessible to anything that says "require("id")". The script doesn't even have to be spawned in the hierarchy, it will execute and run right from the project content folder in the same context as whatever calls it. In case you're wondering, Core has built-in functions that will allow the module to ask itself if it's running on the server or the client, so just do some poking around for the api names if you ever need to find out. Keep in mind, all scripts have read-write access to this module's table that it gives back. If, for instance, a script runs this code:
moduleLibrary.formatNumber = nil
it will assign the variable "formatNumber" to nil, effectively rendering our function value we had associated with that name to be inaccessible and therefore targetted by the garbage collector for permanent deletion from ram, so make sure that anything you change in the module won't break another script that accesses it too! Hope this helps.
Last note I swear: If you're ever interested, you can look into _G. It's one single table globally shared by all scripts running in the same Lua environment. It can be incredibly useful in large projects that need to communicate information and game state data, or even to be treated as a module that doesn't need to be imported with a require() statement. Just make sure whatever sets _G runs before whatever accesses _G!