XEP-xxxx: Multi-User Gaming

Abstract
This document defines an XMPP protocol extension for multi-user gaming.
Authors
  • Torsten Grote
  • Arne König
  • Günther Nieß
Copyright
© 2008 – 2009 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

ProtoXEP

WARNING: This document has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document is not yet an XMPP Extension Protocol (XEP). If this document is accepted as a XEP by the XMPP Council, it will be published at <https://xmpp.org/extensions/> and announced on the <standards@xmpp.org> mailing list.
Type
Standards Track
Version
0.0.3 (2009-04-20)
Document Lifecycle
  1. Experimental
  2. Proposed
  3. Stable
  4. Final

1. Introduction

Many modern instant messenger networks support playing games. Still, XMPP mostly lacks this kind of support. Therefore, this document (Multi-User Gaming or MUG) describes a base protocol for game playing over XMPP.

This protocol is not by itself sufficient to play games. It just describes a basic protocol framework which game-specific protocols can use.

2. Requirements

This document addresses the functionality which is needed to play multi-user games over XMPP. In particular this functionality consists of:

  1. discovering support for games and of particular games
  2. inviting users to game rooms
  3. discovering and joining existing game rooms
  4. exchanging game information (moves, states, etc.)
  5. saving and loading of matches
  6. terminating games
  7. allow spectators to watch the match
  8. validate game moves

In addition, this document provides protocol elements for supporting the following room types:

  1. moderated or unmoderated
  2. public or hidden
  3. members-only or open
  4. password-protected or unsecured

The following requirements are explicitly not adressed, but might be realized by seperate XEPs.

  1. support for near-realtime games or for games which require low latency
  2. defined timers for each turn
  3. scores and highscores
  4. tournaments

The extensions needed to implement these requirements are qualified by the 'http://jabber.org/protocol/mug' namespace (and the #owner, and #user fragments on the main namespace URI).

3. Terminology

3.1 General Terms

Game -- a XEP which defines the rules of a match

Initiator -- the entity that started a game.

Match -- represents a specific instance of a game played in a room.

Member -- a user with an affiliation of type "member" in the context of member-only games.

Owner -- a priviledged entity that owns a game.

Player -- a user in a match who has a defined game role

Role -- role in the game (e.g. 'black' and 'white' in chess)

Room -- a game room in which matches are played

Room JID -- the <room@service/nick> by which an occupant is identified within the context of a match; contrast with Bare JID and Full JID.

Spectator -- an entity who does not actually plays the game but watches it.

Occupant -- a player or spectator who is currently in the match.

3.2 Room Types

Unmoderated Room -- The owner has limited rights. The match cannot be saved; antonym: Moderated Room.

Moderated Room -- The owner is allowed to kick users, revoke roles and save the match; antonym: Unmoderated Room.

Hidden Room -- a room that cannot be found by any user through normal means such as searching and service discovery; antonym: Public Room.

Public Room -- a room that can be found by any user through normal means such as searching and service discovery; antonym: Hidden Room.

Members-Only Room -- a room that a user cannot enter without being on the member list; antonym: Open Room.

Open Room -- a room that anyone may enter without being on the member list; antonym: Members-Only Room.

Password-Protected Room -- a room that a user cannot enter without first providing the correct password; antonym: Unsecured Room.

Unsecured Room -- a room that anyone is allowed to enter without first providing the correct password; antonym: Password-Protected Room.

Fully-Anonymous Room -- a room in which the full JIDs or bare JIDs of occupants cannot be discovered by anyone, including the room owner; contrast with Non-Anonymous Room and Semi-Anonymous Room.

Semi-Anonymous Room -- a room in which an occupant's full JID can be discovered by the room owner only; contrast with Fully-Anonymous Room and Non-Anonymous Room.

Non-Anonymous Room -- a room in which an occupant's full JID is exposed to all other occupants; contrast with Semi-Anonymous Room and Fully-Anonymous Room.

3.3 Room Status

active -- room that is currently in use

adjourned -- 'saved' room

3.4 Match Status

There are three different match status:

created -- before the initial room configuration is done

inactive -- before and after a match, turns are not possible, options can be changed

active -- within a match, turns are possible, options cannot be changed

paused -- halted within a match, turns are not possible, options cannot be changed

3.5 Dramatis Personae

Most of the examples in this document use the scenario of Miranda and Ferdinand playing chess in Act V, Scene I of Shakespeare's The Tempest, represented here as the "island-chess@games.shakespeare.lit" room. The characters are as follows:

Table 1: Dramatis Personae
Room NicknameFull JIDAffiliationGame Role
damselmiranda@shakespeare.lit/desktopOwnerWhite
ladferdinand@shakespeare.lit/laptopNoneBlack
KingOfNaplesalonso@shakespeare.lit/pdaNoneNone
prosperoprospero@shakespeare.lit/cellNoneNone

4. Affiliations

The following affiliations are defined:

  1. Member
  2. Owner
  3. None (the absence of an affiliation)

Support for the all affiliations is REQUIRED. (The "None" affiliation is the absence of an affiliation.)

If a user without a defined affiliation enters a match, the user's affiliation is defined as "None".

The member affiliation provides a way for room owners to specify a "whitelist" of users who are allowed to enter a members-only match. When a member enters a members-only match, his or her affiliation does not change.

Information about affiliations MUST be sent in all presence stanzas generated or reflected by the match and sent to occupants.

4.1 Privileges

Owners are allowed to do what they like (saving/loading, change match options, etc.) except in unmoderated matches. This match type restricts the use of owner privileges to specific room statuses. Users with no affiliation SHALL NOT enter members-only matches. Besides that, these users have the same privileges as members.

Table 2: Owner Privileges Overview
Room Type Configure Save/Load Grant Member Revoke Member Assign Role Revoke Role
moderated match inactive all status all status all status all status all status
unmoderated match inactive inactive all status inactive inactive and paused inactive and paused

4.2 Changing Affiliations

The ways in which a user's affiliation changes are well-defined. Sometimes the change results from the user's own action (e.g., registering as a member of the match), whereas sometimes the change results from an action taken by an owner. If a user's affiliation changes, a MUG service implementation MUST change the user's affiliation to reflect the change and communicate that to all occupants.

5. Entity Use Cases

A MUG implementation MUST support Service Discovery (XEP-0030) [1], Service Discovery Extensions (XEP-0128) [2] and Jabber Search (XEP-0055) [3].

5.1 Discovering MUG Component Support

A Jabber entity may wish to discover if a service implements the Multi-User Game protocol; in order to do so, it sends a service discovery information ("disco#info") query to the service's JID:

Example 1. Client Queries Gaming Service for MUG Support via Disco
<iq from='alonso@shakespeare.lit/pda'
    id='disco1'
    to='games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
		

The service MUST return its identity and the features it supports:

Example 2. Service Returns Disco Info Results
<iq from='games.shakespeare.lit'
    id='disco1'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='game'
        name='Shakespeare Gaming Service'
        type='multi-user'/>
    <feature var='jabber:iq:search'/>
    <feature var='http://jabber.org/protocol/mug'/>
    <feature var='http://jabber.org/protocol/mug/chess'/>
    <feature var='http://jabber.org/protocol/mug/poker'/>
    <feature var='http://jabber.org/protocol/mug/maumau'/>
  </query>
</iq>
		

5.2 Discovering Active Rooms

The service discovery items ("disco#items") protocol enables a user to query a service for a list of associated items, which in the case of a game service would consist of the active game rooms hosted by the service.

Example 3. User Queries for Active Rooms
<iq from='alonso@shakespeare.lit/pda'
    id='disco2'
    to='games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
		

The service SHOULD return a full list of the active and public rooms it hosts.

Example 4. Service Returns Disco Item Results
<iq from='games.shakespeare.lit'
    id='disco2'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='chess@games.shakespeare.lit'
          name='The Game of Kings'/>
    <item jid='island-chess@games.shakespeare.lit'
          name='A lovers match'/>
    <item jid='maumau@games.shakespeare.lit'
          name='Public Mau Mau Match'/>
    <item jid='poker@games.shakespeare.lit'
          name='Poker'/>
  </query>
</iq>
		

If the full list of rooms is large (see Service Discovery (XEP-0030) [1] for details), the service MAY return only a partial list of rooms. If it does so, it SHOULD include a <set/> element (as defined in Result Set Management (XEP-0059) [4]) to indicate that the list is not the full result set.

5.3 Search for Rooms

It is RECOMMENDED that a user uses Jabber Search (XEP-0055) [3] to search for active or adjourned rooms. At first the user needs to discover what search fields are supported by the service:

Example 5. Client Requests Search Fields from Service
<iq type='get'
    from='prospero@shakespeare.lit/cell'
    to='games.shakespeare.lit'
    id='search1'
    xml:lang='en'>
  <query xmlns='jabber:iq:search'/>
</iq>
		

The service MUST then return the possible search fields to the user, and MAY include instructions:

Example 6. Service Returns Search Form to Client
<iq type='result'
    from='games.shakespeare.lit'
    to='prospero@shakespeare.lit/cell'
    id='search1'
    xml:lang='en'>
  <query xmlns='jabber:iq:search'>
    <instructions>
      Use the enclosed form to search. If your Jabber client does not
      support Data Forms, visit http://web.games.shakespeare.lit/
    </instructions>
    <x xmlns='jabber:x:data' type='form'>
      <title>Room Search</title>
      <instructions>
        Please provide the following information
        to search for active or adjourned matches.
      </instructions>
      <field type='hidden'
             var='FORM_TYPE'>
        <value>jabber:iq:search</value>
      </field>
      <field type='text-single'
             label='Room Name'
             var='mug#roomsearch_name'/>
      <field type='boolean'
             label='Saved Rooms'
             var='mug#roomsearch_saved'/>
      <field type='list-single'
             label='Free Game Roles'
             var='mug#roomsearch_roles'>
        <option label='1'><value>1</value></option>
        <option label='2'><value>2</value></option>
        <option label='3'><value>3</value></option>
        <option label='4'><value>4</value></option>
        <option label='5'><value>5</value></option>
      </field>
      <field type='list-single'
             label='Maximum Number of Occupants'
             var='mug#roomsearch_max_occupants'>
        <option label='1'><value>2</value></option>
        <option label='2'><value>3</value></option>
        <option label='3'><value>4</value></option>
        <option label='4'><value>5</value></option>
        <option label='5'><value>10</value></option>
        <option label='5'><value>20</value></option>
      </field>
      <field type='list-single'
             label='Game Category'
             var='mug#roomsearch_category'>
        <option label='Board Games'><value>board</value></option>
        <option label='Card Games'><value>cards</value></option>
      </field>
      <field type='list-multi'
             label='Games'
             var='mug#roomsearch_game'>
        <option label='Chess'><value>http://jabber.org/protocol/mug#chess</value></option>
        <option label='Tic-Tac-Toe'><value>http://jabber.org/protocol/mug#tictactoe</value></option>
      </field>
    </x>
  </query>
</iq>
		

The Saved Room option allows to search for active or adjourned rooms (see Room Status). The Game Category field is to classify the game and to be able to only search for certain types of games. Every game protocol MUST define its category in the corresponding game XEP.

After having received the possible search fields, the user MAY then submit a search request, specifying values for any desired fields:

Example 7. User Submits Search Form
<iq type='set'
    from='prospero@shakespeare.lit/cell'
    to='games.shakespeare.lit'
    id='search2'
    xml:lang='en'>
  <query xmlns='jabber:iq:search'>
    <x xmlns='jabber:x:data' type='submit'>
      <field type='hidden' var='FORM_TYPE'>
        <value>jabber:iq:search</value>
      </field>
      <field var='status'>
        <value>active</value>
      </field>
      <field var='game'>
        <value>http://jabber.org/protocol/mug/chess</value>
      </field>
    </x>
  </query>
</iq>
		

The submitting entity MAY submit the 'category' or 'game' field but MUST NOT submit both. Sending an empty form adds up to searching for all games.

The service SHOULD then return a list of search results that match the values provided:

Example 8. Service Returns Search Results
<iq type='result'
    from='games.shakespeare.lit'
    to='prospero@shakespeare.lit/cell'
    id='search2'
    xml:lang='en'>
  <query xmlns='jabber:iq:search'>
    <x xmlns='jabber:x:data' type='result'>
      <field type='hidden' var='FORM_TYPE'>
        <value>jabber:iq:search</value>
      </field>
      <reported>
        <field var='status' label='Match Status' type='list-single'/>
        <field var='category' label='Game Category' type='list-single'/>
        <field var='game' label='Game NS' type='text-single'/>
        <field var='jid' label='Jabber ID' type='jid-single'/>
      </reported>
      <item>
        <field var='status'><value>active</value></field>
        <field var='category'><value>board</value></field>
        <field var='game'><value>http://jabber.org/protocol/mug/chess</value></field>
        <field var='jid'><value>island-chess@games.shakespeare.lit</value></field>
      </item>
      ...
    </x>
  </query>
</iq>
		

If the full list of rooms is large, the service MAY return only a partial list of rooms. If it does so, it SHOULD include a <set/> element (as defined in Result Set Management (XEP-0059) [4]) to indicate that the list is not the full result set.

5.4 Querying for Room Information

Using the disco#info protocol, a user may also query a specific room for more detailed information about the room. A user MAY do so before entering a room in order to discover the room configuration.

Example 9. Discovering Game Options of an Active Room
<iq from='alonso@shakespeare.lit/pda'
    id='disco3'
    to='island-chess@games.shakespeare.lit'>
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
		

The room then MUST return its identity and the features it supports.

Example 10. Room Returns Extended Disco Info Results
<iq from='island-chess@games.shakespeare.lit'
    id='disco3'
    to='alonso@shakespeare.lit/pda'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <feature var='http://jabber.org/protocol/mug'/>
    <feature var='http://jabber.org/protocol/mug/chess'/>
    <feature var='mug_passwordprotected'/>
    <feature var='mug_open'/>
    <feature var='mug_moderated'/>
    <feature var='mug_public'/>
    <feature var='mug_semianonymous'/>
    <x xmlns='jabber:x:data' type='result'>
      <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/mug#matchinfo</value>
      </field>
      <field var='mug#game' type='hidden'>
        <value>http://jabber.org/protocol/mug/chess</value>
      </field>
      <field var='mug#match_description' label='Description'>
        <value>A lovers match</value>
      </field>
      <field var='mug#match_occupants' label='Number of Occupants'>
        <value>2</value>
      </field>
      <field var='mug#match_players' label='Number of Players'>
        <value>2</value>
      </field>
      <field var='mug#match_maxoccupants' label='Maximum Number of Occupants'>
        <value>5</value>
      </field>
      <field var='mug#match_chat' label='Communication Ressource'>
        <value>xmpp:island-chess@conference.shakespeare.lit?join</value>
      </field>
    </x>
  </query>
</iq>
		

A room MUST also return more detailed information in its disco#info response using Service Discovery Extensions (XEP-0128) [2], identified by inclusion of a hidden FORM_TYPE field whose value is "http://jabber.org/protocol/mug#matchinfo". It MUST include a 'mug#game' field specifiying the namespace of the game. Optional information MAY include a more verbose description of the room and the current number of occupants and players in the match or 'mug#match_chat' field specifiying a URI for the chat. This is usually a Multi-User Chat (XEP-0045) [5].

See Room Types for details.

5.5 Querying for Room Items

A user MAY also query a specific match for its associated items (occupants):

Example 11. User Queries for Items Associated with a Specific Room
<iq from='alonso@shakespeare.lit/pda'
    id='disco4'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
		

An implementation MAY return a list of existing occupants if that information is publicly available, or return no list at all if this information is kept private.

Example 12. Room Returns Disco Item Results (Items are Public)
<iq from='island-chess@games.shakespeare.lit'
    id='disco4'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='island-chess@games.shakespeare.lit/lad'/>
    <item jid='island-chess@games.shakespeare.lit/damsel'/>
  </query>
</iq>
		

Note: These <item/> elements are qualified by the disco#items namespace, not the mug namespace; this means that they cannot possess 'role' attributes, for example.

Example 13. Room Returns Empty Disco Item Results (Items are Private)
<iq from='island-chess@games.shakespeare.lit'
    id='disco4'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
		

5.6 Querying a Room Occupant

If a non-occupant attempts to send a disco request to an address of the form <room@service/nick>, a MUG service SHOULD return the request to the entity and specify a <bad-request/> error condition. If an occupant sends such a request, the service MAY pass it through the intended recipient.

5.7 Discovering Client Support for MUG

A Jabber user may want to discover if one of the user's contacts supports the Multi-User Game protocol. This is done using Service Discovery.

Example 14. User Queries Contact Regarding MUG Support
<iq from='alonso@shakespeare.lit/pda'
    id='disco5'
    to='ferdinand@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
		

The client SHOULD return its identity and the features it supports:

Example 15. Contact Returns Disco Info Results
<iq from='ferdinand@shakespeare.lit/laptop'
    id='disco5'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='client'
        type='pc'/>
    ...
    <feature var='http://jabber.org/protocol/mug'/>
    <feature var='http://jabber.org/protocol/mug/chess'/>
    ...
  </query>
</iq>
		

A user may also query a contact regarding which room the contact is in. This is done by querying the contact's full JID (<user@host/resource>) while specifying the Service Discovery node 'http://jabber.org/protocol/mug#matches':

Example 16. User Queries Contact for Current Rooms
<iq from='alonso@shakespeare.lit/pda'
    id='matches1'
    to='ferdinand@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/mug#matches'/>
</iq>
		

The requested client MAY list the active rooms as response; see the Implementation Guidelines section of this document for details.

Example 17. Contact Returns Room Query Results
<iq from='ferdinand@shakespeare.lit/laptop'
    id='matches1'
    to='alonso@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/mug#matches'>
    <item jid='island-chess@games.shakespeare.lit'/>
  </query>
</iq>
		

Optionally, the contact MAY include its room nick as the value of the 'name' attribute:

    ...
    <item jid='island-chess@games.shakespeare.lit'
          name='lad'/>
    ...
		

5.8 Announcing a Running Game

The client MAY implement User Gaming (XEP-0196) [6] to announce running games. To publish a running game the user sends:

Example 18. User Publishes Gaming Information
<iq type='set' from='ferdinand@shakespeare.lit/laptop' id='publish1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='urn:xmpp:gaming:0'>
      <item id='1feea9cceec2537e1b561e66d45bc566e276f22f'>
        <game xmlns='urn:xmpp:gaming:0'>
          <name>A lovers match</name>
          <char_name>lad</char_name>
          <server_name>Shakespeare Gaming Service</server_name>
          <server_address>games.shakespeare.lit</server_address>
          <uri>xmpp:island-chess@games.shakespeare.lit?play;game=http://jabber.org/protocol/mug/chess</uri>
        </game>
      </item>
    </publish>
  </pubsub>
</iq>
		

When the user stops playing the game (i.e. leaves the game room), the user's client SHOULD send an empty <game/> element with the same ItemID:

Example 19. User Publishes Gaming Information
<iq type='set' from='ferdinand@shakespeare.lit/laptop' id='publish2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='urn:xmpp:gaming:0'>
      <item id='1feea9cceec2537e1b561e66d45bc566e276f22f'>
        <game xmlns='urn:xmpp:gaming:0'/>
      </item>
    </publish>
  </pubsub>
</iq>
		

6. Occupant Use Cases

6.1 Invitation

It can be useful to invite other users to a room in which one is an occupant. To do this, a MUG client sends XML of the following form to the <room@service> itself adding an <invite/> element for every invitee. (the reason is OPTIONAL and the message MUST be explicitly or implicitly of type "normal"):

Example 20. Occupant Sends an Invitation by Way of Room
<message
    from='ferdinand@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit'>
  <game xmlns='http://jabber.org/protocol/mug#user'>
    <invite to='alonso@shakespeare.lit'>
      <reason>
        Hey Alonso, this is the game of your son!
      </reason>
    </invite>
  </game>
</message>
		

The <room@service> itself MUST then add a 'from' address to the <invite/> element whose value is the room JID of the invitor and send the invitation to the invitee specified in the 'to' address. The room SHOULD add the password if the room is password-protected:

Example 21. Room Sends Invitation to Invitee on Behalf of Invitor
<message
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug#user'>
    <invited
        from='ferdinand@shakespeare.lit/desktop'
        var='http://jabber.org/protocol/mug/chess'>
      <reason>
        Hey Alonso, this is the game of your son!
      </reason>
    </invited>
    <password>cauldronburn</password>
  </game>
</message>
		

If the room is members-only, the service MAY also add the invitee to the member list. If the invitor supplies a non-existent JID, the room SHOULD return an <item-not-found/> error to the invitor. The invitee MAY choose to formally decline (as opposed to ignore) the invitation; and this is something that the sender may want to be informed about. In order to decline the invitation, the invitee MUST send a message of the following form to the <room@service> itself:

Example 22. Invitee Declines Invitation
<message
    from='alonso@shakespeare.lit/pda'
    to='island-chess@games.shakespeare.lit'>
  <game xmlns='http://jabber.org/protocol/mug#user'>
    <decline to='ferdinand@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </decline>
  </game>
</message>
		
Example 23. Room Informs Invitor that Invitation Was Declined
<message
    from='island-chess@games.shakespeare.lit'
    to='ferdinand@shakespeare.lit/Desktop'>
  <game xmlns='http://jabber.org/protocol/mug#user'>
    <declined from='alonso@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </declined>
  </game>
</message>
		

Invitations MAY be based on room JIDs rather than bare JIDs (so that, for example, an occupant could invite someone from one match to another without knowing that person's bare JID). Thus the service MUST handle both the invites and declines.

6.2 Joining a Room

6.2.1 Entering a Room

A User enters a room as follows:

Example 24. Jabber User Seeks to Enter a Room
<presence
    from='alonso@shakespeare.lit/pda'
    to='island-chess@games.shakespeare.lit/KingOfNaples'>
  <game
      xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'/>
</presence>
			

The service MAY assign a free role to the user.

6.2.2 Presence Broadcast

If the service is able to add the user to the room, it MUST send presence from all the existing occupants' room JIDs to the new occupant's full JID, including extended presence information about roles in a <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner", "member", or "none" as appropriate:

Example 25. Service Sends Match State and Presence from Existing Occupants to New Occupant
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>active</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner' role='White'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none' role='Black'/>
  </game>
</presence>
			

The service MUST also send the new occupant's presence to all occupants including the new occupant. If a role was assigned to the new occupant, it MUST be included in the presence in order to notify the new and all other occupants about the new occupant's role.

Example 26. Service Sends New Occupant's Presence to All Occupants
<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none'/>
  </game>
</presence>
			
Example 27. Service Sends New Occupants Presence to New Occupant
<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none'/>
  </game>
</presence>
			

Note: The order of the presence stanzas sent to the new occupant is important. The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant. This helps the client know when it has received the complete "room roster".

6.2.3 Non-Anonymous Rooms

If the room is non-anonymous, the service MUST send the new occupant's full JID to all occupants using extended presence information in an <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing an <item/> child with a 'jid' attribute specifying the occupant's full JID:

Example 28. Service Sends Full JID to all Occupants
<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='miranda@shakespeare.lit/desktop'
  <game xmlns='http://jabber.org/protocol/mug'>
    <item jid='alonso@shakespeare.lit/pda' affiliation='none'/>
  </game>
</presence>

[...]
			

6.2.4 Semi-Anonymous Rooms

If the room is semi-anonymous, the service MUST send presence from the new occupant to all occupants as specified above, but MUST include the new occupant's full JID only in the presence notifications it sends to the room owner and not to any other occupant.

6.2.5 Fully-Anonymous Rooms

If the room is fully-anonymous, the service MUST send presence from the new occupant to all occupants as specified above, but MUST NOT include the new occupant's full JID to any other occupant.

6.2.6 Password-Protected Rooms

If the room requires a password and the user did not supply one (or the password provided is incorrect), the service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning a presence stanza of type "error" specifying a <not-authorized/> error:

Example 29. Service Denies Access Because No Password Provided
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='auth'>
    <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

Passwords SHOULD be supplied with the presence stanza sent when entering the room, contained within an <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing a <password/> child. Passwords are to be sent as cleartext; no other authentication methods are supported at this time, and any such authentication or authorization methods shall be defined in a separate specification (see the Security Considerations section of this document).

Example 30. User Provides Password On Entering a Room
<presence
    from='alonso@shakespeare.lit/pda'
    to='island-chess@games.shakespeare.lit/KingOfNaples'>
  <game
      xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'>
    <password>brave new world</password>
  </game>
</presence>
			

6.2.7 Members-Only Rooms

If the room is members-only but the user is not on the member list, the service MUST deny access to the room and inform the user that they are not allowed to enter the room; this is done by returning a presence stanza of type "error" specifying a <registration-required/> error condition:

Example 31. Service Denies Access Because User Is Not on Member List
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='auth'>
    <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

6.2.8 Nickname Conflict

If the room already contains another user with the nickname desired by the user seeking to enter the room (or if the nickname is reserved by another user on the member list), the service MUST deny access to the room and inform the user of the conflict; this is done by returning a presence stanza of type "error" specifying a <conflict/> error condition:

Example 32. Service Denies Access Because of Nick Conflict
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

However, if the bare JID <user@domain> of the present occupant matches the bare JID of the user seeking to enter the room, then the service SHOULD allow entry to the user, so that the user has two (or more) in-room "sessions" with the same roomnick, one for each resource. If a service allows more than one occupant with the same bare JID and the same room nickname, it SHOULD route in-room messages and presence to all of the user's resources and allow all of the user's resources to send messages to the room; it is up to the implementation to determine how to route private messages to all or only one resource (based on presence priority or some other algorithm).

6.2.9 Max Users

If the room has reached its maximum number of occupants, the service SHOULD deny access to the room and inform the user of the restriction; this is done by returning a presence stanza of type "error" specifying a <service-unavailable/> error condition:

Example 33. Service Informs User that Room Occupant Limit Has Been Reached
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='wait'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

Alternatively, the room could kick an "idle user" in order to free up space.

6.2.10 Locked Room

If a user attempts to enter a room while it is "locked" (i.e., before the room creator provides an initial configuration and therefore before the room officially exists), the service MUST refuse entry and return an <item-not-found/> error to the user:

Example 34. Service Denies Access Because Room Does Not Exist
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

6.2.11 Nonexistent Room

If the room does not already exist when the user seeks to enter it, the service SHOULD create it; however, this is not required, since an implementation or deployment MAY choose to restrict the privilege of creating rooms. For details, see the Creating a Room section of this document.

6.3 Taking a Role

When a user wants to take a free role, he sends the following presence to <room@service>.

Example 35. User Wants To Take a Role
<presence
    from='ferdinand@shakespeare.lit/laptop'
    to='island-chess@games.shakespeare.lit'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item role='Black'/>
  </game>
</presence>
			

After the role has been successfully assigned to the requesting occupant, the service MUST send the new presence to all occupants.

Example 36. Service Sends Changed Occupant's Presence to All Occupant
<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none' role='Black'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none' role='Black'/>
  </game>
</presence>
			
Example 37. Service Sends Changed Occupants Presence Back To Occupant
<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none' role='Black'/>
  </game>
</presence>
			

If the role is already taken, the service must return the following error.

Example 38. Service Informs User About Role Conflict
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
			

If the requested role doesn't exist in the match, the service MUST return a not-acceptable error.

6.4 Game Start

After the match is ready to be started (as to be defined by the game protocol), all players MUST send start messages in order to start the game.

Example 39. Player Send a Start Message
<message
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit'>
  <start xmlns='http://jabber.org/protocol/mug#user'/>
</message>
		

In order to see what players are ready to start, the service MUST reflect the start message from each player to all players.

Example 40. The Service reflects the Start Message
<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'>
  <start xmlns='http://jabber.org/protocol/mug#user'/>
</message>

<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='ferdinand@shakespeare.lit/desktop'>
  <start xmlns='http://jabber.org/protocol/mug#user'/>
</message>
		

If the match is not ready, the service MUST send the following error.

Example 41. Service Informs Player that the Match is Not Ready
<message
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'
    type='error'>
  <start xmlns='http://jabber.org/protocol/mug#user'/>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>
		

After the service received messages from all players, it MUST update the match status from inactive to active by a presence broadcast to all occupants. If the owner changes the configuration or roles change after a player sent his message and before the service sends presence broadcast indicating the game status active, the player MUST send the message again.

Example 42. Service Broadcasts the Start Message to All
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>active</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>active</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>active</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
    </state>
  </game>
</presence>
		

Note that the spectator alonso recieves the start presence, too.

6.5 Game Play

In order to make a move in a match, a <message/> stanza MUST be send to <room@service/nick> containing a <turn/> element qualified by 'http://jabber.org/protocol/mug#user' namespace. Game protocols SHOULD place own elements defining the turn inside the <turn/> element.

Example 43. Occupant Sends a Game Turn
<message
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit'
    type='chat'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
</message>
		

A service MUST validate the player's move before passing it to the occupants. If the turn is invalid, as defined by the game protocol, the service MUST return an error and kick the player unless the player is the owner of the room, in which case he SHOULD lose his game role.

Example 44. Service Informs Player About an Invalid Turn
<message
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'
    type='error'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
  <error type='cancel'>
    <undefined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <invalid-turn xmlns='http://jabber.org/protocol/mug'/>
  </error>
</message>

<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'
    type='unavailable'>
  <invalid-turn xmlns='http://jabber.org/protocol/mug#user'/>
</presence>
		

If a spectator sends a turn the service MUST return the following error.

Example 45. Service Denies Turn
<message
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>
		

If a player sends a turn while the match status is 'inactive' or 'paused' the service MUST send this error:

Example 46. Service Denies Turn Because of Match Status
<message
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit'
    type='error'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>
		

If the move is valid, the service MUST distribute the turn. The occupants, who receive the turn are defined by the game protocol. However, the turn MUST be reflected to the sender.

Example 47. Service Reflects Turn to All Occupants
<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='ferdinand@shakespeare.lit/laptop'
    type='chat'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
</message>

<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='alonso@shakespeare.lit/pda'
    type='chat'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
</message>

<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'
    type='chat'>
  <turn xmlns='http://jabber.org/protocol/mug#user'>
    <play xmlns='http://jabber.org/protocol/mug/chess'
          suit='queen'
          col='d'
          row='2'/>
  </turn>
</message>
		

6.6 Resignation

If a client wants to resign, he sends the following.

Example 48. User resigns
<presence
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit'>
  <game
      xmlns='http://jabber.org/protocol/mug'>
    <item role='none'/>
  </game>
</presence>
		

Afterwards, the service decides whether to cancel or pause the match based on the game specification.

6.7 Termination

The game protocol respectively the game protocol implementation decides when a match is over. In the case of game termination, the service MUST notify every player through updated presence including the resulting final state.

Example 49. Service Sends Termination Broadcast to all Players
<presence
    from='island-chess@games.shakespeare.lit'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <won>Black</won>
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <won>Black</won>
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <won>Black</won>
    </state>
  </game>
</presence>
		

6.8 Changing Nickname

To change his nickname, an occupant sends the following presence.

Example 50. Occupant Changes Nickname
<presence
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit/miranda'>
  <game xmlns='http://jabber.org/protocol/mug'/>
</presence>
		

The service must send the updated presence to all occupants.

Example 51. Service Updates Nick
<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner'
      nick='miranda'
      role='White'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner'
      nick='miranda'
      role='White'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner'
      nick='miranda'
      role='White'/>
  </game>
</presence>
		

If the room already contains another user with the nickname the same rules apply as on entering a room.

6.9 Sending a Private Message

Since each occupant has a unique room JID, an occupant MAY send a "private message" to a selected occupant via the service by sending a message to the occupant's match JID. The message type SHOULD be "chat", or MAY be left unspecified (i.e., a normal message). This privilege SHOULD be allowed to any occupant (even a spectator in a moderated room).

Example 52. Occupant Sends Private Message
<message
    from='miranda@shakespeare.lit/desktop'
    to='island-chess@games.shakespeare.lit/lad'
    type='chat'>
  <body>Sweet lord, you play me false.</body>
</message>
		

The service is responsible for changing the 'from' address to the sender's match JID and delivering the message to the intended recipient's full JID.

Example 53. Recipient Receives the Private Message
<message
    from='island-chess@games.shakespeare.lit/damsel'
    to='ferdinand@shakespeare.lit/laptop'
    type='chat'>
  <body>Sweet lord, you play me false.</body>
</message>
		

If the sender attempts to send a private message to a room JID that does not exist, the service MUST return an <item-not-found/> error to the sender.

If the sender is not an occupant of the room in which the intended recipient is visiting, the service MUST return a <not-acceptable/> error to the sender.

6.10 Getting Member List

If allowed in accordance with room configuration, an occupant MAY be allowed to retrieve the list of room members. For details, see the Modifying the Member List section of this document.

6.11 Exiting A Room

In order to exit a multi-user game room, an occupant sends a presence stanza of type "unavailable" to the <room@service/nick> it is currently using in the room.

Example 54. Occupant Exits a Room
<presence
    from='ferdinand@shakespeare.lit'
    to='island-chess@games.shakespeare.lit/lad'
    type='unavailable'/>
		
Example 55. Service Sends Presence Related to Departure of Occupant
<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='miranda@shakespeare.lit'
    type='unavailable'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='member' role='none' />
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='alonso@shakespeare.lit'
    type='unavailable'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='member' role='none' />
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='ferdinand@shakespeare.lit'
    type='unavailable'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='member' role='none' />
  </game>
</presence>
		

If the leaving occupant had a role that was indispensable, the service MUST pause or cancel the game.

Example 56. Service Broadcasts the Pause Message to All
<presence>
    from='island-chess@games.shakespeare.lit'
    to='ferdinand@shakespeare.lit/laptop'>
  <pause xmlns='http://jabber.org/protocol/mug'/>
</presence>

<presence>
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'>
  <pause xmlns='http://jabber.org/protocol/mug'/>
</presence>
		

To resume the game, all players have to send <start/> messages again.

Example 57. Service Broadcasts the Cancel Message to All
<presence
    from='island-chess@games.shakespeare.lit'
    to='ferdinand@shakespeare.lit/laptop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <match-canceled />
    </state>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <match-canceled />
    </state>
  </game>
</presence>
		

7. Owner Use Cases

7.1 Creating a Room

To create a room a user sends the following presence to the room.

Example 58. User Creates a Room and Signals Game Support
<presence
    from='miranda@shakespeare.lit/desktop'>
    to='island-chess@games.shakespeare.lit/damsel'>
  <game xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'/>
</presence>
		

If the priviledge to create a room is restricted to certain users and the room cannot be created, the service MUST reply with the following error.

Example 59. Service Informs User of Inability to Create a Room
<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'
    type='error'>
  <game xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'/>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
		

If a game element or the var attribute with the game namespace is missing then the service MUST deny creating a room and send a presence with a bad request error back to the user.

If this user is allowed to create a room and the room does not yet exist, the service MUST create the room according to some default configuration, assign the requesting user as the initial room owner, and add the owner to the room but not allow anyone else to enter the room (effectively "locking" the room). The initial presence stanza received by the owner from the room MUST include extended presence information indicating the user's status as an owner and acknowledging that the room is awaiting configuration and that the initial match status is 'created'.

Example 60. Service Acknowledges Room Creation
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <status>created</status>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/damsel'>
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner' role='White'/>
  </game>
</presence>
		

The role attribute is only necessary if the service assignes roles automatically.

7.1.1 Creating an Instant Room

To request a room with the default configuration the owner sends the following query.

Example 61. Initiator Requests Instant Room
<iq from='miranda@shakespeare.lit/desktop'
    id='create1'
    to='island-chess@games.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options>
      <x xmlns='jabber:x:data' type='submit'/>
    </options>
  </query>
</iq>
			

7.1.2 Configuring the Room

If the user wants to configure the room, he MAY first request the configuration form.

Example 62. Initiator Requests Configuration Form
<iq from='miranda@shakespeare.lit/desktop'
    id='create1'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options/>
  </query>
</iq>
			

If no configuration is possible, the service MUST return the following error.

Example 63. Service Informs Owner that No Configuration is Possible
<iq from='island-chess@games.shakespeare.lit'
    id='create1'
    to='miranda@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options/>
  </query>
</iq>
			

The service then sends the initial configuration form to the user.

Example 64. Service Sends Configuration Form
<iq from='island-chess@games.shakespeare.lit'
    id='create1'
    to='miranda@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options>
      <x xmlns='jabber:x:data' type='form'>
        <title>Configuration for "Island Chess" Room</title>
        <instructions>
          Your room island-chess@games.shakespeare.lit has been created!
          The default configuration is as follows:
            - Moderated and public room
            - Up to 20 occupants
            - No password required
            - No invitation required
          To accept the default configuration, click OK. To
          select a different configuration, please complete
          this form.
        </instructions>
        <field
            type='hidden'
            var='FORM_TYPE'>
          <value>http://jabber.org/protocol/mug#matchconfig</value>
        </field>
        <field
            label='Natural-Language Room Name'
            type='text-single'
            var='mug#roomconfig_roomname'/>
        <field
            label='Short Description of the Room'
            type='text-single'
            var='mug#roomconfig_matchdesc'/>
        <field
            label='Type of the Room Policy'
            type='list-single'
            var='mug#roomconfig_roompolicy'>
          <value>moderated</value>
          <option label='Moderated Room'><value>moderated</value></option>
          <option label='Unmoderated Room'><value>unmoderated</value></option>
        </field>
        <field
            label='Allow Occupants to Invite Others?'
            type='boolean'
            var='mug#roomconfig_allowinvites'>
          <value>0</value>
        </field>
        <field
            label='Maximum Number of Occupants'
            type='list-single'
            var='mug#roomconfig_maxusers'>
          <value>20</value>
          <option label='2'><value>2</value></option>
          <option label='5'><value>5</value></option>
          <option label='10'><value>10</value></option>
          <option label='20'><value>20</value></option>
          <option label='30'><value>30</value></option>
          <option label='50'><value>50</value></option>
          <option label='None'><value>none</value></option>
        </field>
        <field
            label='Make Room Publicly Searchable?'
            type='boolean'
            var='mug#roomconfig_publicroom'>
          <value>1</value>
        </field>
        <field
            label='Make Room Members-Only?'
            type='boolean'
            var='mug#roomconfig_membersonly'>
          <value>0</value>
        </field>
        <field
            label='Type of the Anonymity'
            type='list-single'
            var='mug#roomconfig_anonymity'>
          <value>semi-anonymous</value>
          <option label='Fully-Anonymous Room'><value>fully-anonymous</value></option>
          <option label='Semi-Anonymous Room'><value>semi-anonymous</value></option>
          <option label='Non-Anonymous Room'><value>non-anonymous</value></option>
        </field>
        <field
            label='Password Required to Enter?'
            type='boolean'
            var='mug#roomconfig_passwordprotectedroom'>
          <value>0</value>
        </field>
        <field type='fixed'>
          <value>
            If a password is required to enter this room,
            you must specify the password below.
          </value>
        </field>
        <field
            label='Password'
            type='text-private'
            var='mug#roomconfig_roomsecret'/>
        <field type='fixed'>
          <value>
            You may specify a URL for a communication resources such as a MUC chat,
            a video chat or an IRC chat, leave it empty for no chat
            or leave it up to the server to create one.
          </value>
        </field>
        <field
            label='Communication Ressource'
            type='text-multi'
            var='mug#roomconfig_chat'/>
      </x>
      <options xmlns='http://jabber.org/protocol/mug/chess'>
        <x xmlns='jabber:x:data' type='form'>
          <title>Configuration for Chess Game</title>
          <instructions>
            The default configuration is as follows:
              - Classic Chess
            To accept the default configuration, click OK. To
            select a different configuration, please complete
            this form.
          </instructions>
          <field var='FORM_TYPE'>
              type='hidden'
            <value>http://jabber.org/protocol/mug/chess#chessconfig</value>
          </field>
          <field
              label='Game Variant'
              type='list-single'
              var='mug/chess#config_variant'>
            <value>classic</value>
            <option label='The standard classical chess'><value>classic</value></option>
            <option label='Four Player Bosworth'><value>bosworth</value></option>
            <option label='Four Player Tandem Chess'><value>tandem</value></option>
            <option label='Three Handed Chess'><value>threehanded</value></option>
          </field>
          ...
        </x>
      </options>
    </options>
  </query>
</iq>
			

To finish the configuration, the user MUST submits the completed form to the service.

Example 65. Owner Submits Configuration Form
<iq from='miranda@shakespeare.lit/desktop'
    id='create2'
    to='island-chess@games.shakespeare.lit'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE'>
          <value>http://jabber.org/protocol/mug#roomconfig</value>
        </field>
        <field var='mug#roomconfig_roomname'>
          <value>A lovers room</value>
        </field>
        <field var='mug#roomconfig_roomdesc'/>
          <value>The Chess Match at Act V, Scene IV of Shakespeare's The Tempest</value>
        </field>
        <field var='mug#roomconfig_roompolicy'>
          <value>moderated</value>
        </field>
        <field var='mug#roomconfig_allowinvites'>
          <value>0</value>
        </field>
        <field var='mug#roomconfig_maxusers'>
          <value>5</value>
        </field>
        <field var='mug#roomconfig_publicroom'>
          <value>1</value>
        </field>
        <field var='mug#roomconfig_membersonly'>
          <value>0</value>
        </field>
        <field var='mug#roomconfig_anonymity'>
          <value>semi-anonymous</value>
        </field>
        <field var='mug#roomconfig_passwordprotectedroom'>
          <value>1</value>
        </field>
        <field var='mug#roomconfig_roomsecret'>
          <value>bravenewworld</value>
        </field>
        <field var='mug#roomconfig_chat'/>
      </x>
      <options xmlns='http://jabber.org/protocol/mug/chess'>

<x xmlns='jabber:x:data' type='submit'>
          <field var='FORM_TYPE'>
            <value>http://jabber.org/protocol/mug/chess#chessconfig</value>
          </field>
          <field var='mug/chess#config_variant'>
            <value>classic</value>
          </field>
          ...
        </x>
      </options>
    </options>
  </query>
</iq>
			

In addition to the room configuration, the user MAY also supply a custom initial state for the match.

Example 66. Owner Submits Configuration Form Including a Constructed Match
<iq from='miranda@shakespeare.lit/desktop'
    id='create2'
    to='island-chess@games.shakespeare.lit'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
      <options xmlns='http://jabber.org/protocol/mug/chess'>
        <x xmlns='jabber:x:data' type='submit'>
          ...
        </x>
      </options>
    </options>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      <x xmlns='jabber:x:data' type='submit'>
        ...
      </x>
    </state>
  </query>
</iq>
			

Valid states are defined by the game protocol and may consist of the explicit current state in form of a data form or the series of turns that led to the state.

If the room creation fails because the specified room configuration options violate one or more service policies (e.g., because the password for a password-protected room is blank), the service MUST return a <not-acceptable/> error.

Example 67. Service Informs Owner that Requested Configuration Options Are Unacceptable
<iq from='island-chess@games.shakespeare.lit'
    id='create2'
    to='miranda@shakespeare.lit/desktop'
    type='error'>
  <error type='modify'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
			

Alternatively, the room owner MAY cancel the configuration process:

Example 68. Owner Cancels Initial Configuration
<iq from='miranda@shakespeare.lit/desktop'
    id='create2'
    to='island-chess@games.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <x xmlns='jabber:x:data' type='cancel'/>
  </query>
</iq>
			

If the room owner cancels the initial configuration, the service SHOULD destroy the room, making sure to send unavailable presence to the room owner (see the "Destroying a Room" use case for protocol details).

7.2 Subsequent Room Configuration

The owner may change the configuration whenever the match status is 'inactive'.

Example 69. Owner Requests Configuration Form
<iq from='miranda@shakespeare.lit/desktop'
    id='create1'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/mug#owner'/>
</iq>
		
Example 70. Service Sends Configuration Form
<iq from='island-chess@games.shakespeare.lit'
    id='create1'
    to='miranda@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <options>
      <x xmlns='jabber:x:data' type='form'>
        <title>Configuration for "Island Chess" Room</title>
        <instructions>
          To select a different configuration, please complete
          this form.
        </instructions>
        <field
            type='hidden'
            var='FORM_TYPE'>
          <value>http://jabber.org/protocol/mug#roomconfig</value>
        </field>
        <field
            label='Natural-Language Room Name'
            type='text-single'
            var='mug#roomconfig_roomname'>
          <value>A lovers match</value>
        </field>
        <field
            label='Short Description of the Room'
            type='text-single'
            var='mug#roomconfig_roomdesc'>
          <value>The Chess Match at Act V, Scene IV of Shakespeare's The Tempest</value>
        </field>
        <field
            label='Type of the Room Policy'
            type='list-single'
            var='mug#roomconfig_roompolicy'>
          <value>moderated</value>
          <option label='Moderated Room'><value>moderated</value></option>
          <option label='Unmoderated Room'><value>unmoderated</value></option>
        </field>
        <field
            label='Allow Occupants to Invite Others?'
            type='boolean'
            var='mug#roomconfig_allowinvites'>
          <value>0</value>
        </field>
        <field
            label='Maximum Number of Occupants'
            type='list-single'
            var='mug#roomconfig_maxusers'>
          <value>5</value>
          <option label='2'><value>2</value></option>
          <option label='5'><value>5</value></option>
          <option label='10'><value>10</value></option>
          <option label='20'><value>20</value></option>
          <option label='30'><value>30</value></option>
          <option label='50'><value>50</value></option>
          <option label='None'><value>none</value></option>
        </field>
        <field
            label='Make Room Publicly Searchable?'
            type='boolean'
            var='mug#roomconfig_publicroom'>
          <value>1</value>
        </field>
        <field
            label='Make Room Members-Only?'
            type='boolean'
            var='mug#roomconfig_membersonly'>
          <value>0</value>
        </field>
        <field
            label='Type of the Anonymity'
            type='list-single'
            var='mug#roomconfig_anonymity'>
          <value>semi-anonymous</value>
          <option label='Fully-Anonymous Room'><value>fully-anonymous</value></option>
          <option label='Semi-Anonymous Room'><value>semi-anonymous</value></option>
          <option label='Non-Anonymous Room'><value>non-anonymous</value></option>
        </field>
        <field
            label='Password Required to Enter?'
            type='boolean'
            var='mug#roomconfig_passwordprotectedroom'>
          <value>1</value>
        </field>
        <field type='fixed'>
          <value>
            If a password is required to enter this room,
            you must specify the password below.
          </value>
        </field>
        <field
            label='Password'
            type='text-private'
            var='mug#roomconfig_roomsecret'>
          <value>bravenewworld</value>
        </field>
      </x>
      <options xmlns='http://jabber.org/protocol/mug/chess'>
        <x xmlns='jabber:x:data' type='form'>
          <title>Configuration for Chess Game</title>
          <instructions>
            The default configuration is as follows:
              - Classic Chess
            To accept the default configuration, click OK. To
            select a different configuration, please complete
            this form.
          </instructions>
          <field var='FORM_TYPE'>
              type='hidden'
            <value>http://jabber.org/protocol/mug/chess#chessconfig</value>
          </field>
          <field
              label='Game Variant'
              type='list-single'
              var='mug/chess#config_variant'>
            <value>classic</value>
            <option label='The standard classical chess'><value>classic</value></option>
            <option label='Four Player Bosworth'><value>bosworth</value></option>
            <option label='Four Player Tandem Chess'><value>tandem</value></option>
            <option label='Three Handed Chess'><value>threehanded</value></option>
          </field>
          ...
        </x>
      </options>
    </options>
  </query>
</iq>
	

If there are no configuration options available, the service MUST return an empty query element to the owner as shown in the previous use case.

The owner SHOULD then submit the form with updated configuration information.

7.2.1 Notification of Configuration Changes

If as a result of a change in the room configuration the room type is changed to members-only, any occupants MUST become members and the service MUST reflect the updated presence to all.

A room MUST send notification to all occupants when the room configuration changes. If the game configuration changed, the game MUST also specify an adequate match state.

Example 71.
<presence
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <configuration-changed/>
    <status>inactive</status>
    <state xmlns='http://jabber.org/protocol/mug/chess'>
      ...
    </state>
  </game>
</presence>
		

7.3 Room Saving

The owner may save the room whenever the match status is 'inactive' and save the room including the match state in a moderated room.

Example 72. Owner Saves the Room
<iq from='miranda@shakespeare.lit/desktop'
    id='save'
    to='island-chess@games.shakespeare.lit'>
    type='result'>
  <save xmlns='http://jabber.org/protocol/mug#owner'/>
</iq>
		

If saving is allowed, the service MUST inform all occupants and remove them from the room.

Example 73. Service Broadcasts Presence to all Occupants
<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'
    type='unavaiable'>
  <saved xmlns='http://jabber.org/protocol/mug'/>
</presence>
<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='ferdinand@shakespeare.lit/laptop'
    type='unavaiable'>
  <saved xmlns='http://jabber.org/protocol/mug'/>
</presence>
		
Example 74. Service Informs Owner of Successful Save Request
<iq from='island-chess@games.shakespeare.lit'
    id='save'
    to='miranda@shakespeare.lit/desktop'
    type='result'/>
		

After saving the room, nobody can join it until it is loaded by the owner.

7.4 Room Loading

For Discovering of Saved Rooms see search for rooms. Send an iq stanza to request loading a the room as follows:

Example 75. Owner Requests Loading an Adjourned Room
<iq from='miranda@shakespeare.lit/desktop'
    id='load1'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <load xmlns='http://jabber.org/protocol/mug#owner'/>
</iq>
		

After loading, the match status is 'paused' if the match was 'active' before saving. Alternatively, the match status is set to 'inactive' if the match was inactive. The service SHOULD send an invitation to all occupants that were present in the game when saved.

Players entering the room SHOULD be assigned the role they had when the room was saved.

7.5 Modifying the Member List

In the context of a members-only match, the member list is essentially a "whitelist" of people who are allowed to enter the match. Anyone who is not a member is effectively banned from entering the match.

In the context of an open match, the member list is simply a list of users (bare JID and reserved nick) who are registered with the match. Such users may appear in a match roster, have their match nickname reserved, be returned in search results, and the like.

It is RECOMMENDED that only the room owner has the privilege to modify the member list in members-only rooms. To do so, the owner first requests the member list by querying the room for all users with an affiliation of "member":

Example 76. Owner Requests Member List
<iq from='miranda@shakespeare.lit/desktop'
    id='member3'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item affiliation='member'/>
  </query>
</iq>
		

Note: A service SHOULD also return the member list to any occupant in a members-only room; i.e., it SHOULD NOT generate a <forbidden/> error when a member in the room requests the member list. This functionality may assist clients in showing all the existing members even if some of them are not in the room, e.g. to help a member determine if another user should be invited. A service SHOULD also allow any member to retrieve the member list even if not yet an occupant.

The service MUST then return the full member list to the owner qualified by the 'http://jabber.org/protocol/mug#owner' namespace; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for each members that is currently an occupant.

Example 77. Service Sends Member List to Owner
<iq from='island-chess@games.shakespeare.lit'
    id='member3'
    to='miranda@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item affiliation='member'
        jid='alonso@shakespeare.lit'
        nick='KingOfNaples'/>
  </query>
</iq>
		

The owner MAY then modify the member list. In order to do so, the owner MUST send the changed items (i.e., only the "delta") to the service; each item MUST include the 'affiliation' attribute (normally set to a value of "member" or "none") and 'jid' attribute but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage game roles in a room):

Example 78. Owner Sends Modified Member List to Service
<iq from='miranda@shakespeare.lit/desktop'
    id='member4'
    to='island-chess@games.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item affiliation='none'
        jid='alonso@shakespeare.lit'/>
    <item affiliation='member'
        jid='prospero@shakespeare.lit'/>
  </query>
</iq>
		

The service MUST modify the member list and then inform the owner of success:

Example 79. Service Informs Owner of Success
<iq from='island-chess@games.shakespeare.lit'
    id='member4'
    to='miranda@shakespeare.lit/desktop'
    type='result'/>
		

The service MUST change the affiliation of any affected user. If the user has been removed from the member list, the service MUST change the user's affiliation from "member" to "none". If the user has been added to the member list, the service MUST change the user's affiliation to "member".

If a removed member is currently in a members-only room, the service SHOULD kick the occupant by changing the removed member's affiliation to "none" and send appropriate presence to the removed member as previously described. No matter whether the removed member was in or out of a members-only room, the service MUST subsequently refuse entry to the user.

For all room types, the service MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "none".

Example 80. Service Sends Notice of Loss of Membership to All Occupants
<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none'/>
  </game>
</presence>

...
		

In addition, the service SHOULD send an invitation to any user who has been added to the member list of a members-only room if the user is not currently affiliated with the room, for example as an owner (such a user would by definition not be in the match; note also that this example includes a password but not a reason -- both child elements are OPTIONAL):

Example 81. Room Sends Invitation to New Member
<message
    from='island-chess@games.shakespeare.lit'
    to='prospero@shakespeare.lit'>
  <invited xmlns='http://jabber.org/protocol/mug#user'
      from='miranda@shakespeare.lit'
      var='http://jabber.org/protocol/mug/chess'>
    <password>cauldronburn</password>
  </invited>
</message>
		

While only the owner SHOULD be allowed to modify the member list, an implementation MAY provide a configuration option that opens invitation privileges to any member of a members-only match. In such a situation, any invitation sent SHOULD automatically trigger the addition of the invitee to the member list. However, if invitation privileges are restricted to the owner and a mere member attempts to a send an invitation, the service MUST deny the invitation request and return a <forbidden/> error to the sender:

Example 82. Service Returns Error on Attempt by Mere Member to Invite Others to a Members-Only Match
<message
    from='island-chess@games.shakespeare.lit'
    to='alonso@shakespeare.lit/pda'
    type='error'>
  <invite xmlns='http://jabber.org/protocol/mug#user'
      to='prospero@shakespeare.lit'>
    <reason>
      Hey Prospero, join the game!
    </reason>
  </invite>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>
		

Invitations sent through an open room MUST NOT trigger the addition of the invitee to the member list.

If a user is added to the member list of an open room and the user is in the room, the service MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member".

Example 83. Service Sends Notice of Membership to All Occupants
<presence
    from='island-chess@games.shakespeare.lit/prospero'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='member'/>
  </game>
</presence>

...

7.6 Revoke and Assign Roles

The room owner may decide to modify the assigned game roles in a room. To do so, the owner first requests a list of the occupants and assigned roles by querying the room:

Example 84. Owner Requests List of All Occupants and Assigned Roles
<iq from='miranda@shakespeare.lit/desktop'
    id='roles1'
    to='island-chess@games.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item role='all'/>
  </query>
</iq>
		

Note: The role 'all' is a reserved name for querying the list of active players and MUST NOT be redefined by games for other purposes.

The service SHOULD then return the full list of all occupants qualified by the 'http://jabber.org/protocol/mug#owner' namespace; each item MUST include the 'role' and 'nick' attributes and MAY include the 'jid' and 'affiliation' attributes for each occupant in the room.

Example 85. Service Sends List of Occupants and Assigned Roles to Owner
<iq from='island-chess@games.shakespeare.lit'
    id='roles1'
    to='miranda@shakespeare.lit/desktop'
    type='result'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item role='White'
        nick='damsel'/>
    <item role='Black'
        nick='lad'/>
    <item role='none'
        nick='KingOfNaples'/>
  </query>
</iq>
		

The service MUST send a <forbidden/> error if the owner has not the required Privileges.

The owner MAY then modify the roles assigned by occupants. In order to do so, the owner MUST send the changed items (i.e., only the "delta") to the service; each item MUST include the 'roles' attribute and 'nick' attribute but SHOULD NOT include the 'jid' attribute and MUST NOT include the 'affiliation' attribute:

Example 86. Owner Sends Modified List of Assigned Roles to Service
<iq from='miranda@shakespeare.lit/desktop'
    id='roles2'
    to='island-chess@games.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item role='none'
        nick='lad'/>
    <item role='Black'
        nick='KingOfNaples'/>
  </query>
</iq>
		

The service MUST modify the roles of the occupants and then inform the owner of success:

Example 87. Service Informs Owner of Success
<iq from='island-chess@games.shakespeare.lit'
    id='roles2'
    to='miranda@shakespeare.lit/desktop'
    type='result'/>
		

The service MUST change the roles of any affected user and MUST send updated presence to all occupants, indicating the changed role by including an <game/> element qualified by the 'http://jabber.org/protocol/mug' namespace and containing an <item/> child with the 'role' attribute.

Example 88. Service Sends Notice of Changed Roles to All Occupants
<presence
    from='island-chess@games.shakespeare.lit/KingOfNaples'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item role='Black'/>
  </game>
</presence>

...
		

7.7 Transfer Ownership

The room owner may decide to transfer the ownership to another occupant.

Example 89. Owner Transfers the Ownership to Another Occupants
<iq from='miranda@shakespeare.lit/desktop'
    id='owner1'
    to='island-chess@games.shakespeare.lit'
    type='set'>
  <query xmlns='http://jabber.org/protocol/mug#owner'>
    <item affiliation='owner'
        jid='ferdinand@shakespeare.lit'/>
  </query>
</iq>
		
Example 90. Service Informs Owner of Success
<iq from='island-chess@games.shakespeare.lit'
    id='owner1'
    to='miranda@shakespeare.lit/desktop'
    type='result'/>
		
Example 91. Service Informs Occupants About the Affiliation Changes
<presence
    from='island-chess@games.shakespeare.lit/lad'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='owner'/>
  </game>
</presence>

<presence
    from='island-chess@games.shakespeare.lit/damsel'
    to='miranda@shakespeare.lit/desktop'>
  <game xmlns='http://jabber.org/protocol/mug'>
    <item affiliation='none'/>
  </game>
</presence>

...
		

8. Business Rules

OPTIONAL.

9. Implementation Notes

The following guidelines may assist client and component developers in creating MUG implementations.

9.1 Services

  1. In order to allow supporting multiple games on the service the component may offer a game plugin interface.

  2. To manage team games, the service should offer game plugins an API and leave game turn message routing to the game plugins.

  3. In case of loading a room the service SHOULD remember each player's role, so it can assign the roles properly when the room is loaded.

  4. The game service MAY offer a managed multi-user chatroom. This can be done by creating a new chat room and keep membership synchronized with the game room.

9.2 Clients

  1. In order to respect the users privacy the jabber client SHOULD hide active matches for discovering as default behavior. However jabber clients MAY offer a setting to enable the active match discovery.

  2. MUG clients MAY highlight users that participate in a room chat somehow. The highlighting could be done with a small speech balloon icon behind the players name.

10. Internationalization Considerations

OPTIONAL.

11. Security Considerations

REQUIRED.

12. IANA Considerations

REQUIRED.

13. XMPP Registrar Considerations

If this protocol will be accepted by the XMPP Standards Foundation, the XMPP Registrar [7] should includes the following information in its registries.

13.1 Protocol Namespaces

The XMPP Registrar includes the following MUG-related namespaces in its registry of protocol namespaces:

13.2 Service Discovery Category/Type

A Multi-User Game service or match is identified by the "game" category and the "multi-user" type within Service Discovery.

13.3 Service Discovery Features

There are many features related to a MUG service or match that can be discovered by means of Service Discovery. The most fundamental of these is the 'http://jabber.org/protocol/mug' namespace. In addition, a MUG match SHOULD provide information about the specific match features it implements, such as password protection and match moderation.

13.4 URI Query Types

13.4.1 play

The "play" querytype is registered as a MUG-related action, with keys of "game" and "password".

Example 92. Play Action: IRI/URI
xmpp:island-chess@games.shakespeare.lit?play
			

The application MUST either present an interface enabling the user to provide a room nickname or populate the room nickname based on configured preferences or nickname discovery.

If the application doesn't know the game namespace of the room it MUST query for room information to receive the game namespace.

Example 93. Play Action: Resulting Stanza
<presence to='island-chess@games.shakespeare.lit/KingOfNaples'>
  <game
      xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'/>
</presence>
			

In order to avoid sending the service discovery query, the play action SHOULD include the game namespace for the room.

Example 94. Play Action with Game: IRI/URI
xmpp:island-chess@games.shakespeare.lit?play;game=http://jabber.org/protocol/mug/chess
			

The play action MAY include a password for the room. Naturally, access to a URI that includes a room password MUST be appropriately controlled.

Example 95. Play Action: IRI/URI
xmpp:island-chess@games.shakespeare.lit?play;password=brave%20new%20world
			
Example 96. Play Action with Password: Resulting Stanza
<presence to='island-chess@games.shakespeare.lit/KingOfNaples'>
  <game
      xmlns='http://jabber.org/protocol/mug'
      var='http://jabber.org/protocol/mug/chess'>
    <password>brave new world</password>
  </game>
</presence>
			

The following submission registers the "play" querytype.

<querytype>
  <name>play</name>
  <proto>http://jabber.org/protocol/mug</proto>
  <desc>enables joining a multi-user game room</desc>
  <doc>XEP-XXXX</doc>
  <keys>
    <key>
      <name>game</name>
      <desc>the game namespace required to enter a multi-user game room</desc>
    </key>
    <key>
      <name>password</name>
      <desc>the password required to enter a multi-user game room</desc>
    </key>
  </keys>
</querytype>
			

14. XML Schemas

14.1 http://jabber.org/protocol/mug

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/mug'
    xmlns='http://jabber.org/protocol/mug'
    elementFormDefault='qualified'>

<xs:element name='game'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='configuration-changed' minOccurs='0'/>
      <xs:element ref='status' minOccurs='0'/>
      <xs:any processContents='skip' minOccurs='0'/>
      <xs:element ref='item' minOccurs='0'/>
      <xs:element name='password' type='xs:string' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='var' type='xs:string' use='optional'/>
  </xs:complexType>
</xs:element>

<xs:element name='configuration-changed'>
  <xs:complexType/>
</xs:element>

<xs:element name='status'>
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="created"/>
      <xs:enumeration value="active"/>
      <xs:enumeration value="inactive"/>
    </xs:restriction>
    </xs:simpleType>
</xs:element>

<xs:element name='item'>
  <xs:complexType>
    <xs:attribute name='affiliation' use='optional'>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="owner"/>
          <xs:enumeration value="member"/>
          <xs:enumeration value="none"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name='jid' type='xs:string' use='optional'/>
    <xs:attribute name='role' type='xs:string' use='optional'/>
    <xs:attribute name='nick' type='xs:string' use='optional'/>
  </xs:complexType>
</xs:element>

<xs:element name='pause'>
  <xs:complexType/>
</xs:element>

<xs:element name='saved'>
  <xs:complexType/>
</xs:element>

</xs:schema>
		

14.2 http://jabber.org/protocol/mug#user

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/mug#user'
    xmlns='http://jabber.org/protocol/mug#user'
    elementFormDefault='qualified'>

<xs:element name='game'>
  <xs:complexType>
    <xs:sequence>
      <xs:choice>
        <xs:element ref='invite' maxOccurs='unbounded'/>
        <xs:element ref='invited'/>
        <xs:element ref='decline'/>
        <xs:element ref='declined'/>
      </xs:choice>
      <xs:element name='password' type='xs:string' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='var' type='xs:string' use='optional'/>
  </xs:complexType>
</xs:element>

<xs:element name='invite'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='reason' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='to' type='xs:string' use='required'/>
  </xs:complexType>
</xs:element>

<xs:element name='invited'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='reason' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='from' type='xs:string' use='required'/>
    <xs:attribute name='var' type='xs:string' use='required'/>
  </xs:complexType>
</xs:element>

<xs:element name='decline'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='reason' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='to' type='xs:string' use='required'/>
  </xs:complexType>
</xs:element>

<xs:element name='declined'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='reason' minOccurs='0'/>
    </xs:sequence>
    <xs:attribute name='from' type='xs:string' use='required'/>
  </xs:complexType>
</xs:element>

<xs:element name='reason' type='xs:string'/>

<xs:element name='turn'>
  <xs:complexType>
    <xs:sequence>
      <xs:any processContents='skip'/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name='invalid-turn'>
  <xs:complexType/>
</xs:element>

<xs:element name='start'>
  <xs:complexType/>
</xs:element>

</xs:schema>
		

14.3 http://jabber.org/protocol/mug#owner

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/mug#owner'
    xmlns='http://jabber.org/protocol/mug#owner'
    elementFormDefault='qualified'>

<xs:element name='query'>
  <xs:complexType>
    <xs:sequence>
      <xs:element ref='options' minOccurs='0'/>
      <xs:any processContents='skip' minOccurs='0'/>
      <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name='options'>
  <xs:complexType>
    <xs:sequence>
      <xs:any processContents='skip' minOccurs='0' maxOccurs='2'/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name='item'>
  <xs:complexType>
    <xs:attribute name='affiliation' use='optional'>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="owner"/>
          <xs:enumeration value="member"/>
          <xs:enumeration value="none"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name='role' type='xs:string' use='optional'/>
    <xs:attribute name='nick' type='xs:string' use='optional'/>
    <xs:attribute name='jid' type='xs:string' use='optional'/>
  </xs:complexType>
</xs:element>


<xs:element name='save'>
  <xs:complexType/>
</xs:element>

<xs:element name='load'>
  <xs:complexType/>
</xs:element>

</xs:schema>
		

Appendices

Appendix A: Document Information

Series
XEP
Number
xxxx
Publisher
XMPP Standards Foundation
Status
ProtoXEP
Type
Standards Track
Version
0.0.3
Last Updated
2009-04-20
Approving Body
XMPP Council
Dependencies
XMPP Core, XMPP IM, XEP-0004, XEP-0030, XEP-0055
Supersedes
None
Superseded By
None
Short Name
mug

This document in other formats: XML  PDF

Appendix B: Author Information

Torsten Grote
Email
Torsten.Grote(ät)fsfe.org
JabberID
Torsten.Grote(ät)jabber.fsfe.org
Arne König
Email
arne.ko(ät)23inch.de
JabberID
arne++(ät)jabber.ccc.de
Günther Nieß
Email
guenther.niess(ät)web.de
JabberID
niess(ät)jabber.ccc.de

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2024 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <https://xmpp.org/community/> for a complete list.

Errata can be sent to <editor@xmpp.org>.

Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

Appendix G: Notes

1. XEP-0030: Service Discovery <https://xmpp.org/extensions/xep-0030.html>.

2. XEP-0128: Service Discovery Extensions <https://xmpp.org/extensions/xep-0128.html>.

3. XEP-0055: Jabber Search <https://xmpp.org/extensions/xep-0055.html>.

4. XEP-0059: Result Set Management <https://xmpp.org/extensions/xep-0059.html>.

5. XEP-0045: Multi-User Chat <https://xmpp.org/extensions/xep-0045.html>.

6. XEP-0196: User Gaming <https://xmpp.org/extensions/xep-0196.html>.

7. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <https://xmpp.org/registrar/>.

Appendix H: Revision History

Note: Older versions of this specification might be available at https://xmpp.org/extensions/attic/

  1. Version 0.0.3 (2009-04-20)

    Added sections about entering non-anonymous, semi-anonymous and fully-anonymous rooms.

    gn
  2. Version 0.0.2 (2009-03-14)

    Second draft.

    ak, gn
  3. Version 0.0.1 (2008-07-17)

    First draft.

    tg

Appendix I: Bib(La)TeX Entry

@report{grote2008mug,
  title = {Multi-User Gaming},
  author = {Grote, Torsten and König, Arne and Nieß, Günther},
  type = {XEP},
  number = {xxxx},
  version = {0.0.3},
  institution = {XMPP Standards Foundation},
  url = {https://xmpp.org/extensions/xep-xxxx.html},
  date = {2008-07-17/2009-04-20},
}

END