חשבונות שחקנים

תנו לשחקנים של המשחק שלכם חשבון שהם שומרים על פני כל משחק שנוצר עם Aukimi, עם שמירות שעוקבות אחריהם ממכשיר אחד לשני, על שירות Aukimi או על שרת משלכם.

בשורה אחת#

שחקן נכנס פעם אחת ב-play.aukimi.com ומוצא את החשבון הזה בכל משחק שנוצר עם Aukimi (שמירות כלולות). המשחק שלכם מבקש את החשבון; הוא אף פעם לא מטפל בסיסמה.

למה המשחק שלכם אף פעם לא רואה את הסיסמה#

כל אחד יכול לפרסם משחק. משחק שמבקש סיסמת Aukimi היה עמוד פישינג משכנע לחלוטין, ושום כמות של כוונות טובות מצדכם לא הייתה משנה מה מפתח אחר יכול לשלוח.

אז הסיסמה מוקלדת ב-play.aukimi.com ובשום מקום אחר. המשחק שלכם קורא ל-PlayerLoginAsync(), חלון דפדפן נפתח בצבעים של Aukimi עצמה, השחקן מאשר, והחלון מוסר למשחק שלכם טוקן.

הטוקן ההוא מונפק עבור המשחק שלכם בלבד. טוקן ממשחק א' שמוצג למשחק ב' נדחה, לא מתעלמים ממנו, נדחה. זו הנקודה: החשבון משותף בין משחקים, הגישה לא. בלי זה, משחק זדוני אחד היה קורא את השמירות של שחקן בכל האחרים.

מה אתם מקבלים על שחקן#

שני דברים, ולא יותר:

מה שאתם מקבליםמה שלעולם לא תקבלו
שם תצוגה (PlayerName())כתובת האימייל
id אטום, שונה בכל משחק (PlayerID())כל דבר שמזהה אותם במקום אחר

ה-id משתנה ממשחק אחד לשני בכוונה. שני מפתחים שמשווים בין רשימות השחקנים שלהם לא יכולים לדעת שהם מסתכלים על אותו אדם. זה גם שומר עליכם כמעבד ולא כבקר של הנתון הזה, וזו הבחנה משפטית ולא קישוטית.

שום דבר לא חוסם את לולאת המשחק#

כל פקודה שמדברת עם הרשת מחזירה מספר job, אף פעם לא תוצאה. הלולאה שלכם ממשיכה לרוץ בשישים פריימים לשנייה בזמן שהבקשה בדרך (זו כל הסיבה שמשחק לא יכול פשוט "לחכות לשרת").

job = PlayerLoginAsync()

ואז, פעם אחת בכל פריים:

etat$ = PlatformJobState(job)
if etat$ = "done"
    resultat$ = PlatformJobResult(job)
    PlatformJobRelease(job)
endif
if etat$ = "error"
    Print(PlatformJobError(job))
    PlatformJobRelease(job)
endif

שחררו את ה-job ברגע שקראתם אותו. job שאף פעם לא משוחרר שומר את התוצאה שלו בזיכרון לשארית הסשן. שום דבר לא נשבר, שום דבר לא מזהיר אתכם, והדליפה מתגלה רק בסשן משחק ארוך.

לשחק בלי חשבון#

לא כולם רוצים להירשם לפני שהם מנסים משחק. PlayerGuestAsync(name$) יוצר חשבון בלי אימייל, נשמר בדפדפן הזה.

זה חשבון אמיתי: הוא שומר, הוא טוען, ואפשר לתבוע אותו מאוחר יותר, השחקן מוסיף אימייל וסיסמה, והשמירות הקיימות ממשיכות בלי לזוז.

הקאץ' הכן: מחיקת נתוני האתר של הדפדפן מאבדת את החשבון הזה, ואין דרך לשחזר אותו. זה המחיר של "בלי הרשמה", והמשחק שלכם צריך לומר את זה במקום לתת לשחקן לגלות. PlayerIsGuest() קיים בדיוק בשביל המשפט הזה.

שמירה#

job = PlayerSaveAsync(donnees$)
job = PlayerLoadAsync()

השמירה היא JSON בצורה שלכם, נשמרת כנגד הזוג (השחקן הזה, המשחק הזה). היא עוקבת אחריהם לדפדפן אחר, מכונה אחרת, פלטפורמה אחרת.

עבור כמה ערכים, SetCloudDataVariable() ו-CloudDataVariable() פשוטים יותר, בלי job, בלי JSON. בדקו CloudDataAllowed() קודם: הוא מחזיר 0 כשאף שחקן לא נכנס, וכתיבה בכל זאת תלך לשום מקום בשקט.

ציור המסך#

Aukimi לא מציירת שום טופס כניסה. טופס שהמנוע מרכיב תמיד ייראה כמו דף אינטרנט שנפל על משחק פיקסל ארט, וזה יהיה החלק היחיד במשחק שלכם שלא הייתם יכולים לעצב מחדש.

אתם מציירים אותו. החלק היחיד שחייב להגיע מהדפדפן הוא הקלדת טקסט, אז CreateEditBox() נותן לכם שדה קלט אמיתי שאתם ממקמים בעצמכם:

CreateEditBox(1)
EditBoxPosition(1, 20, 42)
EditBoxSize(1, 60, 8)
nom$ = EditBoxText(1)

ההדגמה Player Account ברשימת הדוגמאות של Engine היא מסך עובד שלם בסביבות מאה שורות. פתחו אותה, קראו אותה, ואז החליפו כל Print() באמנות שלכם.

לפני שמשהו מזה עובד#

המשחק חייב להיות מוצהר מהחשבון שלכם ב-Aukimi, תחת My games (aukimi.com/app/games): כותרת, הכתובת שבה אפשר לשחק אותו, והכתובות שהמשחק שלכם רשאי לחזור אליהן. עד אז PlayerAvailable() מחזיר 0, ומשחק טוב אומר "accounts are not available" במקום להיראות כאילו הוא נתקע.

אותו מסך הוא המקום שבו אתם רואים מי משחק. קראו את המספרים כפי שהם: הם סופרים שחקנים שנכנסו וסשנים שהתחילו, אף פעם לא משחקים ששוחקו. משחק שלעולם לא מבקש מאף אחד להיכנס לא מציג שם כלום, והמסך אומר זאת במקום להציג אפס שקט.

שימוש בשרת חשבונות משלכם#

כל מה שלמעלה מדבר עם שירות החשבונות של Aukimi. אם אתם מארחים את המשחק שלכם על שרת משלכם, אותן שתים עשרה פקודות יכולות לדבר עם השירות שלכם במקום, והסקריפט שלכם לא משתנה בשורה אחת.

ב-Engine: פאנל Multiplayer → מקטע Player accounts → בחרו My own server → מלאו שדה אחד, הכתובת של השרת שלכם. הכתובת הזו היא הגדרה של הסצנה, כך ששני משחקים יכולים להשתמש בשני שירותים שונים.

שתי דרכים להכניס שחקן#

הבחירה נעשית בסקריפט שלכם, לא בהגדרה. שתי הצורות קיימות בכל שרת שאתם מכוונים אליו.

החלון (מה שאתם כבר מכירים)#

job = PlayerLoginAsync()

חלון נפתח, השחקן נכנס שם, והוא מוסר למשחק שלכם את הזכות לפעול בשמו. עם שירות Aukimi החלון הזה הוא play.aukimi.com. עם שרת משלכם, העמוד הזה שלכם לבנות.

ישירות, עם שם משתמש וסיסמה#

job = PlayerLoginAsync(username$, password$)

בלי חלון. המשחק שלכם קורא מה שהשחקן הקליד על המסך שלכם ושולח את זה לשרת שלכם. פשוט יותר לכתוב, וזה נותן לכם לשמור על המראה של המשחק שלכם מקצה לקצה.

אזהרה: בצורה הזו, הסיסמה נוסעת מהמשחק שלכם לשרת שלכם כפי שהוקלדה. שתי השלכות, שתיהן קשיחות: כתובת השרת שלכם חייבת להתחיל ב-https:// (רק בדיקה על המכונה שלכם פטורה), והצורה הזו מיועדת רק לשרת שאתם הבעלים שלו.

play.aukimi.com דוחה אותה, בכוונה. Aukimi אף פעם לא רוצה להיות במצב שבו היא רואה סיסמת שחקן, וגם משחק שלא כתבתם לא צריך.

שתי הבחירות בלתי תלויות בהגדרה: שרת ביתי יכול בהחלט להציע רק את החלון, ולעולם לא לקבל סיסמה ישירות.

דוגמה קונקרטית#

משחק עם מסך "Sign in" משלו: שני שדות טקסט שהמשחק מצייר, כפתור אחד, וזה מאחורי הכפתור.

job = PlayerLoginAsync(typedName$, typedPassword$)
DO
    etat$ = PlatformJobState(job)
    if etat$ = "done"
        PlatformJobRelease(job)
        Print("Welcome " + PlayerName())
    endif
    if etat$ = "error"
        PlatformJobRelease(job)
        Print(PlayerLastError())
    endif
    Sync()
LOOP

הכול אחרי הכניסה זהה לשאר העמוד הזה: PlayerSaveAsync, PlayerLoadAsync, PlayerName והשאר לא יודעים, ולא אכפת להם, איזה שרת ענה.

מה השרת שלכם צריך לענות עליו#

ארבע כתובות נדרשות, איזו כניסה שתציעו:

בשביל מה זהמה המשחק מצפה
שחק כאורחמסור בחזרה חשבון בלי אימייל
מי השחקן הזהשם התצוגה, ה-id, האם הוא אורח
קריאת השמירההנתונים השמורים
כתיבת השמירהשמרו מה שהמשחק שולח

ואז, תלוי מה אתם בוחרים להציע:

  • צורת החלון צריכה עמוד כניסה על השרת שלכם, שאומר למשחק מי נכנס ברגע שזה נגמר.
  • הצורה הישירה צריכה כתובת נוספת אחת, שלוקחת שם משתמש וסיסמה ועונה כן או לא.

הכתובות המדויקות, הצורה של כל תשובה וקודי השגיאה נמצאים במאגר, ב- docs/engine-player-accounts.md. הקובץ ההוא הוא החוזה; העמוד הזה הוא המפה.

הערה: שום דבר מזה לא עובד בייצוא native. הפקודות Player* צריכות שרת לדבר איתו ודפדפן לדבר דרכו, ולבנייה native אין אף אחד משניהם.

הפקודות#

פקודהמה היא עושה
PlayerAvailable()האם שירות החשבונות מוגדר למשחק הזה
PlayerLoginAsync()פותח את חלון הכניסה. מחזיר job
PlayerLoginAsync(user, pass)נכנס ישירות, רק על שרת משלכם. מחזיר job
PlayerGuestAsync()יוצר חשבון בלי אימייל. מחזיר job
PlayerLoggedIn()האם מישהו נכנס כרגע
PlayerName()שם התצוגה שלו
PlayerID()ה-id האטום שלו, ספציפי למשחק הזה
PlayerIsGuest()האם זה חשבון בלי אימייל
PlayerSaveAsync()כותב את השמירה. מחזיר job
PlayerLoadAsync()קורא אותה חזרה. מחזיר job
PlayerRefreshAsync()מחדש את הטוקן לפני שהוא פג
PlayerLogout()מנתק על המכשיר הזה
PlayerLastError()למה הקריאה האחרונה נכשלה