Skip to content

Getting Started

1Humza edited this page Nov 10, 2021 · 23 revisions

Here I will show you basic usage of the framework so you can grasp some sort of workflow.

Using the Module Loader

At the core of Evolve is the module loader. You should require it at the beginning of every script.

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Evolve"))

It's not the prettiest line of code but it allows us to then require our modules very easily.

local CO = require("CustomObjects")

Create a Class

The first thing you need to do is make a class. You can easily do this by using the Create Class button in the plugin.

With this opened, we can see a field to name our class and designate specific modules to be visible on Server, Client or both(Shared). Parent to selection can be used for creating subclasses.
image
Once clicking Create Class, your selection will be automatically placed on the new class. This operation will create a new Folder and two modules(since we only selected two of the three code visibility types).
image

--Door Class Server Module Script
local Door = {}

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Evolve")) --Require module loader

local Events = require("Events")

function Door.new(Color) --This function is only called when 'new' function through Custom Objects module.
   local newDoor = Instance.new("Part")
   newDoor.BrickColor = Color --Parameters are passed through to this constructor from 'new' function of Custom Objects module.
   return newDoor --Returns an Instance of which wrapper will be applied to.
end

function Door:Initialize() --Called every time Custom Object is created using this class after 'new' function. Also runs when 'Clone' is called on a CustomObject.
   self.OpenStatus = false
end


--Below are user defined properties of the class--

Door.Opened = Events.new("Signal") --Create new Custom Signal

function Door:Open()
   self.OpenStatus = true
   self.Opened:Fire()
end

function Door:Close()
   self.OpenStatus = false
end

function Door:IsOpen()
   return self.OpenStatus
end

return Door
--Door Class Client Module Script

local Door = {}

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Evolve")) --Require module loader

function Door:Initialize() --Called every time Custom Object is created using this class after 'new' function.
				--Also runs when 'Clone' is called on a CustomObject.
   print("Door client initialized")
end

function Door:ClientFunction()
   print("Door client function called")
end

return Door

You are half way there! Now we just need to create our Door using the class module we created.

--Some script

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Evolve")) --Require module loader
local CO = require("CustomObjects") --Require "CustomObjects" module

local redDoor = CO.new("Door",BrickColor.new("Bright Red")) --Returns new Part that is red wrapped with our class!
--This is when 'Initialize' within our class is called.

print(redDoor:IsOpen()) --prints 'false' since we initialized the variable as false in our class.

redDoor:Open()

print(redDoor:IsOpen()) --prints 'true' since variable is set to true in code above.

redDoor.OpenStatus = false --since the variable is assigned as a property of the Door we can skip using the function and set the value ourselves.

print(redDoor:IsOpen()) --prints 'false'

Replication

Since the above code creates a new CustomObject with our Door class, it's currently parented to nil. Thus, we must parent it to a replicated directory such as workspace to allow the client to synchronize with its state.

--Continuation of script block above

redDoor.Parent = workspace --Parenting Door to workspace(replicated directory) will trigger replication of state to the client

wait(1)
redDoor.Test = true
-- Value used in `Await` function in script block below

Now let's get into how we reference our replicated CustomObject on clients.

--Some localscript

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Evolve")) --Require module loader
local CO = require("CustomObjects") --Require "CustomObjects" module

local redDoor = CO.Wrap(workspace:WaitForChild("Door")) --Without a specific class specified as the second argument, yields-
					             --until Custom Object finished replicating onto client.
                                                     --prints 'Door client initialized'
                    
Door:ClientFunction() --prints 'Door client function called'

print(Door:Await("Test")) --after yield, prints 'true'

Removal

Effectively cleaning up CustomObjects on removal is important to avoid memory leaks.
We can do this using Maids and an integrated _CleanUp function within our class, which is run whenever the CustomObject is removed.

What constitutes removal?

Removal refers to Destroy or Removebeing called on a CustomObject.
Here is an example of proper removal practice:

--Door Class Client Module Script

...

local Maid = require("Maid")
local maid = Maid.new()

function Door:Initialize()
    ...
    
    maid:GiveTask(self.Opened:Connect(function() --Giving maid "Opened" Signal to later clean
       ...
    end))
    
   function self._CleanUp()
       maid:DoCleaning() --Maid will clean up "Opened" Signal to avoid memory leak
   end
end

Clone this wiki locally