Why GetService() and not game?

I’ve even some scripters getting service using game:GetService(), and not just game.???. And I heard that it is encouraged to use :GetService() when getting a service and not use game. Why?

Because some services don’t exist before you use :GetService() on them to create them and also some services have names different than their ClassName for some reason (RunService I’m looking at you) so it’s more convenient to use :GetService() than using the . or [] to get those.

This still doesn’t explain that much, it’s a general knowledge we should know already. Of course we use game:GetService() on services that aren’t visible in the explorer, but why people do game:GetService(“Workspace”) when workspace is a global keyword already?

Consistency. There is no global for the Players service, ReplicatedStorage, etc.

3 Likes

I still don’t get why. These two services can just do game.ReplicatedStorage and game.Players.

Indexing by name is in general a bad practice, it makes assumptions that the instance will always be there, it makes assumptions that Roblox won’t introduce an API member with that exact name. And services can be renamed. So then game.Players etc wouldn’t work.

6 Likes

I’m a person that never renames the services, so what’s still the use for GetService?

Yes but it looks more consistent and better and less prone to error if you use :GetService() than whatever the hell this is:
image

2 Likes

iirc someone told me GetServices get the service internally or somewhere where it can still access the service even if it gets renamed.

i.e Jailbreak names it’s replicated storage container a random uuid value, meaning that game.ReplicatedStorage doesn’t work

These points still stand. More recent example: Upcoming Potential Property Name Conflict: "Pivot"

It hasn’t been done yet, but the fact that they had to make an announcement beforehand shows the problem.

2 Likes

I still don’t understand when you said indexing when I said I’m a person that doesn’t rename services. I don’t understand this post.

game.ReplicatedStorage indexes game for ReplicatedStorage. Class members have precedence over children, so if you had a NumberValue for example inside of a BasePart called Transparency, BasePart.Transparency gets you the property, not the NumberValue. Roblox wants to introduce a property to Models called Pivot, however there are models that name Parts inside of Models “Pivot” to mark a pivot point, so they don’t want to make the change just yet since it would be intrusive.

So you’re telling me to imagine game is BasePart and Transparency is (whatever services)?

3 Likes

I’m not 100 percent on this but i’m pretty sure if you use game.ServiceName too much in too many scripts, it errors because too many scripts are trying to access it. While GetService(ServiceName) gets the class name, and it creates the service if it doesn’t exist I THINK

Just use GetService anyways, once you start using alot of scripts the scripts will error.

I’ll also point out that service objects can be renamed, but GetService() will always return the correct service regardless of the object name.

Though I personally don’t see any point to renaming other than maybe fooling skid exploiters.

Notice how I got the property, not the instance

That is why it is bad practice in these cases, your code wouldn’t be forwards-compatible.

That won’t do anything

What do you mean that won’t do anything. If you rename Players to something random, they can’t just do game.Players anymore. But because you can just get the Player service using game:GetService('Players'), that’s why I say it would only fool skid exploiters.

Right, and since game:GetService is encouraged all around, nobody will directly access it anymore. Skids copy scripts that do the exploiting for them, they don’t make them. So again, this stops nobody. You even noted Jailbreak as a good example of a game where its services get renamed, yet, there are still exploiters.

Feel free to DM me if you want to discuss this further

You’d be surprised how many people still try to path directly. Because it takes so little effort to rename (and I’d personally rename everything to a blank string), you might as well do that on top of using GetService as everyone should be doing in the first place.

Regardless, I mentioned it because that’s another difference between and reason to use GetService over direct pathing, that’s all.