Manages basic game task / objective logic for Roblox experiences — progress tracking, completion conditions, awards, random timed assignments, and saving.
Add it to your Wally manifest under [dependencies]:
[dependencies]
EzTask = "kestidev/eztask@^1.0.3"Then run:
wally installEzTask installs into the shared realm, so it replicates to clients and its types are usable on both the server and the client.
EzTask reads your task list from a ModuleScript named Task in
ReplicatedStorage.Data that returns an array of task entries. Keeping it in
ReplicatedStorage lets the client read the same definitions for building UI.
-- ReplicatedStorage/Data/Task.luau
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local EzTask = require(ReplicatedStorage.Packages.EzTask)
local tasks: { EzTask.TaskEntry } = {
{
info = {
id = "collect_coins",
name = "Treasure Hunter",
desc = "Collect 5 coins.",
maxProgress = 5,
awards = {
{ id = "coin_collector", name = "Coin Collector", desc = "Found 5 coins." },
},
},
},
{
info = {
id = "say_hello",
name = "Friendly Face",
desc = "Say hello in chat.",
awards = {
{ id = "greeter", name = "Greeter", desc = "Said hello." },
},
},
condition = function(event, data)
return event == "chat"
and typeof(data.message) == "string"
and string.find(string.lower(data.message), "hello") ~= nil
end,
},
}
return taskslocal ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local EzTask = require(ReplicatedStorage.Packages.EzTask)
EzTask.init({
-- onSave is required and must return true on success.
onSave = function(player, data)
-- persist `data` (e.g. to a DataStore) and return whether it succeeded
return true
end,
onLoad = function(player)
-- return the player's previously saved data, or nil
return nil
end,
onSaveFailed = function(player, data)
warn(`[EzTask] failed to save data for {player.Name}`)
end,
maxSaveAttempts = 3, -- optional, default 3
retryDelay = 2, -- optional, seconds between retries, default 2
random = { -- optional: periodically assign a random `random = true` task
min = 10,
max = 20,
unit = "seconds", -- "seconds" | "minutes"
},
})
Players.PlayerAdded:Connect(EzTask.addPlayer)
Players.PlayerRemoving:Connect(function(player)
EzTask.save(player)
EzTask.removePlayer(player)
end)
-- Drive progress from your gameplay:
EzTask.fire(player, "chat", { message = "hello!" }) -- evaluates each task's condition
EzTask.incrementProgress(player, "collect_coins", 1) -- advances a maxProgress taskLoads tasks from ReplicatedStorage.Data, sets up the EzTaskRemotes folder
(GetStats RemoteFunction + Updated RemoteEvent), and starts random
assignment if config.random is set. Returns the EzTask table.
config field |
Type | Notes |
|---|---|---|
onSave |
(player, SaveData) -> boolean |
Required. Return true on success. |
onLoad |
(player) -> SaveData? |
Optional. Restores saved progress in addPlayer. |
onSaveFailed |
(player, SaveData) -> () |
Optional. Called when every save attempt fails. |
maxSaveAttempts |
number? |
Optional, default 3. |
retryDelay |
number? |
Optional, seconds between retries, default 2. |
random |
{ min: number, max: number, unit: "seconds"|"minutes" }? |
Optional periodic random assignment. |
Initializes the player's state and applies any data returned by onLoad.
Clears the player's in-memory state.
Evaluates every incomplete task's condition(event, data) and completes those
that match.
Adds amount (default 1) to a task's progress; completes it once maxProgress
is reached.
Returns the player's current per-task { completed, progress, maxProgress }.
Saves via onSave with retries. Returns whether the save succeeded.
EzTask.TaskCompleted: Signal<Player, TaskInfo>EzTask.AwardGranted: Signal<Player, TaskInfo, AwardInfo>EzTask.TaskAssigned: Signal<TaskInfo>
EzTask.AwardGranted:Connect(function(player, taskInfo, award)
print(`{player.Name} earned {award.name}`)
end)A runnable demo place is included. Build and serve it with:
rojo build demo.project.json -o EzTask.rbxlx
rojo serve demo.project.jsonMIT © kestidev