Foreword
I’ve noticed that I’ve been posting around the link for the CoreScripts repository many times, so I’ve decided to create a resource thread regarding it. This allows for link exposure and future usage, without the hassle of digging up a thread that references it.
Abstract
The following GitHub repository contains Roblox’s core client scripts. Here, you can view the source code for some of the CoreScripts that are inserted into the client at run time.
You may notice that you have some experience working with these scripts. For example, you may have forked the PlayerModule to access a CameraScript module in order to access the PopperCam to add a custom whitelist. In doing so, you’re forking a script that was inserted from this repository. Another example is using RemoveDefaultLoadingScreen. You’re not directly interacting with CoreScripts but you’re using a method exposed by them to modify something they made.
Note: The linked CoreScripts repository is fairly outdated and the last commit was around a year ago. CloneTrooper1019’s RobloxClientWatch repository holds an updated copy of the CoreScripts repository, which you can view here:
In addition, you are also able to view the files via your local file system. The path may look differently for some users, however I can provide the Windows path: %appdata%\..\Local\Roblox\Versions\{LATEST-STUDIO-VERSION}\content\scripts
Exploring
For veteran developers and those who can infer the meaning of various directories, exploring through this repository should be a breeze. For those who aren’t as experienced or need some guidance, I can provide a brief rundown of what you can expect to find and the purpose of each item.
Most or all CoreScripts are self explanatory, given their naming and brief documentation in comments around the script, especially the abstract at the top of each script.
The exploration section is written for the latest commit on the master branch (August 13th, 2018). Please keep in mind that this commit was made nearly a year ago and does not accurately reflect the current version of the CoreScripts at all - there are some very noticeable differences.
The point of showing the repository is allowing you to browse code.
Exploration Directory:
CoreScriptsRoot
CoreScriptsRoot is the first of the two top-level directories in the CoreScripts repository. This directory primarily contains the client CoreScripts you see for various controls, such as core UIs. You will never really find yourself having to access any of the code from this folder.
CoreScriptsRoot contains four code files:
-
LoadingScript.lua: Code for the default loading screen, notoriously known for being removed in favour of custom loading screens. For those curious, Lines 955 to 973 show the behaviour of removing the loading screen either when ReplicatedFirst has non-zero children or RemoveDefaultLoadingScreen is called.
-
MergeSort.lua: This is a module that returns the result of a call from the function mergesort. The mergesort function presents a way to quickly sort through a table, much like table.sort. It takes an array, reproduces a similar array and through a few reassignments of variables, returns a newly sorted table.
- An engineer has noted that mergesort is intended to be used like a script in the command bar, rather than as an actual module (it cannot be used in its raw form unless you modify some parts of the code).
- MergeSort is used as a sorter primarily for custom sorting order in a UI layout, such as UIPageLayout.
-
ServerStarterScript.lua: This script sets up the server-side logic for certain CoreScripts.
-
StarterScript.lua: Another script that sets up logic during initial load. This script is responsible for setting up various CoreGui-based elements.
Within CoreScriptsRoot, there are also four folders; CoreScripts, Libraries, Modules and ServerCoreScripts.
(back to directory) | (conclusion)
CoreScripts
Relatively self explanatory. The scripts in this folder contain code used as the contents of CoreScripts. Each of their functions are explained by the name of the script. There are two exceptions however, to which their name may not immediately explain their purpose:
-
MainBotChatScript2: This script is responsible for handling the ugly legacy dialog system. It has since been rewritten and replaced by a full Lua implementation with more features and a better framework, however it is not currently being maintained.
-
NotificationScript2: This script is responsible for the notifications you see in the bottom right corner of your screen (new badge, new friend, so on), as well as registering the SendNotification SetCore option that allows developers to send their own notifications.
- Note that SetCore can only be called from LocalScripts once it has been registered. I typically set up my script in StarterPlayerScripts to connect to a remote.
- You can have two buttons show up maximum. Having none of them with text hides them; having one of them with text shows only one button; having both with text shows both.
Example code for sending out a notification:
local StarterGui = game:GetService("StarterGui")
-- Called when the user selects an option of the notification
local function OnNotificationOptionSelected(OptionText)
warn("Selected option:", OptionText)
end
local NotificationData = {
Title = "Title", -- Required
Text = "Body", -- Required
Icon = "rbx(game)asset(id)://content", -- Optional, defaults to none
Duration = 5, -- Optional, defaults to 5, dictates how long it stays for
Callback = OnNotificationOptionSelected, -- Optional, defaults to nothing
Button1 = "Yes", -- Optional, defaults to nothing
Button2 = "No", -- Optional, defaults to nothing
}
(back to directory) | (conclusion)
Libraries
The libraries under here are used with the deprecated function LoadLibrary. You are still able to use LoadLibrary as well as the libraries without issue or error, though the libraries and their methods are recognised as deprecated. You’re encouraged to create your own libraries.
-
RbxGui: This library was used to create various Gui objects. Roblox has since provided better methods of accomplishing what RbxGui can do and developers can do the same. For example, ScrollingFrames replace the need to use RbxGui.CreateScrollingFrame.
-
RbxStamper: This library was used in Roblox’s legacy Stamper Building tool. Stampers were commonly used in free or plot-based building games such as the currently-closed Welcome to ROBLOX Building and Personal Servers (the Roblox Fandom page is unofficial, however it covers Personal Servers well enough without me needing to branch off and explain what they were).
-
RbxUtility: One of the most commonly used libraries. As the name suggests, it provided utilities for developers to use at their discretion. RbxUtility still has material that can be salvaged even now, despite the deprecation of LoadLibrary and the libraries.
-
EncodeJSON / DecodeJSON: Full Lua implementations of JSON encoding to and from the format respectively. These functions have since been superseded by their HttpService variants, JSONEncode and JSONDecode. It is more recommended that you use these as they are actively supported and handled in the backend.
- Note: You do not need to use HttpEnabled to perform JSON (en/de)coding.
-
CreateSignal (and related): CreateSignal allows you to create pseudosignals that function similarly to a standard RBXScriptSignal via BindableEvents. There are still developers even now who favour creating signals like this, even to the point of making a signal pseudoclass - as a matter of fact, the Lua Chat System implements this for events as well, such as those listed under the Events section of the ChatService module.
-
Create: Create serves as a more powerful version of Instance.new. This allowed you to specify an object in the same format as Instance.new(ClassName) via RbxUtility.Create(ClassName), however you also got the option to specify properties.
- Another powerful benefit to Create is that it defers (delays) setting the parent, regardless of what order you specify it in the dictionary of properties to set. This acts as a catcher for the bad practice of setting the parent first before the properties, which incurs performance issues.
- Fun fact: the source code for RbxUtility.Create, despite RbxUtility being deprecated, still gets used in some areas internally. The code of RbxUtility.Create is still highly reusable for projects.
-
Code samples and difference between Instance.new and RbxUtility.Create
local Part = Instance.new("Part")
Part.Name = "NewPart"
Part.Parent = workspace
---
local RbxUtility = LoadLibrary("RbxUtility")
local Create = RbxUtility.Create
local Create = LoadLibrary("RbxUtility").Create -- Also valid as a shorthand
local Part = Create("Part")({
Name = "NewPart",
Parent = workspace,
})
local Part = Create("Part"){
Name = "NewPart",
Parent = workspace,
} -- Also valid. Using ["Name"] = "NewPart" is also valid.
(back to directory) | (conclusion)
Modules
The modules folder contains an assortment of modules with code that can be reused or expose various functionality to other CoreScripts. This is another folder that you won’t find really find yourself looking through. There’s of course inspiration, salvaging, getting inspiration for something you’re making or just out of curiosity.
This directory contains seven folders, each of which expand out into more modules or folders. Some folders may contain useful content (such as a handy BarGraph pseudoclass under Stats) for developers who know how to extract, modify and use these modules (it’s usually just as simple as copying the source code and posting it into a ModuleScript).
The Server folder, to note, does contain parts of the previously mentioned Lua Chat System, under the ClientChat and ServerChat modules. You’ll notice similar folders being mirrored while you fork the chat system through the Play Solo → Copy method.
Other than that, there are around 23 modules in this folder. I won’t be running through any of them as I haven’t had time to explore them myself, though the documentation and names of the scripts should suffice in helping you understand. If that doesn’t work, feel free to ask questions.
(back to directory) | (conclusion)
ServerCoreScripts
ServerCoreScripts is essentially the CoreScripts folder, however it relates to the server. There is only a single script within this folder, ServerSocialScript, which handles server-side logic for social interactions.
Social interactions are player-player interactions that can be the following:
- Friends
- Followers
- Blocked users
(back to directory) | (conclusion)
PlayerScripts
PlayerScripts is the second top-level directory in the CoreScripts repository. This mainly pertains to scripts that you see inserted into each respective container under StarterPlayer. This is the directory you may find yourself searching through, directly on GitHub or indirectly by using the Play Solo → Copy fork method especially for the PlayerModule.
There are three folders here: StarterCharacterScripts, StarterPlayerScripts and StarterPlayerScripts_NewStructure.
(back to directory) | (conclusion)
StarterCharacterScripts
This directory matches the name of StarterPlayer.StarterCharacterScripts in the Studio Explorer menu, given the scripts here are placed inside that folder when the server starts initially. Currently, this folder only contains the script for character sounds.
(back to directory) | (conclusion)
StarterPlayerScripts
This directory contains the old modules used in StarterPlayerScripts, when CameraModule and ControlModule were separate. Although you can still salvage these items, it’s recommended that you use the new structure instead, as it is actively supported. It also has better, efficient and centralised features to use over the former two-branch structure.
(back to directory) | (conclusion)
StarterPlayerScripts_NewStructure
Note - this folder does NOT actually contain the new structure. The fork from a Play Solo session is more accurate. This one still uses two modules, while the current version uses one module to unify the two and act as a helper.
This folder contains the source code for the current PlayerScripts structure. PlayerModule is inserted into StarterPlayerScripts, which is a singleton that loads in both the camera and control modules under it respectively. It is initialised by a LocalScript that requires the module eagerly on start-up.
The PlayerModule is designed in a pseudoclass-like fashion, which exposes methods for allowing you to use certain exposed methods of the camera and control modules without directly trying to index them.
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerScripts = LocalPlayer:WaitForChild("PlayerScripts")
local PlayerModule = require(PlayerScripts:WaitForChild("PlayerModule"))
local Cameras = PlayerModule:GetCameras()
local Controls = PlayerModule:GetControls()
local ClickToMoveController = PlayerModule:GetClickToMoveController()
Conclusion
That’s the end.
I’m not well-versed in this topic, I just happened to write this entire thread on a whim with several free hours after two exams. I don’t quite know if the information here is accurate or helpful and it drifted off towards the end particularly because there wasn’t much to say once all the important items were out of the way.
If there’s anything I’m misinformed of, have gotten incorrect, any questions or feedback in general, please do leave a response or drop me a direct message. I’ll try to address anything that’s dropped off within a timely manner, considering I’m hanging around here on a daily basis.
Thank you for reading if you did and good luck with your development.