
Είμαι σίγουρος ότι πολλοί από εσάς έχετε αναρωτηθεί αν τα νούμερα που βλέπουμε σε σελίδες όπως το SteamCharts και το SteamDB είναι ακριβή, πόσο μάλλον αληθή. Με την τροπή που έχει πάρει η βιομηχανία του gaming τα τελευταία χρόνια το ενδιαφέρον πολλών από εμάς έχει στραφεί όχι μόνο στην επιφανειακή κατάσταση των παιχνιδιών όπως το gameplay, τα γραφικά και η ιστορία τους αλλά και στον τρόπο ανάπτυξης, τις πωλήσεις και τον αριθμό των ενεργών παικτών – ειδικά στα multiplayer games. Σίγουρα θα έχετε δει ή διαβάσει πολλές συζητήσεις σχετικά με τον αριθμό των ενεργών παικτών κυρίως σε περιπτώσεις μεγάλων παιχνιδιών που δεν πετυχαίνουν τα προβλεπόμενα νούμερα και τότε αρχίζει ο “χορός” προστασίας, επίθεσης και κριτικής.
Σε κάποιες συζητήσεις έχω δει πολλούς να αμφισβητούν αυτά τα νούμερα και δικαιολογημένα, μιας και τα πάντα μπορούν να παραλαχθούν ή να “πειραχτούν”. Ωστόσο, δεν είναι τόσο εύκολο όσο νομίζουμε μιας και οι υπηρεσίες και οι διεργασίες που τρέχουν στο παρασκήνιο κάνουν δύσκολη μια “νοθεία” (π.χ.) στα πραγματικά νούμερα και βέβαια δεν οφελεί και σε κάτι πέρα από ψευδείς νίκες και “flexing”, τα οποία δεν οδηγούν πουθενά.
Η καταγραφή των αριθμών αυτών γίνεται διαρκώς στο παρασκήνιο, σε servers και βάσεις δεδομένων που ανανεωνόνταν διαρκώς, σε πραγματικό χρόνο και διαβιβάζουν συνεχώς αυτή την πληροφορία σε ιστοσελίδες και εφαρμογές. Η λογική της διαβίβασης αυτής βρίσκεται πίσω από τον Κύκλο Ζωής Ανάπτυξης Λογισμικού (Software Development Life Cycle ή SDLC) και στην εργασία που γίνεται από πίσω ώστε να υπάρχουν αυτές οι πληροφορίες.
Για να μπορέσουμε να καταλάβουμε πως αντλεί το SteamCharts αυτά τα νούμερα και τα φέρνει μπροστά, πρέπει πρώτα να καταλάβουμε αυτόν τον κύκλο ζωής.

[divider] Τι είναι ο Κύκλος Ζωής Ανάπτυξης Λογισμικού; [/divider]
Ο Κύκλος Ζωής Ανάπτυξης Λογισμικού (Software Development Life Cycle – SDLC) είναι μια συστηματική διαδικασία που ακολουθείται για την ανάπτυξη λογισμικού, εξασφαλίζοντας ότι το τελικό προϊόν είναι ποιοτικό, λειτουργικό και ικανοποιεί τις απαιτήσεις των χρηστών. Περιλαμβάνει διάφορα στάδια, τα οποία καθορίζουν τη ροή εργασιών, από την αρχική σύλληψη της ιδέας έως τη συντήρηση του λογισμικού μετά την κυκλοφορία του.
Το πρώτο στάδιο είναι η ανάλυση απαιτήσεων (Requirement Analysis), όπου γίνεται η συλλογή και κατανόηση των αναγκών των χρηστών και των επιχειρηματικών απαιτήσεων. Σε αυτό το στάδιο, καθορίζονται οι λειτουργίες που θα πρέπει να έχει το λογισμικό και δημιουργούνται τα απαραίτητα έγγραφα προδιαγραφών.
Στη συνέχεια, ακολουθεί ο σχεδιασμός (Design), όπου καθορίζεται η αρχιτεκτονική του λογισμικού (Architecture), η βάση δεδομένων (DB – Database) και η διεπαφή χρήστη (UI – User Interface). Εδώ αποφασίζεται επίσης η τεχνολογία που θα χρησιμοποιηθεί, όπως οι γλώσσες προγραμματισμού, τα frameworks και τα API. Σε αυτό το στάδιο μπορεί να δημιουργηθούν πρωτότυπα (wireframes, mockups) για να γίνει οπτικοποίηση της τελικής μορφής του συστήματος.
Το επόμενο βήμα είναι η υλοποίηση (Development/Implementation), όπου οι προγραμματιστές γράφουν τον κώδικα σύμφωνα με τις προδιαγραφές. Σε αυτή τη φάση αναπτύσσονται τόσο το frontend (το περιβάλλον χρήστη) όσο και το backend (ο διακομιστής, η βάση δεδομένων και το API). Ο κώδικας ελέγχεται και διαχειρίζεται μέσω συστημάτων ελέγχου εκδόσεων (όπως το Git).
Ακολουθεί η δοκιμή (Testing), ένα σημαντικό στάδιο όπου το λογισμικό ελέγχεται για σφάλματα (bugs) και αστοχίες. Διεξάγονται διάφοροι τύποι δοκιμών, όπως δοκιμές μονάδας (unit testing), δοκιμές ολοκλήρωσης (integration testing) και δοκιμές απόδοσης (performance testing), ώστε να διασφαλιστεί η σωστή λειτουργία του συστήματος πριν την κυκλοφορία του.
Η ανάπτυξη και υλοποίηση (Deployment) είναι το στάδιο όπου το λογισμικό μεταφέρεται από το δοκιμαστικό περιβάλλον σε παραγωγή, δηλαδή σε πραγματικούς χρήστες. Γίνονται οι τελευταίοι έλεγχοι για να διαπιστωθεί ότι το λογισμικό λειτουργεί σωστά και αποδίδει σύμφωνα με τις απαιτήσεις.
Τέλος, υπάρχει η συντήρηση και υποστήριξη (Maintenance & Support), όπου το λογισμικό συνεχίζει να βελτιώνεται και να ενημερώνεται μετά την κυκλοφορία του. Περιλαμβάνει διορθώσεις σφαλμάτων, βελτιώσεις ασφαλείας και προσθήκη νέων λειτουργιών, καθώς και τεχνική υποστήριξη για τους χρήστες.

[divider] Τι είναι το API; [/divider]
Στην διαδικασία ανάπτυξης λογισμικού – αλλά και στο τελικό προϊόν – το API είναι ένα από τα σημαντικότερα στοιχεία. Για την ακρίβεια, το API (Application Programming Interface) είναι ένα σύνολο κανόνων και πρωτοκόλλων που επιτρέπουν σε διαφορετικές εφαρμογές να επικοινωνούν μεταξύ τους. Λειτουργεί ως ένας ενδιάμεσος σύνδεσμος που επιτρέπει σε ένα λογισμικό να ζητά και να ανταλλάσσει δεδομένα με ένα άλλο, χωρίς να χρειάζεται να γνωρίζει τον εσωτερικό του μηχανισμό λειτουργίας. Αυτά διευκολύνουν την ανάπτυξη λογισμικού, καθώς επιτρέπουν στους προγραμματιστές να χρησιμοποιούν ήδη υπάρχουσες λειτουργίες αντί να τις δημιουργούν από την αρχή, εξοικονομώντας χρόνο και πόρους.
Τα API χρησιμοποιούνται ευρέως σε εφαρμογές ιστού, κινητών και λογισμικού, επιτρέποντας, για παράδειγμα, σε μια εφαρμογή καιρού να λαμβάνει δεδομένα από έναν εξωτερικό πάροχο μετεωρολογικών δεδομένων ή σε ένα e-shop να επικοινωνεί με ένα σύστημα πληρωμών.
Υπάρχουν διάφοροι τύποι API, με τους πιο κοινούς να είναι:
- RESTful API: Χρησιμοποιεί το πρωτόκολλο HTTP και μορφές δεδομένων όπως JSON ή XML για την ανταλλαγή πληροφοριών.
- SOAP API: Βασίζεται στο πρωτόκολλο SOAP και χρησιμοποιεί XML για την ανταλλαγή δεδομένων, προσφέροντας μεγαλύτερη ασφάλεια και τυπικότητα.
- GraphQL API: Δίνει τη δυνατότητα στους χρήστες να ζητούν ακριβώς τα δεδομένα που χρειάζονται, βελτιώνοντας την απόδοση σε σχέση με το REST.
- Webhooks: Πρόκειται για APIs που λειτουργούν με βάση γεγονότα (event-driven) και ειδοποιούν άλλες υπηρεσίες όταν συμβαίνει μια αλλαγή.
Με πιο απλά λόγια, τα API είναι σύνολα πληροφοριών και μηχανισμών που διαβιβάζουν πληροφορίες μεταξύ βάσεων δεδομένων και της εφαρμογής. Για παράδειγμα, η απλή διαδικασία σύνδεσης στον λογαριασμό μας απαιτεί από εμάς να εισάγουμε το όνομα χρήστη (ή email) και τον κωδικό πρόσβασης στη φόρμα σύνδεσης της εφαρμογής. Αυτά τα δεδομένα αποστέλλονται μέσω ενός HTTP POST αιτήματος στο API της εφαρμογής. Έπειτα, το API επαληθεύει αυτά τα διαπιστευτήρια μέσω της βάσης δεδομένων και αν τα βρει ή δει πως αντιστοιχούν τότε μας επιτρέπει την πρόσβαση. Αφού γίνει αυτή η διαπίστευση, το API δημιουργεί και επιστρέφει ένα “Authentication Token” που χρησιμοποιείται για τις επόμενες αιτήσεις, αντί να στέλνονται ξανά τα διαπιστευτήρια. Κάθε φορά που ο χρήστης ξανασυνδέεται, το API δημιουργεί ένα νέο, προσωρινό, μοναδικό Token.
[divider] Δηλαδή τι βλέπουμε με το API σε ιστοσελίδες & εφαρμογές; [/divider]
Με τον ίδιο τρόπο λειτουργεί και η παρουσίαση πληροφοριών στο SteamCharts και SteamDB. Ένα API δουλεύει διαρκώς πίσω από τις πλατφόρμες και ζητάει αλλά και στέλνει πληροφορίες από μια βάση δεδομένων και υπηρεσιών της Valve.
Ας πάρουμε ως παράδειγμα την σελίδα store.steampowered.com/charts του Steam το οποίο μας επιστρέφει ορισμένα δεδομένα χρηστών όπως τον ‘Μέγιστο αριθμό χρηστών σε σύνδεση‘. Για να δούμε αν αυτός ο αριθμός είναι σωστός, μπορούμε σαν απλοί χρήστες, να ανοίξουμε το Networkl Dev Tools Tab του Browser μας (F12 –> Network Tab) και να δούμε όλες τις αιτήσεις που τρέχουν στο παρασκήνιο.
Το πεδίο ‘Μέγιστος αριθμός (χρηστών) σε σύνδεση‘ βρίσκεται κάτω από την αίτηση με URL: https://store.steampowered.com/stats/userdata.json?days_back=3. Ανοίγοντας το σύνδεσμο βλέπουμε ένα πλήθος δεδομένων – κυρίως αριθμών – που απεικονίζουν τα δεδομένα που βλέπουμε στην οθόνη. Συγκεκριμένα, για τον αριθμό εδώ:

Η απάντηση που λαμβάνει η αίτηση από τον διακομιστή είναι είναι ένας πίνακας (array) που περιέχει ένα ή περισσότερα αντικείμενα:
[
{
"label": "Steam users logged in",
"color": "#67c1f5",
"data": [
...
[
1740406488000,
35952666
],
...
}
]
Το data περιέχει πολλαπλά ζεύγη [ώρα σε milliseconds, αριθμός χρηστών], για παράδειγμα τα οποία μετατρέπονται σε πραγματικά νούμερα από αλγόριθμο που έχουν δημιουργήσει οι προγραμματιστές.
[divider] Πως αντλεί το SteamCharts/Steam DB τα δεδομένα [/divider]
Το SteamCharts καταγράφει πόσοι παίκτες παίζουν ένα παιχνίδι στο Steam σε πραγματικό χρόνο. Για να το πετύχει αυτό, παίρνει δεδομένα από το Steam Web API, δηλαδή ένα εργαλείο που παρέχει πληροφορίες απευθείας από το Steam, και από τη σελίδα Steam Stats μέσω μιας τεχνικής που λέγεται web scraping (ουσιαστικά «διαβάζει» και αποθηκεύει τα νούμερα από τη σελίδα).
Κάθε λίγα λεπτά, το SteamCharts ελέγχει πόσοι παίζουν κάθε παιχνίδι και αποθηκεύει αυτά τα νούμερα. Έτσι, δημιουργεί ιστορικά γραφήματα που δείχνουν αν ένα παιχνίδι ανεβαίνει ή πέφτει σε δημοφιλία.
Ωστόσο, αν θέλουμε να γίνουμε πιο τεχνικοί, το Steam Web API οποίο παρέχει πληροφορίες σε πραγματικό χρόνο για τον αριθμό των παικτών. Ένα σημαντικό endpoint που αξιοποιεί είναι το ISteamUserStats/GetNumberOfCurrentPlayers, το οποίο επιστρέφει τον αριθμό των παικτών που παίζουν ένα συγκεκριμένο παιχνίδι τη δεδομένη στιγμή. Επιπλέον, μπορεί να χρησιμοποιεί το ISteamApps/GetAppList για να ενημερώνει τη λίστα των παιχνιδιών στο Steam.
Παράλληλα, το SteamCharts εφαρμόζει και web scraping στη σελίδα store.steampowered.com/stats, η οποία εμφανίζει τους πιο δημοφιλείς τίτλους και τον αριθμό των ενεργών παικτών τους. Μέσω αυτής της τεχνικής, το SteamCharts μπορεί να συλλέγει δεδομένα ακόμα και αν το API του Steam δεν είναι διαθέσιμο.
[divider] Πως συλλέγει και αποθηκεύει τα δεδομένα; [/divider]
Το SteamCharts εκτελεί τακτικές μετρήσεις κάθε λίγα λεπτά, είτε μέσω API κλήσεων είτε μέσω scraping, για να καταγράφει τον αριθμό των ταυτόχρονων παικτών. Συνήθως, αυτές οι κλήσεις γίνονται σε συγκεκριμένα URLs. Για παράδειγμα, το Granblue Fantasy Versus: Rising λαμβάνει τις πληροφορίες του από το https://steamcharts.com/app/2157560/chart-data.json που στέλνει την απάντηση που αναφέραμε παραπάνω (δηλαδή πολλαπλά ζεύγη σε [ώρα σε milliseconds, αριθμός χρηστών]).
Τα δεδομένα οργανώνονται ώστε να εμφανίζουν όμως τα δεδομένα ανά ημέρα ή χρονική περίοδο με διάφορους τρόπους:
- Τρέχοντες παίκτες (real-time data).
- Ημερήσιες και μηνιαίες καταγραφές παικτών.
- Μέγιστος αριθμός παικτών (peak players) που καταγράφηκε σε συγκεκριμένες χρονικές περιόδους.
Το SteamCharts δίνει και ιδιαίτερη έμφαση στον αριθμό ταυτόχρονων παικτών (concurrent players), δηλαδή πόσοι χρήστες παίζουν το ίδιο παιχνίδι ταυτόχρονα σε μια δεδομένη στιγμή. Αυτός ο αριθμός ενημερώνεται συνεχώς μέσα στην ημέρα και χρησιμοποιείται για τη δημιουργία ιστορικών διαγραμμάτων.
Επιπλέον, το SteamCharts υπολογίζει και άλλα στατιστικά, όπως:
- Μέσο όρο παικτών σε 24 ώρες.
- Μέσο αριθμό παικτών ανά μήνα, που βοηθά στην ανάλυση τάσεων δημοφιλίας.
- Συγκρίσεις μεταξύ παιχνιδιών, ώστε να φαίνεται πώς αλλάζει η βάση παικτών σε σχέση με άλλα παιχνίδια.
Η απεικόνιση των δεδομένων από ένα API στο Frontend ακολουθεί τα εξής βήματα:
- Ανάκτηση των δεδομένων από το API μέσω
fetchή Axios. - Επεξεργασία των δεδομένων, π.χ. μετατροπή timestamps σε αναγνώσιμες ημερομηνίες.
- Απεικόνιση σε HTML (π.χ. πίνακες, λίστες).
- Οπτικοποίηση με βιβλιοθήκες διαγραμμάτων όπως το Chart.js ή Recharts.
Παραδείγματα πολύ πρόχειρου κώδικα για την απεικόνιση αυτών των στοιχείων στην σελίδα του Steam θα μπορούσαν να είναι τα παρακάτω
Παραδειγμα: Aνακτησης δεδομενων με fetch σε JavaScript
fetch('https://store.steampowered.com/stats/userdata.json?days_back=3')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error fetching data:', error));
Παραδειγμα: Επεξεργασια και Μετατροπη των Δεδομενων
const processData = (apiData) => {
return apiData[0].data.map(([timestamp, users]) => ({
date: new Date(timestamp).toLocaleString(), // Μετατροπή σε αναγνώσιμη ημερομηνία
users: users
}));
};
Παραδειγμα: Απεικονιση των Δεδομενων σε γραφικα και UI
<table>
<thead>
<tr>
<th>Ημερομηνία</th>
<th>Συνδεδεμένοι Χρήστες</th>
</tr>
</thead>
<tbody id="data-table"></tbody>
</table>
<script>
fetch('https://store.steampowered.com/stats/userdata.json?days_back=3')
.then(response => response.json())
.then(data => {
const tableBody = document.getElementById('data-table');
data[0].data.forEach(([timestamp, users]) => {
const row = `<tr><td>${new Date(timestamp).toLocaleString()}</td><td>${users}</td></tr>`;
tableBody.innerHTML += row;
});
})
.catch(error => console.error('Error:', error));
</script>
Παραδειγμα: Διαγραμματα (Charts)
<canvas id="steamChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
fetch('https://store.steampowered.com/stats/userdata.json?days_back=3')
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('steamChart').getContext('2d');
const chartData = data[0].data.map(([timestamp, users]) => ({
x: new Date(timestamp),
y: users
}));
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Steam Users Online',
data: chartData,
borderColor: '#67c1f5',
fill: false
}]
},
options: {
scales: {
x: { type: 'time', time: { unit: 'hour' } },
y: { beginAtZero: true }
}
}
});
})
.catch(error => console.error('Error:', error));
</script>
[divider] Συμπεράσματα [/divider]
Το SteamCharts και το SteamDB προσφέρουν μια πολύ καλή εκτίμηση της δημοφιλίας των παιχνιδιών στο Steam, αλλά δεν είναι απόλυτα ακριβή. Επειδή βασίζονται στο Steam API, δεν μπορούν να καταγράψουν παίκτες σε offline mode ή με ιδιωτικά προφίλ, κάτι που σημαίνει ότι ο πραγματικός αριθμός παικτών μπορεί να είναι λίγο μεγαλύτερος. Παρόλα αυτά, είναι χρήσιμα εργαλεία για να παρακολουθείς τάσεις και συγκρίσεις στη δραστηριότητα των παιχνιδιών με την πάροδο του χρόνου παρά τις ενδεχόμενες μικρές αποκλίσεις ανά διαστήματα.

