UI & Scripting Portfolio | ShaneSloth

About Me

(This portfolio is requires updating)

| Twitter Profile | Roblox Profile | Twitch Profile |

Howdy! I’m ShaneSloth and I have been developing on ROBLOX for just over 7 years. Over the near-decade of learning and scripting on ROBLOX, I have encountered a vast amount of talented and like-minded developers who have helped spur my passion for scripting/programming and helped me turn it into something more.
I am currently a third-year student studying Computer Science, and over the three years of further education I have studied various topics most notable and relevant being:

  • Human-Computer Interaction (UI/UX Design)
  • Intelligent Systems
  • Applied Intelligent Systems
  • Object-Oriented Software Architecture, Design, and Implementation
  • Data Structures & Algorithms
  • ... and various project planning oriented modules!
  • Currently, I am the Chairman of a development studio, Arvorian Industries, revolving around a group on ROBLOX known as RSF, it is somewhat overseen, in partnership, by the Commander of the group, PurpleMicro.


    Personal Projects

    Over the years I have been involved with many projects, however, I will only showcase my most recent (and subsequently, best) work:

    Project Aetherium (Shelved)

    Project Aetherium (Shelved)

    Project Aetherium started as my first endeavour when I came back to ROBLOX after a two-year hiatus while I was at university, I decided I would come back and do what I was always best at, UI for clans.
    Aetherium’s goal was to be as customisable and as thematic as possible, utilising my freshly acquired UI/UX design skills to create one of the smoothest experiences found in the clan world. However, this project was shelved when I began running my development studio, and as such, this project will probably never see the light of day unless I either finish a similar design for my studio, or I get some free time.
    Below you will see a GIF of part of this ‘product’.

    Parametric Phrase Interpreter

    Parametric Phrase Interpreter (WIP)

    This small endeavour of mine is admittedly badly written and could be improved a lot, however, it serves a great purpose for RSF in use with our global kill/death feed.
    As of writing, there is no formal documentation.

    TweenService Overhaul

    TweenService Overhaul

    As of writing, there is no official link or documentation anywhere for this project.

    This project aims to correct/add onto the base TweenService, I am attempting to write it verbatim to make it as comfortable for pre-existing TweenService users to utilise and also to help beginners get more on board with using TweenService over :TweenPosition(), :TweenSize(), and :TweenSizeAndPosition().

    The main attraction point that I aim to produce is allowing more customised tweening, this is done by instead opening up the individual properties of a given property to be tweened on its own ‘Axis’.

    • Color3int | float: red, green, blue
    • Vector3float: x, y, z
    • ColorSequencearray: ColorSequenceKeypoints

    I will use Color3 as our example, let’s say we wanted to tween a given Color3 property, c1 from red (255, 0, 0) to green (0, 255, 0), along the way it would pass first through orange, then yellow, and finally end at, green. For this example, I will show two different methods of tweening on an individual axis using a prototype version of this software.

    This GIF showcases the tween applied with a Linear style (no direction because it’s linear) across all Color3 properties.
    This GIF showcases the tween applied with a custom style and direction across its axes dependent on the event fired (MouseEnter or MouseLeave), this example uses Linear, InSine, Linear and OutSine, Linear, Linear for its r, g, b values.
    Below is a code example utilising the prototype which was implemented into my old 2015 tweening engine.

    Code
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local Modules = ReplicatedStorage:WaitForChild("Modules")
    local Interface = require(Modules.Interface)
    local TweenService = Interface.TweenService
    
    local Gui = script.Parent
    local Frame = Gui:WaitForChild("Frame")
    
    local onEnterEasing =
    {
        [1] = "Linear",
        [2] = "InSine",
        [3] = "Linear"
    }
    local onEnterGoals =
    {
        ["BackgroundColor3"] = Color3.new(0, 1, 0)
    }
    
    local onLeaveEasing =
    {
        [1] = "OutSine",
        [2] = "Linear",
        [3] = "Linear"
    }
    local onLeaveGoals =
    {
        ["BackgroundColor3"] = Color3.new(1, 0, 0)
    }
    
    -- TweenService.Tween(instance Instance, dictionary AxesEasingArray, dictionary PropertyGoals, float Duration)
    -- Currently, this prototype *should* only perform one property at a time, 
    -- however, you can add multiple Properties in PropertyGoals all with the same AxesEasingArray.
    Frame.MouseEnter:Connect(function()
        TweenService.Tween(Frame, onEnterEasing, onEnterGoals, 2.5)
    end)
    
    Frame.MouseLeave:Connect(function()
        TweenService.Tween(Frame, onLeaveEasing, onLeaveGoals, 2.5)
        --TweenService.Tween(Frame, "Linear", onLeaveGoals, 2.5) is an appropriate substitute
    end)
    

    That covers all of what I can divulge into with this fun little project, it is worth noting, however, that the prototypes code is implemented within a 5-year old bootleg tweening engine that I had made, and will instead be written differently, and more similar to TweenService, and will also be equipped to handle not just more types, but also custom bezier tweening of any order.


    UI Showcase

    My UI Showcase as of right now is quite limited; I haven’t listed any work from before I returned August 2019. This section will be updated whenever I have more work to add. Right now though, I hope you like it.

    Disclaimer: My designs are primarily created using ROBLOX Studio UI Components (Frames, TextBoxes, etc.), I am no artist and most of the icons seen are outsourced or free-to-use/license-free, I am able to create some UI using software such as PDN (paint dot net), however, more often than not, I will stick to ROLOX UI to create minimal/material designs.

    Torus UI (SHELVED)

    This UI is not yet functional and has just started being designed, icons are not apparent on the menu screen as of yet, though they will be added!

    Updated UI screenshots to v2

    Loading UI

    The animation in the background (named ‘Digital Rain’) was made using a wholly unnecessary custom ‘AnimationFX’ prototype (basically, it is over-engineered), and the rest of the design and animation was made using my own Tween Engine written in 2015.

    Mesmer UI

    This UI can be seen here, though the final two images displayed are event-triggered and unavailable outside of “raiding”.

    BasicHudFinal

    TerminalFinal


    Scripting Showcase

    This section of my portfolio will be used to both showcase and provide documentation on any open-source asset I release. I hope you enjoy the work.

    Roblox-Firebase - A RESTful Firebase Wrapper

    Guide

    Installation

    Information

    Roblox-Firebase (“RoBase”) is a standalone API-wrapper module for Firebase’s Realtime Database RESTful API. In the future, I may end up writing a similar module for Firebase’s Firestore service, though this will be at a much later date when I have the time to invest in it.

    This is a somewhat niche module, but for those discontented with DataStoreService and looking for an external database alternative that has a decent free-plan, I believe this is the module for you.


    Firefly - Graphical Preset Module

    Firefly ROBLOX Model

    Firefly is a lightweight module designed at reducing the load on rendering performance costs while maintaining a decent client graphics quality setting. This is to say, you can have your client graphics on full while reducing the amount of which is enabled.
    For example, you can customise your graphics settings using this module such that you can disable materials, particle emitters, textures, post effects, global shadows, and, the soon to come atmosphere!

    Firefly comes pre-installed with a default preset list for you so you don’t have to touch the module at all, but for those of you with more confidence you can adjust the presets to whatever values you desire.

    For example, the default preset list will toggle everything listed above off when using the “Min” setting, it will then toggle materials on in the “Low” setting and gradually move it’s way up the list turning more and more features on. You could even remove presets that you do not need, it comes installed with 5 different preset arrangements, these being: Min, Low, Medium, High, and Max.

    It is worth noting this does not interfere with the Client’s RenderSettting QualityLevel property settings.
    This was developed because I wanted to somewhat untie the connection between QualityLevel and Render Distance, as it stands the Client’s Render Distance is tied with the game’s whole QualityLevel which includes cost-heavy features such as Atmospheres and GlobalShadows, I also decided to throw in extra settings to customise: ParticleEmitters, Materials, and Textures*.

    *- Currently Textures just get totally removed when they are toggled off, this might not be optimal for you, feel free to adjust the presets list however necessary.

    Firefly was designed similar to how most AAA (Triple-A) titles and various other games handle their “general” graphics settings

    (with the added addition of turning on individual things at the player’s choosing).

    I intend to add this functionality in a future update of the module - though it is theoretically possible, - you can also turn on notifications for this post or follow me on twitter - link atop portfolio - to follow this project & my work.


    The following is documentation of the used methods of Firefly, I have cut superfluous code out, if you wish to view it download the model below or grab it from the link above.

    Documentation & Cut Codebase
    --> Arvorian Industries Firefly 0.3.0
    --> Written & Maintained by ShaneSloth
    
    
    --> Services
    local Lighting = game:GetService("Lighting")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    
    local Firefly = {
    	Preset = "Medium",
    	Loaded = false,
    
    	Presets = {
    
    		["Min"] = {
    			Materials = false,
    			PostEffects = false,
    			Textures = false,
    			Atmosphere = false,
    			
    			Lighting = {
    				["GlobalShadows"] = false
    			}
    		},
    
    		["Low"] = {
    			Materials = true,
    			PostEffects = false,
    			Textures = false,
    			Atmosphere = false,
    			
    			Lighting = {
    				["GlobalShadows"] = false
    			}
    		},
    
    		["Medium"] = {
    			Materials = true,
    			PostEffects = true,
    			Textures = false,
    			Atmosphere = false,
    			
    			Lighting = {
    				["GlobalShadows"] = false
    			}
    		},
    
    		["High"] = { 
    			Materials = true,
    			PostEffects = true,
    			Textures = true,
    			Atmosphere = false,
    			
    			Lighting = {
    				["GlobalShadows"] = true
    			}
    		},
    
    		["Max"] = {
    			Materials = true,
    			PostEffects = true,
    			Textures = true,
    			Atmosphere = true,
    			
    			Lighting = {
    				["GlobalShadows"] = true
    			}
    		}
    
    	}
    }
    
    Firefly.PartsCollection = { }
    Firefly.ParticleEmittersCollection = { }
    Firefly.PostEffectsCollection = { }
    Firefly.TexturesCollection = { }
    
    
    --[[
    	Initialise Firefly, set default preset for client on player join
    
    	\code Informs client of Firefly initialisation call and warns it could take time scanning the game
    	Begins by grabbing the initial run time of Firefly
    	Scans the workspace and other DataModel containers for relevant Instances
    	{ Parts, ParticleEmitters, PostEffects, Textures }
    
    	Clones the Lighting's current Atmosphere if one exists to the ReplicatedStorage for quick enabling
    
    	Initialisation is complete, grab the start time
    	Inform the client of setup completion and give duration of setup ( Generally 0s )
    
    	Allow Firefly operations to run by setting Firefly.Loaded to true
    
    	If a preset is given and autoAdjustToPreset is true adjust the client to the new default preset
    
    	@param String: preset	a string value representing which preset to load the client with ("Min", "Low", etc.)
    	@param boolean: autoAdjustToPreset	a boolean value indicating whether to allow initialisation adjustment
    ]]
    function Firefly:Initialise(preset, autoAdjustToPreset)
    	-- initialises by collecting all default information
    	print("Initialising Firefly... This may take some time... Scanning workspace & other containers")
    	local s = tick()
    	self:CollectParts()
    	self:CollectParticleEmitters()
    	self:CollectPostEffects()
    	self:CollectTextures()
    
    	if Lighting:FindFirstChild("Atmosphere") then
    		Lighting:FindFirstChild("Atmosphere"):Clone().Parent = ReplicatedStorage
    	end
    
    	local d = tick() - s
    	print("Finished initialisation! Time taken (s): " .. tostring(math.floor(d)))
    	self.Loaded = true
    
    	if preset and autoAdjustToPreset then
    		self:AdjustGraphicsQuality(preset)
    	end
    end
    
    --[[
    	Adjust the client's Graphics Quality setting to a new preset
    
    	\code Check if a new preset is given otherwise default to the current preset 
    	Check that the new preset exists within Firefly's preset list
    
    	If Firefly is not yet loaded before this operation occurs hang the calling thread --> This should probably be handled better. Coroutines preferred.
    
    	Acquire the preset from Firefly's preset list
    
    	Using the given preset update the client's toggles.
    	Set Firefly's in-use preset to the given preset
    
    	@param String: newPreset	a string value representing the preset to adjust the client to
    ]]
    function Firefly:AdjustGraphicsQuality(newPreset)
    	newPreset = newPreset or self.Preset
    	assert(self.Presets[newPreset], "Firefly: The Preset {" .. newPreset .. "} is not a valid preset")
    
    	if not self.Loaded then print("Firefly has not finished initialising, awaiting initialisation...") end
    
    	repeat wait() until self.Loaded
    
    	local presetInformation = self.Presets[newPreset]
    
    	self:ToggleMaterials(presetInformation.Materials)
    		:TogglePostFX(presetInformation.PostEffects)
    		:ToggleTextures(presetInformation.Textures)
    		:ToggleAtmosphere(presetInformation.Atmosphere)
    		:ToggleLighting(presetInformation.Lighting)
    	self.Preset = newPreset
    end
    
    function Firefly:ToggleMaterials(isMaterialsEnabled)
    end
    
    function Firefly:TogglePostFX(isPostFXEnabled)
    end
    
    function Firefly:ToggleTextures(isTexturesEnabled)
    end
    
    function Firefly:ToggleAtmosphere(isAtmosphereEnabled)
    end
    
    function Firefly:ToggleLighting(lightingProperties)
    end
    
    function Firefly:CollectParts(root)
    end
    
    function Firefly:CollectParticleEmitters(root)
    end
    
    function Firefly:CollectPostEffects()
    end
    
    function Firefly:CollectTextures(root)
    end
    
    return Firefly
    

    Firefly.rbxm (5.2 KB)


    Payment

    Currently: FOR HIRE

    Feel free to check out the “Requesting a Commission” process below if you wish to send me a request; though please heed my current status of hiring. Regardless of my status, you are free to send me a message (via any contact method), so long as you follow the process below.

    Requesting a Commission

    1) What exactly do you want?

    Please take 5 minutes to think about, write down, and plan out your request, this can save us a great deal of time in the long run and allows for an easier and more direct way of looking back at the requirements of the order.


    2) What are the requirements of your commission?

    Following the details of your order, I would like you to list some of the requirements of the commission. Requirements may be in the form of MoSCoW (Must do, should do, could do, won’t do) for simplicity for the client, however, more adept customers may find a better, more extensive method to produce requirements, alternatively, we can gather requirements together using any process that fits you.


    3) Do you have any pre-made assets that I may need to work with for this commission?

    If so, please show me pictures of what these are, and perhaps explain what you envision each asset being used for. This question is mainly aimed at UI commissions but can also be relevant to other work too.


    4) Finally, what is your budget?

    As a precursor, I only take USD/GBP as a form of payment, however, I may take a percentage of revenue if I deem the project to be worthwhile in the long run; this is, however, a rarity as I very rarely take on projects large enough to warrant this payment method (my time is primarily consumed with my Studio and University).


    Availability

    I am British so my timezone is UTC-0, I have no specific times that I am free, I am a major night-owl however, and therefore get most of my work done in the evenings and nights. You are free to contact all hours of the day, I will get back to you when I am available (~30-60 minutes maximum, usually straight away)


    Contact

    My preferred method of contact is through Discord, please if you add me, send me a message detailing that you came from this post, thank you.

    Discord: Shane#3756
    ROBLOX: ShaneSloth
    Twitter: Personal and Development Studio


    Closing

    Thank you for taking the time to read through my extensive and formal portfolio; if you are at all interested in what I am doing, you can follow this post, contact me on Discord, or follow my twitter accounts.
    Feedback and constructive criticism are wholeheartedly appreciated and I can’t wait to hear what you think of my work! :heart:

    Changes

    Changelog
    • Major reformatting [24th March]
    • Requesting a Commission process [24th March]
    • Added quick-links atop of the post to Twitter, ROBLOX, and Twitch profiles [24th March]
    • Updated Torus UI screenshots to v2 [22nd March]
    • Loading UI added [17th March]
    • Added Scripting Showcase [18th July]
    • Added Firefly Graphical Preset Module to Scripting Showcase [18th July]
    • Listed Torus UI as “SHELVED” [18th July]
    • Added Robase - A RESTful Firebase API Wrapper to Scripting Showcase [7th September]
    20 Likes

    Overall pretty cool UI/UX animations and interactions. I like the loading screen and your Project Aetherium main menu. :slight_smile:

    1 Like

    Thank you, it means a lot!

    Project Aetherium was by far one of the most fun things I worked on, I’m not entirely happy with how the “Maps” screen turned out but the main menu was :ok_hand:

    Fun fact, though: The Loading UI went through 14 different iterations (2 of which were micro changes) :joy:

    1 Like

    Can you add me on discord because me your name dosen’t work my name on discord is:push151 # 9643(no space)

    This is a really well built portfolio and I should also add that your designs are amazing!
    I was really suprised on how you tweened all those little particles in the loading menu.
    image

    2 Likes

    Thank you, and thank you! The AnimationFX is over-engineered but I’m super happy about how it has turned out, I can’t wait to think of more cool little animations to add onto it, I may even opensource it in the future! :smiley:

    2 Likes

    I cant wait for the opensource. I really like the animation and would very much love to buy something like that from you, but sadly I am a bit broke.

    2 Likes

    Hello, everyone, I am now/soon-to-be available for commissions and have updated the post to reflect that, I would also request you follow the process for requesting a commission provided under “Payment”.

    Thank you!

    As of right now, I need you to create a script for a music player. I have a UI that is already completed, I just need you to finish the job itself.
    disc - durb#3215