Γιατί η Χριστουγεννιάτικη εκεχειρία δεν ήταν και τόσο ειρηνική...

Sterben

Social Moderator
Η ομάδα του Grepolis
Στο παρακάτω άρθρο, εξηγούμε το λόγο που η Χριστουγεννιάτικη εκεχειρία δεν ήταν και τόσο ειρηνική..

https://devblog.grepolis.com/?p=2284
-
Αγαπητοί παίκτες,

Όπως πολλοί πιθανόν να βιώσατε ή τουλάχιστον να γνωρίζετε, η περίοδος ειρήνης δεν ήθελε και πολύ να φέρει την ειρήνη στο παιχνίδι φέτος. Και δυστυχώς, αυτό δε συνέβει για πρώτη φορά στην ιστορία του Grepolis, οπότε αυτό το άρθρο έχει σκοπό να εξηγήσει γιατί οι περίοδοι ειρήνης είναι ένα συνεχές πρόβλημα στο Grepolis, τι πήγε στραβά αυτή τη χρονιά και πως θα τα πάμε καλύτερα στο μέλλον.

Οι περίοδοι ειρήνης πηγαίνουν στραβά; Πάλι;
Δυστυχώς, το Grepolis έχει ιστορικό όσον αφορά τις περιόδους ειρήνης - όμως αυτή τη χρονιά, κάτι ήταν διαφορετικό! Ενώ είχαμε προβλήματα με τη λογική και τους ελέγχους για αυτές τις ειδικές περιπτώσεις στο παρελθόν, οι τελευταίες περίοδοι ειρήνης εξακολουθούν να έχουν προβλήματα, καθώς δεν είχαν ρυθμιστεί σωστά. Και πράγματι, το σύστημα για τη δημιουργία μιας τέτοιας ειρήνης ήταν πολύ αργό, οι διευθυντές της κοινότητας δε μπορούσαν να το σχεδιάσουν και έπρεπε να γίνει χειροκίνητα σε κάθε ένα κόσμο ξεχωριστά, έτσι αυτή η διαδικασία ήταν κάπως προορισμένη να αποτύχει σε κάποιο σημείο (ξεχνώντας να σημειωθεί ένα πλαίσιο ελέγχου για έναν από τους κόσμους, ξεχνώντας να επικολληθεί ένα από τα ψηφία για μία χρονική σήμανση...). Αυτός είναι ο λόγος για τον οποίο επανεξετάσαμε το μηχανισμό της δημιουργίας μιας περιόδου ειρήνης, για να χρησιμοποιήσουμε τον ίδιο αποδεδειγμένο μηχανισμό που χρησιμοποιούμε στις εκδηλώσεις του παιχνιδιού (όπως ο Τροχός της Τύχης).

Γιατί εξακολουθούμε να έχουμε προβλήματα; Μήπως το χαλάσαμε όσο το ανασκευάζαμε; Δεν το δοκιμάσαμε αρκετά;
Κατά τη μετακίνηση του συστήματος, γράψαμε αρκετές αυτοματοποιημένες δοκιμές (γνωστές ως Δοκιμές Μονάδας και Ολοκλήρωσης) για να σιγουρέψουμε τη λειτουργικότητα του μηχανισμού, καλύπτοντας επίσης αρκετά σενάρια με τα οποία είχαμε προβλήματα στο παρελθόν, συμπεριλαμβανομένου και αυτού που απέτυχε φέτος. Και όλα κυλούσαν. Φυσικά, δοκιμάσαμε χειροκίνητα την περίοδο ειρήνης, βασικά προσομοιώσαμε τα Χριστούγεννα στους εσωτερικούς διακομιστές μας και εκεί όλα λειτουργούσαν.

Περίμενε, τι; Οπότε τι πήγε λάθος;
Για να το εξηγήσω αυτό, πρέπει πρώτα να εξηγήσω συνοπτικά πως λειτουργεί το Grepolis στο παρασκήνιο. Το Grepolis είναι ένα παιχνίδι όπου το "Backend" (το "πρόγραμμα" που τρέχει στους διακομιστές μας, π.χ. που διαχειρίζεται όσες δράσεις γίνονται, τις μάχες κ.ο.κ.), λειτουργεί με PHP, οπότε δεν "τρέχει" ακριβώς συνέχεια αλλά πρέπει να δημιουργήσουμε το παιχνίδι με κάθε αίτημα του δικού σας περιηγητή ή της εφαρμογής ή από το δικό μας σύστημα (π.χ. όταν φτάνει μία εντολή). Όπως μπορείτε να φανταστείτε, το Grepolis είναι ένα πολύ μεγάλο και πολύπλοκο παιχνίδι, οπότε η δημιουργία του μπορεί να πάρει αρκετό χρόνο. Για να το βελτιώσουμε αυτό (και ως εκ τούτου να έχετε χαμηλότερους χρόνους απόκρισης για τα αιτήματά σας) χρησιμοποιούμε αρκετές διαφορετικές τεχνικές, μία από αυτές είναι η προσωρινή αποθήκευση. Πιθανόν να γνωρίζετε την προσωρινή αποθήκευση από τους περιηγητές σας, όπου αυτοί θυμούνται εικόνες ή άλλα αρχεία για να μη χρειάζεται να τα φορτώνετε ξανά και ξανά αν δεν αλλάζουν. Ουσιαστικά κάνουμε το ίδιο με το "backend", επίσης ειδικά με το "σύστημα συμβάντων" (δηλαδή το σύστημα που χρησιμοποιούμε για τις εκδηλώσεις του παιχνιδιού, καθώς αυτό είναι ένα είδος ειδικού συμβάντος).

Η ιδέα είναι η εξής: Γιατί να ρωτήσουμε τη βάση δεδομένων (το μέρος που αποθηκεύουμε όλες τι πληροφορίες σχετικά με το παιχνίδι), αν γνωρίζουμε ήδη για κάτι, καθώς το να ρωτήσουμε τη βάση δεδομένων είναι αρκετά "ακριβό" (κοστίζει χρόνο), έτσι προσπαθούμε να θυμηθούμε μια απάντηση που ήδη έχουμε.

Εντάξει, όμως αυτό τι έχει να κάνει με τα προβλήματα που αντιμετωπίσαμε;
Ας θυμηθούμε το πρόβλημα που είχαμε: 24 ώρες πριν την περίοδο ειρήνης, δε θα έπρεπε να είναι εφικτό να σταλούν αποικιακά πλοία σε άλλες πόλεις (οπότε δε θα έπρεπε να μπορούν να κατακτηθούν νέες πόλεις αν τα αποικιακά δεν ήταν ήδη στο δρόμο).
Για να εξασφαλίσουμε αυτό και πολλούς άλλους κανόνες, έχουμε μία λίστα με ελέγχους που πρέπει να γίνουν όταν ο παίκτης προσπαθήσει να στείλει μια επίθεση - μόνο όταν δεν παραβιάζεται κανένας κανόνας στέλνουμε την επίθεση.

Και εδώ έρχεται το πρόβλημα: Με την αποστολή μιας επίθεσης, πρώτα ελέγχουμε αν υπάρχει ειρήνη κατά την ώρα άφιξης (ας το πούμε timestamp1) Ή 24 ώρες μετά αν και μόνο σταλεί αποικιακό μαζί με την επίθεση (timestamp2).

Και εδώ έρχεται το πρόβλημα με την προσωρινή αποθήκευση: Έχουμε ήδη φορτώσει τα δεδομένα της ειρήνης για το timestamp1 και τα αποθηκεύσαμε προσωρινά. Όταν κάνει το δεύτερο έλεγχο, η προσωρινή μνήμη νόμιζε ότι ήξερε τα πάντα για τις περιόδους ειρήνης - οπότε αν ξεκινούσε μία νέα περίοδος ειρήνης ανάμεσα στο timestamp1 και το timestamp2, το παιχνίδι απλά δε μπορούσε να το δει.

Εντάξει, το κατάλαβα αυτό - πως όμως περνούσαν οι δοκιμές μας;
Ουσιαστικά αυτός είναι ο λόγος που μας πήρε τόσο να διορθώσουμε το σφάλμα (ξεκινήσαμε τη διόρθωση στις 9μμ στις 23 Δεκεμβρίου και μας πήρε μέχρι τις 1πμ στις 24/12 μέχρι να βρούμε μία διόρθωση γι'αυτό το σφάλμα.) Το πρόβλημα είναι: Η προσωρινή αποθήκευση είναι απενεργοποιημένη στο δοκιμαστικό μας σύστημα καθώς δε χρειαζόμαστε την ενίσχυση της απόδοσης εκεί, από την άλλη όμως θέλουμε να απλοποιήσουμε τη διαδικασία δοκιμών μας (δε θα εμβαθύνω σε αυτό το θέμα). Έτσι, παρόλο που δοκιμάζαμε πολύ, δε δοκιμάζαμε ακριβώς τι συμβαίνει στο πραγματικό παιχνίδι και αυτό ήταν σίγουρα δικό μας λάθος, καμία αμφισβήτηση σε αυτό - και πραγματικά λυπόμαστε!


Το σφάλμα διορθώθηκε, όμως μετά κάναμε ένα άλλο λάθος


Με σκοπό να μειώσουμε τον αντίκτυπο που θα είχε αυτό το σφάλμα σε όλους εσάς, γράψαμε ένα script με σκοπό να ελέγξει όλες τις επιθέσεις που γινόταν, συμπεριλαμβανομένων και των αποικιακών και όλες τις πολιορκίες που ήταν σε εξέλιξη, για να δούμε πότε ξεκίνησε η επίθεση.

Η ακύρωση των επιθέσεων που ήταν σε εξέλιξη, δούλεψε τέλεια. Η ακύρωση των αποικιακών πλοίων: όχι και τόσο - και πάλι, λυπόμαστε πολύ γι'αυτό. Η λογική του script επιδιόρθωσης ήταν η εξής: Πάρε όλες τις πολιορκίες, δες πότε ξεκίνησαν, υπολόγισε την απόσταση από την αρχική πόλη μέχρι την πόλη που τελεί υπό πολιορκία και έλεγξε αν αυτή θα μπορούσε να είναι μία κανονική επίθεση. Εντάξει ως εδώ - εκτός από ένα πρόβλημα: Όταν υπολογιζόταν πότε ξεκίνησε μία πολιορκία (αυτό δεν το αποθηκεύουμε κάπου), έπρεπε να το υπολογίσουμε σχετικά με την ώρα που θα τελείωνε (αυτό το αποθηκεύουμε) και να το αφαιρέσουμε από τις ώρες που διαρκεί η πολιορκία σε αυτό τον κόσμο. Το πρόβλημα εδώ ήταν ότι στους περισσότερους κόσμους, η τιμή είναι 0.

Γιατί 0; Δεν υπάρχουν κόσμοι με στιγμιαία πολιορκία! Το 0 δηλώνει μία προεπιλεγμένη συμπεριφορά, που σημαίνει ότι έπρεπε να υπολογίσουμε 24 ώρες διαιρεμένες με την ταχύτητα του κόσμου. Ήταν ήδη 4π.μ. όταν αναπτύξαμε αυτό το script (η ανάπτυξή του χρειάζεται κάποιο χρόνο και φυσικά δοκιμάσαμε ξανά τα πάντα: αρχικά τη διόρθωσή μας σε πραγματικές συνθήκες, ύστερα το script μας, όλα λειτουργούσαν!) και μέχρι εκείνη την ώρα δε μπορούσαμε να θυμηθούμε αυτή τη λεπτομέρεια - ενώ από την άλλη ήμασταν υπό την πίεση του χρόνου καθώς θέλαμε να ελαχιστοποιήσουμε τον αντίκτυπο αυτού του σφάλματος όσο το δυνατόν περισσότερο. Στους δοκιμαστικούς διακομιστές μας όλα λειτουργούσαν καθώς συνήθως βάζουμε την τιμή εκεί (απλά δε θέλουμε να δοκιμάσουμε κάτι σχετικό με την πολιορκία και μετά να περιμένουμε 8 ώρες για τη συνέχεια), έτσι δε μπορούσαμε να πιάσουμε αυτή την προεπιλεγμένη περίπτωση εκεί.

Αυτός είναι ο λόγος που κάναμε ακόμη ένα script στις 25 Δεκεμβρίου για να αποζημιώσουμε όλους τους παίκτες που επηρεάστηκαν από τις λανθασμένες ακυρώσεις (αυτή τη φορά δεν αναπτύχθηκε στις 3 το πρωί και με σχεδόν καμία πίεση χρόνου) και εκτελέστηκε στις 2:30μμ .

Κλείνοντας
Αρχικά, σας οφείλουμε μία συγνώμη - πραγματικά λυπόμαστε, όλοι αξίζετε καλύτερα και υποσχόμαστε να πάρουμε αυτό το θέμα στα σοβαρά, να αναλογιστούμε και να λάβουμε τα κατάλληλα μέτρα για να αποτρέψουμε τέτοια ζητήματα στο μέλλον (και το πιο σημαντικό για τώρα: να αποτρέψουμε να ξανασυμβεί κατά τη διάρκεια της πρωτοχρονιάτικης περιόδου ειρήνης).

Δεύτερον, αυτό το πρόβλημα αποκάλυψε κάποιες ιδιαιτερότητες και προβλήματα σχεδιασμού με τον υπάρχοντα κώδικα - κάτι που είναι απολύτως φυσιολογικό σε ένα παιχνίδι τόσο παλιό όσο το Grepolis, όμως φυσικά πρέπει τα αντιμετωπίσουμε, ώστε να μην κάνουμε τα ίδια λάθη ξανά σε μια άλλη περίπτωση.

Τρίτον, ευχαριστούμε όλους όσους κράτησαν το Fair Play και δεν έστειλαν αποικιακά πλοία ενώ μπορούσαν να το κάνουν!
 
Τελευταία επεξεργασία από έναν συντονιστή: