Player Count (Ask)

So I supposed that’s a little bit possible but it would take tons of memories, yes?

It’s possible.

-- Pseudo code:
game.Players.PlayerAdded:Connect(function(plr)
	local todaysVisitors = -- get todays visits
	-- Check if current time is on the next day
		-- compared to lastSavedTime
	-- If it's the next day, then set previousVisitors
		-- to the # todaysVisitors. Empty the list
		-- of todays visitors on the datastore
		todaysVisitors = {}
	if plr.UserId in todaysVisitors then
		-- Do nothing. Player is already added to the list.
	else
		-- Add player to data store.
		-- Save the current time to lastSavedTime
	end
end)
1 Like

Or is it possible to make two values using datastore so when player added it will add one to the first values (todayValues) and check if it’s already 00:00 of the next day it will plus the totalValues and reset the todayValues to 0?

What about loading the table? What about the DataStore Limits? Please, Elaborate and understand what i’m trying to say. You can indeed do that but doing it would basically break your game as loading the Data would take alot of time and plus saving it with alot of Players would probably fill the DataStore Limit.


DataStoreDataLimits

You could maybe try creating and hosting your own Server to do WebRequests but that would take alot of time plus despiting the fact anyone could send a DDoS attack to it.
If you want to do that, Then do it. But don’t get surprised if your game DataStores throw errors or Data gets lost.

So I’m supposing it only works if you have small players game? I mean not that famous game that has like 100K players, but it can if like yeah a day you only get 100 or less players.

I mean both works but with less risk.

I think you need to store 3 values. Since your server wont be on every second (most likely, unless you have a fairly popular game) it won’t be active when it reaches 00:00.

todaysVisitors { userId’s } – Prevent storing of already stored user
lastSavedTime { dateTime} – Used to calculate if today is the next day
previousVisitors {number] – Used to display amount of visitors you had previous day.

Regarding @MeCrunchAstroX’s concerns regarding the data limits, you will only request it once every player joins. Since your request limit is 60 + 10 * Players you have more than enough.

The only limit you may need to worry about is the Data limit. (4´000´000 characters is a lot though).

IF you run out of space on your data limit, then simply create a backup key “todaysVisitors2” or something. You have now doubled your storage.

Speed will most likely not be an issue either, since loading data is Async.

Ah no i don’t need player userId tho, I just need the amount(numerical)

You need the userId if you don’t want to calculate unique visitors. You don’t need to otherwise.

I mean I don’t need to store player UserId on the table I just need to know the amount of player that comes to the game.

Ahhh yes. Limit………
But Yes………

Well, Using Regular DataStores would be a bad idea for this, But maybe trying using ProfileService could solve most of those problems? Since ProfileService was specially made for saving and loading data fastly and without needing to worry about limits.

Ahh thank you, yes I know about profile service.

About this how to make the function though?

I have not heard of ProfileService before, however there is no need for incredible speed in this use case. If ProfileService works as smoothly as regular datastores it will probably be a good alternative.

DateTime gives you the day you are currently on (or another day if you give it other input). Comparing the stored date with your current date will tell you if you are on a new day or not.

You don’t have to retrieve data at all really, and there is no point of last saved checks. You can just generate a new key for each day and increment its value everytime a player joins a server. Example:

local datastoreService = game:GetService("DataStoreService");
local playersService = game:GetService("Players");

local today = os.date("!*t");
local key = ("%i_%i_%i"):format(today.day, today.month, today.year);

local visitsStore = datastoreService:GetDataStore("visits_1");

playersService.PlayerAdded:Connect(function(player)
	visitsStore:IncrementAsync(key, 1);	
end);

To get the visit count of a day:

local count = visitsStore:GetAsync(("%i_%i_%i"):format(day, month, year));

And for the people worried about memory consumption, you can only keep the visits count of, say, 30 days by just using :RemoveAsync(). You can get the key like I mentioned above.

EDIT: Updated the code a little:

local datastoreService = game:GetService("DataStoreService");
local playersService = game:GetService("Players");

local visitsStore = datastoreService:GetDataStore("visits_1");

local today = os.date("!*t");

local function getKey(date)
	return ("%i_%i_%i"):format(date.day, date.month, date.year);
end

local function getVisits(date)
	local s, e = pcall(visitsStore.GetAsync, visitsStore, getKey(date));
	if not s then
		warn("There was an error while retrieving the visits on the day" .. tostring(date) .. "\n" .. e);
	else
		return tonumber(e) or 0;
	end
end

playersService.PlayerAdded:Connect(function(player)
	local s, e = pcall(visitsStore.IncrementAsync, visitsStore, getKey(today), 1);
	if not s then
		warn("There was an error while incrementing the visits DataStore:\n" .. e);
	end
	
	local requiredDate = {
		day = 20,
		month = 3,
		year = 2022,
	}
	
	print(getVisits(requiredDate));
end);

Also, I don’t think memory consumption would be an issue here. All we are doing is saving a number on each key per day, right? Thats even less memory than the simplest leaderstats Datastore implementation. Either way, I have provided a solution for the issue in the top.

2 Likes

This is a neat solution. I got so focused on the “http or not” discussion that I completely forgot he may want to store multiple days.

But how to make it so I can make total for a week too? Let’s say 7 days, 1st day - 7th day same 100, so it will total to 700 and Send webhook at 00:00 of monday next week? I don’t ask about how to make webhook but how to make it automatically send the value every beginning day 00:00 of next week

Got a simple solution for that using the getVisits() function I already wrote in my previous post:

The date here is the first date of the week, and it works its way to 6 days after the given date and adds to the count.

local function getWeekVisits(date)
	local dateInS = os.time(date);
	local count = getVisits(date);
	
	for i = 1, 6, 1 do
		count += getVisits(os.date("!*t", dateInS + (i * 86400))); -- 1 day = 86400 seconds
	end
	
	return count;
end

So if you wanted to get the the weekly visits of this week considering today as the last day of the week, provide the date 7 days from before now. To get that date, this is what I found easy:

print(os.date("!*t", os.time(lastDayOfWeek) - (7 * 86400)));

Or the easier way is just to change the sign from + to - in the line:

dateInS + (i * 86400); -- change the "+" to "-" to change the day from first day of week to last day of week

EDIT: Forgot to use the UTC date :man_facepalming:

1 Like

The limitation that breaks this use case is the 6 second write cooldown per key. It works fine with just a few players in just a few servers. But with more servers all writing to the same key, it breaks.