Skip to content

Cod2rDude/chained

Repository files navigation

chained

Easy way of chaining tasks.

Table of Contents

Why does this even exist?

I was too frustrated to make a promise library and too egoist to use promise library.

I made this to solve complexity of sequential game logic that usualy requires more than just a linear execution. In normal game programming you may need to pause or go back or skip some tasks based on logic. Normally writing this could lead to nested and spaghetti code. But chained provides a virtual enviroment (I dont know if its good to call it like this.) where you can manage, navigate, insert, skip or go back in tasks keeping complex execution flows look simple.

Features

  • Non-Linear Navigation: Tasks can dynamically control the flow by skipping ahead or looping backward to retry previous steps using skip() and goBack().
  • Dynamic Injection: New tasks can be inserted into the chain at runtime using addNext(), allowing for adaptive workflows.
  • Shared Blackboard: A built-in database table allows all tasks in a chain to read and write shared data without passing arguments manually.
  • Tuple Support: Automatically captures and passes multiple return values from one task to the next.

Installation

To install this to your computer you have this options;

  1. Clone this repository by running following command
    git clone https://github.com/Cod2rDude/chained
  2. Get the latest release of .rbxm file from releases
  3. Or add this as a submodule to your project
    git submodule add https://github.com/Cod2rDude/chained [PATH]

Wally will be added in future (I hope).

Usage

Simple Argument Pass

local chain = Chained.new({
    -- Task 1: Returns 3 values
    function(skip, addNext, goBack)
        return "Sword", 50, true
    end,

    -- Task 2: Receives them directly
    function(skip, addNext, goBack, item, damage, isRare)
        print(item, damage, isRare) -- Output: Sword 50 true
    end
}, true, true) -- This 2 booleans are 
-- stopOnError, runImmediately

Shared Database

local chain = Chained.new({
    function(skip, addNext, goBack)
        self.database.PlayerName = "Hero"
        self.database.HP = 100
    end,

    function(skip, addNext, goBack)
        -- Access data set by previous tasks
        print(self.database.PlayerName, "has", self.database.HP, "HP")
    end
}, true, true)

Non-Linear Navigation

local chain = Chained.new({
    function(skip, addNext, goBack)
        local success = (math.random() > 0.5)
        
        if not success then
            print("Failed... Retrying!")
            goBack(1) -- Restart this task 
            -- It runs this task again because there is
            -- no previous task
        else
            print("Success! Moving on.")
            skip(1) -- Skip the next task
        end
    end,

    function() print("I was skipped!") end,
    function() print("Finished.") end
}, true, true)

Adding A New Task

local chain = Chained.new({
    function(skip, addNext, goBack)
        print("I am Task 1")
        
        -- Inject a new task to run immediately after this
        addNext(function()
            print("I am the Secret Task!")
        end)
    end,

    function() print("I am Task 2") end
}, true, true)

Await

local chain = Chained.new({
    function() task.wait(1) print("Loading assets...") end,
    function() task.wait(1) print("Spawning player...") end
}, true, true)

local success = chain:await() -- Success is whatever if any task was failed

if success then -- Wont run until chain is finished
    print("Game loaded!")
end

Creating an Infinite Loop

local chain = Chained.new({
    function(skip, addNext, goBack)
        print("Intermission...")
        task.wait(5)
    end,

    function(skip, addNext, goBack)
        print("Round Started!")
        task.wait(60)
        print("Round Ended.")
        
        -- Loop back to previous task forever
        goBack(1)
    end
}, true, true)

Finished Callback

local chain = Chained.new({
    function() task.wait(1) end,
    function() print("Jobs done.") end
}, true, true, function()
    print("The entire chain is finished!")
end)

On Error Callback

local chain = Chained.new({
    function()
        error("Something went wrong!")
    end
}, false, true, nil, function(err)
    warn("Caught error:", err)
end)

API

Please check out source code for further info about api. (Sorry!)

(I plan to make a project to autoconvert it to a documentation automatically.)

Found a Bug?

If you encounter any issues or unexpected behavior, please let me know! Your feedback helps make this library more stable.

  1. Check the existing issues to see if it has already been reported.
  2. If not, open a new issue and describe the problem.
  3. Provide a small code snippet to reproduce the bug if possible.

Contribution

Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

Contributing

To maintain the stability of the library, direct commits to the main branch are restricted. Please follow the workflow below to suggest changes:

  1. Fork the Project: Create your own copy of this repository.
  2. Create a Feature Branch:
    git checkout -b feature/AmazingFeature
  3. Commit your changes:
    git commit -m 'Add some AmazingFeature'
  4. Push to branch:
    git push origin feature/AmazingFeature
  5. Open a Pull Request: Navigate to the original repository and click "New Pull Request". Describe your changes in detail so they can be reviewed.

Once your Pull Request is merged, GitHub will automatically list you in the official "Contributors" section of the repository. (i guess so)

After a successful merge, I will also manually add your name and contribution to the table below!

Guidelines

We appreciate contributions you will make but we will also highly appreciate you to follow our guidelines while contributing.

  1. Of course make sure your code is efficient.
  2. No nsfw links, swearing or anything like those.
  3. Maybe follow the coding style we do.
  4. That's it!

Contributors

Contributor Description
Cod2rDude Creator
scrpt2r Helped on __log__

This project is licensed under The MIT License