CounterService - Free and Simple Counter and Timer Maker

Introduction

CounterService is a free, easy-to-use service for creating counters and timers in your Roblox game. Whether you need simple counters to track in-game statistics or timers for speedruns, this service will make it simple to implement these features.


Note: this is my first resource and new features will be added.


Features:

  • Counters: Track numbers like player points, steps, items collected, and more.
  • Timers: Easily add timers for various events, speed runs, or countdowns.
  • Knit Supported: You can use this with knit too!
  • Open-Source: Add custom functions based on your needs.
  • Signal Support: React to changes in counters and timers via events like Updated, Started, Paused, etc.
  • Flexible Operations: Update counters with various operators such as +, -, *, /.

How to Use

Counters

  1. Create a Counter:

    local CounterService = require(game.ReplicatedStorage.CounterService)
    local counter = CounterService:CreateCounter("MyCounter")
    
  2. Get a Counter:

    local counter = CounterService:GetCounter("MyCounter")
    print(counter.Count)
    
  3. Update a Counter (with any operator):

    • Increment by 5:

      local counter = CounterService:GetCounter("MyCounter")
      counter:Update("+", 5)
      
    • Multiply by 2:

      counter:Update("*", 2)
      
  4. Set a Counter to a Specific Value:

    counter:Set(10)
    
  5. Reset a Counter:

    counter:Reset()
    
  6. Remove a Counter:

    CounterService:RemoveCounter("MyCounter")
    
  7. Listen for Counter Updates:

    • Example to track when a counter is updated:
      local counter = CounterService:GetCounter("MyCounter")
      counter.Updated:Connect(function(updatedCounter)
          print(updatedCounter.Name .. " was updated. New count: " .. updatedCounter.Count)
      end)
      

Timers

  1. Create a Timer:

    local timer = CounterService:CreateTimer("SpeedRunTimer")
    
  2. Update a Timer:

    timer:Update()
    print(timer.Minutes, timer.Seconds, timer.Milliseconds)
    
  3. Set Timer Value:

    timer:Set(2, 30, 500) -- Set to 2 minutes, 30 seconds, and 500 milliseconds
    
  4. Start a Timer:

    timer:Start()
    
  5. Pause a Timer:

    timer:Pause()
    
  6. Stop a Timer:

    timer:Stop()
    
  7. Listen for Timer Events:

    • Example to detect when a timer is paused:
      timer.PausedSignal:Connect(function(pausedTimer)
          print(pausedTimer.Name .. " was paused.")
      end)
      

Tutorial: Setting Up and Using CounterService

Step 1: Importing CounterService

  • Save the CounterService script in your ReplicatedStorage folder.

Step 2: Setting Up a Counter

  • Create a counter in your server script:
    local CounterService = require(game.ReplicatedStorage.CounterService)
    CounterService:CreateCounter("ScoreCounter")
    

Step 3: Working with Counters

  • Increment your counter by 10:
    local counter = CounterService:GetCounter("ScoreCounter")
    counter:Update("+", 10)
    print("Player score:", counter.Count)
    

Step 4: Timers

  • Create and start a timer for a speedrun:
    local timer = CounterService:CreateTimer("SpeedRunTimer")
    timer:Start()
    
    -- Simulate updating the timer every second
    while wait(1) do
        timer:Update()
        print(timer.Minutes, timer.Seconds, timer.Milliseconds)
    end
    

Example Usage Example:

You can extend CounterService to listen for updates, changes, and pauses in both counters and timers by connecting to the appropriate signals. This allows you to trigger specific game events when a counter or timer reaches a certain threshold.

For example, to detect when a counter reaches a score of 100:

local counter = CounterService:GetCounter("ScoreCounter")
counter.Updated:Connect(function(updatedCounter)
    if updatedCounter.Count >= 100 then
        print("Player has reached 100 points!")
        -- Trigger any specific game logic here
    end
end)

Get it on: Creatorhub

6 Likes

this looks amazing let me just try it and give you a feedback

2 Likes

idk what is going but it is giving me errors

2 Likes

don’t start functions with . start with : as shown in the tutorial. and dont add another argument after the name in :CreateTimer(name : string) function

3 Likes

it is not working iam sorry for that but my plugin works with “.” not “:” :sweat_smile:

1 Like

your plugin should also start with : as that’s how ROBLOX’s functions work

2 Likes

the problem is that is there is already some people using it so if i updated to “:” i will broke their scripts

1 Like

you won’t, their module will not be updated

2 Likes

the plugin offers a way to update the module and if i added a new functions they will not be able to update it

1 Like

Ok, but is MY module working? let me know

2 Likes

it is i tried counters and timers and both is working well for me

2 Likes

if you can add auto update timers and counters

1 Like

some considerations

  • use . instead of : for your functions, eg. API.StartTimer(), you’re not even using self
    honestly would be better if this was written in OOP / DOP

  • add signals like Created, Started, Paused, Updated for these

  • stuff like UpdateCounter shouldn’t just increment the counter, what if I wanted to use other operators? +, /, *, -

your using error wrong…?

error("No Timer found with name: ", name)

results in

invalid argument #2 to ‘error’ (number expected, got string)

just stick to doing

error("No Timer found with name: "..name)

there’s not really a usage case for both of these as it is right now,

2 Likes

I dont like to use oop that much as what if i need to use the same timer in two scripts
?

1 Like

then you can just simply do this

--[[ Modules ]]
local Counter = {}
Counter.__index = Counter

--[[ Variables ]]
local StoredCounters = {}

--[[ Main Functions ]]
function Counter.new(Name)
	local NewCounter = setmetatable({}, Counter)
	NewCounter.name = Name
	
	StoredCounters[Name] = NewCounter
	return NewCounter
end

function Counter.GetCounterByName(Name)
	return StoredCounters[Name]
end

--[[ Returning ]]
return Counter

(this is just a example)

store the counter in a table and just have a function check the table to see if a counter with the name exists

1 Like

Thanks bro, ill probably add all those. But ill still use : . Please give me more suggestions. Also, another reason for not using oop was the simplicity of the code for begieners

2 Likes

: is oop syntax sugar to be used alongside the self keyword. its fine to use this way, sure, but you’re adding an implicit first argument to your functions by using it

2 Likes

the simplicity shouldnt matter, they don’t need to read the actual code in the module to understand how to use it, providing them a API usage like the one you did in the post should work, this goes for every other package like Topbar+, ProfileService, etc.

2 Likes

CounterService v0.2


Key Updates:

  • Set Method: Easily set specific values for counters and timers.
  • More Operators: Counters now support +, -, *, and / for updating values.
  • Signal Enhancements: New signals like Created, Updated, Paused, and Started allow for greater control and custom events.
  • Full Type Checking: Now you don’t have to spend hours correcting mistakes lol.

This update improves ease of use and extends functionality for tracking game stats or managing timers!

4 Likes

This is misleading, not all roblox’s functions uses : you’re very mistaken. : is mainly used for OOP, and tbl:func() the same as doing tbl.func(self). The : notation implicitly adds an self variable that refers to the table. You should only use : when doing OOP/when actually necessary. Just use . otherwise. Oh yeah another thing: : is called a method and . is called a function

Here are some examples of roblox “functions” that uses .:

  • Instance.new
  • Instance.fromExisting
  • Rect.new
  • math.sqrt, math.pow, …
  • CFrame.new, CFrame.Angles, …
2 Likes