Creating a custom service

This is my firstest tutorial, im no good teacher but i want to really post this
Before reading the tutorial, you need to know the following:
Bindableevents,
Modulescripts
if you dont know the following, the tutorial will be confusing, i recommend learn them first

NOTE : ill use images to screenshot codes bc i dont want copy and pasters, i want you to understand
how to make it step by step
this tutorial will teach you how to make a service like this


whats even better : you dont need to require() the service in every script

so the required elements are:
2 Scripts (one which is the loader of the service, one normal)
1 ModuleScript (the service)
Organization (you can organize it as you like):
image

so before we get in the loaders and stuff, lets start with the module script
the fresh module script should look like this:
image
okay, keep that local module and return module thing, to make the module script
work, but it will be a useless part

STEP 1

creating the service
so obviously you would put all functions in the modulescript, but if you dont want to require it in all scripts this is a better way:


now you wanna setup the events , uknow, like this
image
sadly, you cant do that unless you do
image
so you would need bindable events, this is what you will do

okay! step 1 is complete

STEP 2

The loader of the service
i mean its pretty easy, you just

require(pathtomodule) -- loads the service
yeah, so easy

Last Step

How to use the service on normal scripts
congrats, you are on the last step
so you wanna use the service in a script, you can simply do this


Note : its a good idea to use :WaitForChild() because the service wont load directly.
now you wanna make the service do something, easy pz

Done! you completed the tutorial, now you can make custom services!

now look at the cool result!


the baseplate dissapeared, nice service

9 Likes

Using the second argument of Instance.new is bad practice and the parent of an object should always be set after all the other properties are.

Also, parenting objects directly to game has uncertain behaviour and should not be done.

7 Likes

Thanks for letting me know about this, I actually had no idea, and have always been setting the parent via the second parameter. I’ll make sure to change that.

1 Like

not bothering to re-check if the warning is still valid is bad practice and it does not matter if it was set with the second arg or not
RobloxStudioBeta_2kzYJhSlKZ

print("parent arg")
local start = os.clock()
local amount = 40000

for i = 1,amount do
	local part = Instance.new("Part",workspace)
	
	part.CanCollide = true
	part.Transparency = .5
	part.Anchored = true
	--task.wait()
end

print(os.clock() - start)

print("no parent arg")
start = os.clock()
for i = 1,amount do
	local part = Instance.new("Part")
	part.Parent = workspace
	part.CanCollide = true
	part.Transparency = .5
	part.Anchored = true
	
	--task.wait()
end
print(os.clock() - start)

ill look into this, i only parented it to game because i wanted the service to be hidden from explorer.

If those are both the exact code you used, then you just performed the same test twice.
No matter though, I did the tests myself too and the results are about the same as yours. But you’re not testing for the actual issue which is that setting properties of a part which is parented will cause inefficiencies on the client beyond just script execution time. If you set all of the properties of a part before you parent it, your code will execute a little bit faster (.728 seconds vs .837 across 10,000 iterations setting three properties with three function calls) and your client will hang less. The efficiency gains don’t matter a lick if you’re doing this less than a thousand times or so, but it’s bad practice to do it since you should be in the habit of parenting only after setting properties.

1 Like

your sample size is too small. try scaling this up to like 200^2, you are saving literal SECONDS not using the second parameter

1 Like

More like picoseconds.
RobloxStudioBeta_YFIUTOoBHz

1 Like

why not use a modulescript on its own?

-- MyService
local Service = {}

Service.Name = "MyService"

function Service.SayHello(name: string): string
  return "Hello, " .. name .. "!"
end

return Service
-- Some server script
local MyService = require(path.to.MyService)

print(MyService.SayHello("World"))

because you dont need to require it in all scripts.

huh, ig you are right. i just tried it on my image render and the difference was only a second

I actually tested it again and now the difference is only .5 seconds?

Creating the instance is not the performance problem experienced when using the second argument of Instance.new, instead it is all the connections that are added internally for listening to property changes.

1 Like

You haven’t even checked have you? There’s 0 difference.
image

I am saying that the performance impact would not be caught by your script as the performance impact is very small when you’re only doing it to one object.

Functions = {
	["Parent Arg"] = function(Profiler) 
		local part = Instance.new("Part",workspace)
		part.CanCollide = true
		part.Transparency = .5
		part.Anchored = true
	end;

	["Parent First"] = function(Profiler)
		local part = Instance.new("Part")
		part.Parent = workspace
		part.CanCollide = true
		part.Transparency = .5
		part.Anchored = true
	end;
	
	["Parent Last"] = function(Profiler)
		local part = Instance.new("Part")
		part.CanCollide = true
		part.Transparency = .5
		part.Anchored = true
		part.Parent = workspace
	end;

Ran with 10,000 iterations, clearly shows there is a difference but the biggest difference is seen when you parent the instance last.

4 Likes

Are you really gonna talk about this in a tutorial?

If you can’t figure out the exact times then just look at the bar graphs at the bottom that shows the times relavent to eachother which gives the most important information.

That explains nothing. And I’m pretty sure my question wasn’t cryptic.

That graph explains everything in a pretty clear format. The issue with using the parent argument is the inefficiencies when you are also setting properties as now three people have told you. @Alts_alt used clear and controlled code examples and his benchmarking has all the data anybody could want in a very scientific format. Roblox staff themselves have advised against using the parent argument. Yes, the difference is slight unless you’re doing something big like terrain generation, but it’s a bad practice nonetheless.
And by way of warning to all of us, this is significantly off-topic and we kinda need to stop or take it to DMs.