Spiel mit mir

Mobile Multiplayer Games: ein Erfahrungsbericht

Lars Röwekamp und Sebastian Szczygiel

Vor wenigen Jahren aufgrund mangelnder Bandbreite noch nahezu undenkbar, halten heute mehr und mehr Multiplayer Games auf den Handys Einzug. Die mit dem Online Gaming verbundenen Probleme und insbesondere die zur Spielabwicklung notwendige Kommunikation mit einem Gaming Server stellt die Gemeinde der Mobile Game Developer vor neue Herausforderungen, wie der vorliegende Erfahrungsbericht zeigt.

p>Spiele sind seit jeher die Vorreiter, wenn es um das Austesten technischer Grenzen im mobilen Umfeld – also unter anderem in der Welt der Handys – geht. Während es vor wenigen Jahren den Anwendern noch genügte, kleine sich stetig selbst verlängernde Würmer in Monochromdarstellung, unterstützt durch ein primitives Piepen, über das Display zu lotsen, sind heute aufwendige, multimediale und, wenn möglich, dreidimensionale Spiele beinahe Pflichtprogramm.
Eine besondere Rolle spielen dabei so genannte Multiplayer Games, welche es den Handy-Kontrahenten ermöglichen, in einem zum Teil simulierten Echtzeitszenario gegeneinander ihre Kräfte und ihr Geschick zu messen. Wie auf der Exit-Game-Area-Homepage beschrieben, existieren dabei die unterschiedlichsten Spielvarianten und Kommunikationsmöglichkeiten.

Im Folgenden sollen anhand eines Erfahrungsberichtes die wesentlichen Aspekte und Stolpersteine der Konzeption und Entwicklung derartiger Mobile Multiplayer Games dargestellt werden. Im Vordergrund stehen dabei weniger die Problemfelder der Game-Entwicklung als solche, als vielmehr die sich durch den Anspruch des Online Gaming ergebenen zusätzlichen Herausforderungen. Zur besseren Veranschaulichung werden zwei vom Aufbau und Ablauf her relativ einfache Spielklassiker – Seabattle (Schiffe versenken) und Black Jack – in ihrer Multiplayer-Variante vorgestellt. Bei beiden Spielen handelt es sich um „turn-based“ – also zugbasierte – Spiele, bei denen die Vermittlung zwischen den einzelnen Spielern und die Koordination der Kommunikation über einen zentralen Gaming Server realisiert werden.

Als Gaming Server wurde eine Lösung des internationalen Multiplayer Service Provider Exit Games namens Neutron-Plattform verwendet. Die beschriebene Funktionalität kann aber in ähnlicher Art und Weise auch bei anderen Gaming-Servern gefunden werden (siehe Kasten „Gaming Server“). Die beiden vorgestellten Spiele können in der Exit Game Area kostenlos zum Ausprobieren heruntergeladen werden.

Aufbau und Kommunikation

Moderne Multiplayer Games leben davon, dass sie deutlich mehr bieten als lediglich die Möglichkeit, gegen einen anderen Spieler anzutreten. So sind erweiterte Features wie Turnier-Modus, Multi-Session Games, nationale und internationale Highscores und die Verwaltung von Buddy-Listen heutzutage ebenso normal wie die Möglichkeit zur direkten Auswahl eines Gegners. Ermöglicht wird dies durch entsprechende Unterstützung seitens des angebundenen Gaming Server. Dieser bietet darüber hinaus in der Regel noch einiges mehr an Funktionalität, so zum Beispiel eine Unterstützung des Billing.

Entwickler von Multiplayer Games sollten bei der Auswahl des Serveranbieters ein besonderes Augenmerk auf die Unterstützung der folgenden Aspekte legen, um Spiele am Markt gewinnbringend platzieren zu können:

  • Authentifizierungsmechanismen
  • Öffentliche und private Spiele
  • Kommunikation (SMS, Chat …)
  • netzbetreiberabhängige und -unabhängige Billing-Mechanismen
  • Optimierte Transportprotokolle
  • Administration (Games, User, Debugging)
  • Blueprints, Demos, Whitepaper

Wichtig ist darüber hinaus die API-Unterstützung der Serverhersteller bezüglich der Anbindung der Applikation an den jeweiligen Server. So sollte zum einen das API nicht zu groß sein und, wenn möglich, für die jeweiligen Spiele bezüglich ihrer Größe angepasst werden können. Darüber hinaus sollte die gesamte Kommunikation (Socket und/oder HTTP) durch das Client API gekapselt werden. Im Falle der in diesem Beispiel verwendeten Lösung Neutron von Exit Games geht das Server API sogar so weit, dass bestimme Besonderheiten des Operators – und von denen gibt es leider mehr als genug – wie zum Beispiel das Billing für den Entwickler transparent gehalten werden.

Natürlich schadet auch eine Unterstützung seitens des Serverherstellers bei der Gestaltung der Games sowie der Einhaltung von Usability-Richtlinien nicht. Zu diesem Zweck bietet zum Beispiel Exit Games eine Art Blueprint für Turn-based Games an, welches unter anderem einen möglichen Spielaufbau als Template vorgibt (Abb. 1). Beide in diesem Artikel verwendeten Beispiele halten sich im Aufbau weitestgehend an diese Vorgabe.

Abb. 1: Turn-based Game Template – Exit Games

Seabattle: Möge die Seeschlacht beginnen

Wie bereits erwähnt, handelt es sich bei Seabattle um die mobile Multiplayer-Variante des Spielklassikers „Schiffe versenken“. Die Anzahl der gleichzeitigen Gegner ist auf zwei Spieler begrenzt. Ziel des Spiels ist es – wie jedem bekannt sein dürfte –, zunächst seine eigenen Schiffe möglichst geschickt auf einem für den Gegner nicht einsehbaren Spielfeld zu platzieren, um im Anschluss Zug für Zug die Position der gegnerischen Schiffe auf dem Feld ausfindig zu machen und diese zu zerstören. Das Spiel verfügt sowohl über einen Offline-Modus (Spieler vs. Computer/Handy) als auch über eine entsprechende Online-Variante, welche das Spielen gegen reale Gegner erlaubt.

Abb. 2: Menüstruktur

Bevor ein Spieler zum ersten Mal ein Seabattle starten kann, muss er sich auf dem Gaming Server registrieren (Abb. 2). Im Falle der genutzten Neutron-Plattform geschieht dies mithilfe eines Benutzernamens sowie eines zugehörigen Passwortes. Der Zugriff auf die Funktionalität des Servers wird dabei mittels einer Klasse namens NeutronSession gekapselt. Sowohl die Registrierung als auch ein späteres Einloggen verwenden die Methode login. Welche Aktion tatsächlich ausgeführt wurde, lässt sich anhand des serverseitigen Return Code erkennen.

...
NeutronSession neutronSesssion = new NeutronSession(...); 
neutronSession.login(username, password);
doWaitAnimation(); 
...

Wie Listing 1 zeigt, existiert zu jedem Server Request eine zugehörige Callback-Methode, welche durch den Spielentwickler ausimplementiert werden muss. Diese Methode wird beim Eintreffen der Response automatisch angesprungen. Je nach Request kann die Response neben dem eigentlichen Return Code noch andere Payload-Informationen enthalten.

Listing 1
------------------------------
/**
  * Callback for login method.
  * @param returnCode Server sided return code
  */
public void loginReturn(int returnCode) {
    waiting = false;       //stop doWaitAnimation
    switch ( returnCode ) {
        case RC_OK:
            // register includes a login 
            // getting scores afterwards if RC_OK is returned
            setInfoScreen(you are logged in - enjoy the game);
            break;
        case RC_NETWORK_SETUP_ERROR:
            setInfoScreen("login not possible ("+returnCode+").");
            if ( neutronSession.firstConnect ) 
               append("nYou never had a successful connection - check phone settings.");
            break; 
        case RC_NETWORK_SECURITY_ERROR:
            setInfoScreen("To use highscore-features, you need to allow network access!");
            break;
        case RC_NOT_REGISTERED:
            //login error: user can register now - user is not known
            setRegisterScreen();
            break;
        case RC_WRONG_PASSWORD:
            //login error: user is known, but password is wrong - retry
            setInfoScreen("WRONG PASSWORD - RETRY");
            break;
        case RC_USERNAME_INCORRECT:
            //register error: username not allowed (see restrictions)
            setInfoScreen("Username not usable.");
            break;
        case RC_PASSWORD_INCORRECT:
            //register error: password not allowed (see restrictions)
            setInfoScreen("Password not usable.");
            break;
        default:
            //login or register: any other error-code (this is a demo only)
            setInfoScreen("NeutronException: "+returnCode);
            break;
    }

    /allow retry / new login in case of errors
    if ( returnCode != RC_OK ) addCommand(cmdRetry);

In unserem Beispiel liefert der Server nach gelungener Registrierung den Return Code RC_OK. Der Entwickler hat somit nichts weiter zu tun, als den weiteren Spielverlauf an dieser Stelle der Callback-Methode loginReturn anzustoßen.

Einmal registriert, ist der Spieler Teil der Community und kann sich beim nächsten Aufruf des Spiels über seine Login-Daten auf dem Server authentifizieren. Nach erfolgreichem Login wird dem Client vom Server eine eindeutige Session-ID zugewiesen. Für alle weiteren Requests muss der Client die Session-ID mit übertragen, um so auf Seiten des Game Server eine eindeutige Zuordnung zum Spieler und seinem aktuellen Spiel zu ermöglichen.

Wer spielen will, darf zahlen

Je nachdem, zu welchen Konditionen das Spiel erworben wurde, kann es sein, dass nach dem Login der Anwender zur Zahlung eines Abos aufgefordert wird, um die Multiplayer-Funktionalität nutzen zu können. Für die Abbrechung der Abos hat Exit Games bereits einige Operator-abhängige und unabhängige (Premium SMS) Billing-Mechanismen in die Neutron-Plattform integriert, auf die auch die Spielentwickler zugreifen können.

Über die Weboberfläche, das Neutron Control Center, können Spielern mehrere Abo-Pakete von Spielen zugewiesen werden. Der Abruf der Abo-Pakete vom Server läuft über getPackages. Sobald sich der Anwender für ein Abo entschieden hat (z.B. „30 Tage für 2,99 Euro“) kann dieses über reSubscribe aktiviert werden. Um beim Abruf der Abo-Pakete unnötigen Traffic zu vermeiden, kann angegeben werden, welche Daten übertragen werden sollen. Zusätzlich lässt sich deren landesspezifische Formatierung für die Ausgabe auf dem mobilen Endgerät bestimmen (Listing 2).

Listing 2
--------------------------------------
...
/* interesting values: ID, Billingcode 
 and "Time of duration, Price, Description" -second parameter sets language
*/
neutronSession.getPackages( "{i}$${b}$${t} {p:0.00} {d}", "en-" );

...

//as selected in the list of possible packages (see getPackagesReturn() for more)
neutronSession.reSubscribe( packages[packageIndex*3+0] , packages[packageIndex*3+1] );

...

public void resubscribeReturn( int returnCode ) {
    waiting = false;     // stop doWaitAnimation       
        
    //in this case only two states are checked: "RC_OK" or "any other"
    switch ( returnCode ) {
        case RC_OK: 
            setInfoScreen("You successfully resubscribed! Go to login now.");
            break;
        case RC_BILLING_UNAUTHORIZED:
            setInfoScreen("Failure! Can't identify this SIM-card!nPlease make sure this MSISDN is allowed to be billed.");
            break;
        default:
        
    }        
    addCommand( cmdRetry );
}
Geschrieben von
Lars Röwekamp und Sebastian Szczygiel
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.