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 SieDas 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.com lehnt 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 istWas das Spiel erwartet
Als Gast spielenEin Konto ohne E-Mail zurückgeben
Wer ist dieser SpielerDer Anzeigename, die id, ob er ein Gast ist
Den Spielstand lesenDie gespeicherten Daten
Den Spielstand schreibenSpeichern, 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#

BefehlWas 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