Spielerkonten
Geben Sie den Spielern Ihres Spiels ein Konto, das sie über jedes Aukimi-Spiel hinweg behalten, mit Spielständen, die ihnen von einem Gerät zum nächsten folgen, auf Aukimis Dienst oder auf einem eigenen Server.
In einem Satz#
Ein Spieler meldet sich einmal auf play.aukimi.com an und findet dieses Konto in jedem mit Aukimi gemachten Spiel wieder, Spielstände inklusive. Ihr Spiel fragt nach dem Konto; es bekommt das Passwort nie zu sehen.
Warum Ihr Spiel das Passwort nie sieht#
Jeder kann ein Spiel veröffentlichen. Ein Spiel, das nach einem Aukimi-Passwort fragt, wäre eine vollkommen überzeugende Phishing-Seite, und noch so gute Absichten Ihrerseits würden nichts daran ändern, was ein anderer Entwickler ausliefern könnte.
Deshalb wird das Passwort auf play.aukimi.com eingetippt und nirgendwo
sonst. Ihr Spiel ruft PlayerLoginAsync() auf, ein Browserfenster öffnet sich
in Aukimis eigenen Farben, der Spieler stimmt zu, und das Fenster übergibt
Ihrem Spiel ein Token.
Dieses Token wird nur für Ihr Spiel ausgestellt. Ein Token für Spiel A, das Spiel B vorgelegt wird, wird abgelehnt, nicht ignoriert, abgelehnt. Das ist der Punkt: Das Konto wird zwischen Spielen geteilt, der Zugriff nicht. Ohne das könnte ein bösartiges Spiel die Spielstände eines Spielers in allen anderen lesen.
Was Sie über einen Spieler erfahren#
Zwei Dinge, nicht mehr:
| Das bekommen Sie | Das bekommen Sie nie |
|---|---|
Einen Anzeigenamen (PlayerName()) | Die E-Mail-Adresse |
Eine opake id, in jedem Spiel unterschiedlich (PlayerID()) | Irgendetwas, das sie anderswo identifiziert |
Die id wechselt absichtlich von einem Spiel zum nächsten. Zwei Entwickler, die ihre Spielerlisten vergleichen, können nicht erkennen, dass sie dieselbe Person vor sich haben. Das macht Sie außerdem zu einem Auftragsverarbeiter statt zu einem Verantwortlichen dieser Daten, eine rechtliche Unterscheidung, keine dekorative.
Nichts blockiert die Spielschleife#
Jeder Befehl, der mit dem Netzwerk spricht, gibt eine Job-Nummer zurück, nie ein Ergebnis. Ihre Schleife läuft mit sechzig Bildern pro Sekunde weiter, während die Anfrage unterwegs ist, das ist der ganze Grund, warum ein Spiel nicht einfach „auf den Server warten" kann.
job = PlayerLoginAsync()
Dann, einmal pro Frame:
etat$ = PlatformJobState(job)
if etat$ = "done"
resultat$ = PlatformJobResult(job)
PlatformJobRelease(job)
endif
if etat$ = "error"
Print(PlatformJobError(job))
PlatformJobRelease(job)
endif
Geben Sie den Job frei, sobald Sie ihn gelesen haben. Ein Job, den Sie nie freigeben, behält sein Ergebnis für den Rest der Sitzung im Speicher. Nichts bricht, nichts warnt Sie, und das Leck zeigt sich erst in einer langen Spielsitzung.
Spielen ohne Konto#
Nicht jeder will sich anmelden, bevor er ein Spiel ausprobiert.
PlayerGuestAsync(name$) erstellt ein Konto ohne E-Mail, das in diesem
Browser bleibt.
Es ist ein echtes Konto: Es speichert, es lädt, und es kann später beansprucht werden, der Spieler fügt eine E-Mail und ein Passwort hinzu, und die bestehenden Spielstände folgen, ohne sich zu bewegen.
Der ehrliche Haken: Das Löschen der Website-Daten des Browsers verliert
dieses Konto, und es gibt keine Möglichkeit, es wiederherzustellen. Das ist
der Preis für „keine Anmeldung", und Ihr Spiel sollte das sagen, statt es den
Spieler herausfinden zu lassen. PlayerIsGuest() ist genau für diesen Satz
da.
Speichern#
job = PlayerSaveAsync(donnees$)
job = PlayerLoadAsync()
Der Spielstand ist JSON in Ihrer eigenen Form, gespeichert gegen das Paar (dieser Spieler, dieses Spiel). Er folgt ihnen zu einem anderen Browser, einer anderen Maschine, einer anderen Plattform.
Für eine Handvoll Werte sind SetCloudDataVariable() und
CloudDataVariable() einfacher, kein Job, kein JSON. Prüfen Sie zuerst
CloudDataAllowed(): Es liefert 0, wenn kein Spieler angemeldet ist, und ein
Schreibversuch würde trotzdem stillschweigend ins Leere gehen.
Den Bildschirm zeichnen#
aukimi zeichnet kein Anmeldeformular. Ein von der Engine zusammengesetztes Formular würde immer wie eine Webseite aussehen, die auf ein Pixel-Art-Spiel fällt, und es wäre der eine Teil Ihres Spiels, den Sie nicht umgestalten könnten.
Sie zeichnen es. Das einzige Stück, das vom Browser kommen muss, ist die
Texteingabe, deshalb gibt Ihnen CreateEditBox() ein echtes Eingabefeld, das
Sie selbst positionieren:
CreateEditBox(1)
EditBoxPosition(1, 20, 42)
EditBoxSize(1, 60, 8)
nom$ = EditBoxText(1)
Die Demo Player Account in der Beispielliste der Engine ist ein
vollständig funktionierender Bildschirm in etwa hundert Zeilen. Öffnen Sie
sie, lesen Sie sie, und ersetzen Sie dann jedes Print() durch Ihre eigene
Grafik.
Bevor irgendetwas davon funktioniert#
Das Spiel muss von Ihrem Aukimi-Konto aus deklariert werden, unter
My games (aukimi.com/app/games): ein Titel, die Adresse, unter der es
gespielt werden kann, und die Adressen, zu denen Ihr Spiel zurückkehren darf.
Bis dahin gibt PlayerAvailable() 0 zurück, und ein gutes Spiel sagt
„Konten sind nicht verfügbar", statt so zu wirken, als würde es hängen.
Auf demselben Bildschirm sehen Sie, wer spielt. Lesen Sie die Zahlen für das, was sie sind: Er zählt angemeldete Spieler und gestartete Sessions, nie gespielte Spiele. Ein Spiel, das nie jemanden zur Anmeldung auffordert, zeigt dort nichts, und der Bildschirm sagt das, statt eine stille Null zu zeigen.
Einen eigenen Kontoserver verwenden#
Alles oben spricht mit Aukimis Kontodienst. Wenn Sie Ihr Spiel auf Ihrem eigenen Server hosten, können dieselben zwölf Befehle stattdessen mit Ihrem Dienst sprechen, und Ihr Skript ändert sich um keine einzige Zeile.
In der Engine: Panel Multiplayer → Abschnitt Player accounts → wählen Sie My own server → füllen Sie ein Feld aus, die Adresse Ihres Servers. Diese Adresse ist eine Einstellung der Szene, sodass zwei Spiele zwei unterschiedliche Dienste verwenden können.
Zwei Wege, einen Spieler anzumelden#
Die Wahl wird in Ihrem Skript getroffen, nicht in einer Einstellung. Beide Formen existieren, egal auf welchen Server Sie zeigen.
Das Fenster (was Sie schon kennen)#
job = PlayerLoginAsync()
Ein Fenster öffnet sich, der Spieler meldet sich dort an, und es gibt Ihrem
Spiel das Recht zurück, in seinem Namen zu handeln. Mit Aukimis Dienst ist
dieses Fenster play.aukimi.com. Mit Ihrem eigenen Server ist diese Seite
Ihre eigene, zu bauen.
Direkt, mit Benutzername und Passwort#
job = PlayerLoginAsync(username$, password$)
Kein Fenster. Ihr Spiel liest, was der Spieler auf Ihrem eigenen Bildschirm eingetippt hat, und schickt es an Ihren Server. Einfacher zu schreiben, und es lässt Sie den Look Ihres Spiels von Anfang bis Ende behalten.
Warnung: In dieser Form reist das Passwort so eingetippt von Ihrem Spiel zu Ihrem Server. Zwei Konsequenzen, beide fest: Die Adresse Ihres Servers muss mit
https://beginnen (nur ein Test auf der eigenen Maschine ist davon ausgenommen), und diese Form ist ausschließlich für einen Server gedacht, den Sie besitzen.
play.aukimi.comlehnt sie absichtlich ab. Aukimi will nie in der Lage sein, das Passwort eines Spielers zu sehen, und ein Spiel, das Sie nicht geschrieben haben, sollte das auch nicht.
Die beiden Möglichkeiten sind unabhängig von der Einstellung: Ein selbstgebauter Server kann durchaus nur das Fenster anbieten und nie direkt ein Passwort entgegennehmen.
Ein konkretes Beispiel#
Ein Spiel mit einem eigenen „Anmelden"-Bildschirm: zwei vom Spiel gezeichnete Textfelder, ein Button, und das hier hinter dem Button.
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
Alles nach der Anmeldung ist identisch zum Rest dieser Seite:
PlayerSaveAsync, PlayerLoadAsync, PlayerName und die anderen wissen
nicht, und kümmert es nicht, welcher Server geantwortet hat.
Was Ihr Server beantworten muss#
Vier Adressen sind erforderlich, egal welche Anmeldung Sie anbieten:
| Wofür es ist | Was das Spiel erwartet |
|---|---|
| Als Gast spielen | Ein Konto ohne E-Mail zurückgeben |
| Wer ist dieser Spieler | Der Anzeigename, die id, ob er ein Gast ist |
| Den Spielstand lesen | Die gespeicherten Daten |
| Den Spielstand schreiben | Speichern, was das Spiel sendet |
Dann, je nachdem, was Sie anbieten möchten:
- Die Fenster-Form braucht eine Anmeldeseite auf Ihrem Server, die dem Spiel mitteilt, wer sich angemeldet hat, sobald es fertig ist.
- Die direkte Form braucht eine weitere Adresse, die einen Benutzernamen und ein Passwort entgegennimmt und mit Ja oder Nein antwortet.
Die genauen Adressen, die Form jeder Antwort und die Fehlercodes stehen im
Repository, in docs/engine-player-accounts.md. Diese Datei ist der
Vertrag; diese Seite ist die Karte.
Hinweis: Nichts davon funktioniert in einem nativen Export. Die
Player*-Befehle brauchen einen Server, mit dem sie sprechen, und einen Browser, durch den sie sprechen, und ein nativer Build hat keines von beiden.
Die Befehle#
| Befehl | Was er tut |
|---|---|
PlayerAvailable() | Ist der Kontodienst für dieses Spiel konfiguriert |
PlayerLoginAsync() | Öffnet das Anmeldefenster. Gibt einen Job zurück |
PlayerLoginAsync(user, pass) | Meldet direkt an, nur auf Ihrem eigenen Server. Gibt einen Job zurück |
PlayerGuestAsync() | Erstellt ein Konto ohne E-Mail. Gibt einen Job zurück |
PlayerLoggedIn() | Ist gerade jemand angemeldet |
PlayerName() | Sein Anzeigename |
PlayerID() | Seine opake id, spezifisch für dieses Spiel |
PlayerIsGuest() | Ist dies ein Konto ohne E-Mail |
PlayerSaveAsync() | Schreibt den Spielstand. Gibt einen Job zurück |
PlayerLoadAsync() | Liest ihn zurück. Gibt einen Job zurück |
PlayerRefreshAsync() | Erneuert das Token, bevor es abläuft |
PlayerLogout() | Meldet auf diesem Gerät ab |
PlayerLastError() | Warum der letzte Aufruf fehlgeschlagen ist |