Dev:Games Plugin Howto

From AMSN
Jump to: navigation, search

Contents

Introduction

This tutorial will teach you on how to use the game API of aMSN to develope your own game plugin. First of all you should have read the Dev:Plugin Developer Guide as a prerequisite, especially the basics are required.

First steps

First of all, you need to create the first steps for your own plugin (plugininfo.xml, (de-)init proc, register plugin, ...) so that you can load and unload in within your aMSN. To let aMSN recognize that your plugin is a game plugin, and that it should get listed in the games list, you have to register your plugin/game at the game interface.

 ::MSNGamesPlugins::register

proc register { name protocolVersion appID triggerProcs }

Parameters:

  • name: a unique name for your game plugin
  • protocolVersion: the protocol version of the games stack your plugin can use (at the moment it's always 1) in the case it could change one day
  • appID: a list of appIDs and their corresponding names; you can, in theory, handle more than one game with one plugin
  • triggerProcs: a list of event procs that get called by the games stack

Return value:

  • The protocol version the games stack uses. It should be equal to the protocolVersion parameter, just to make sure the games stack doesn't do anything your plugin doesn't understand or the other way round.

An example from the Tic Tac Toe plugin:

 proc RegisterGame {} {
       set name "tictactoe"
       set pVer 1
       set appId [list [list "1021" [trans gamettttitle]]]
       set funcs [list \
             "::GameTTT::onCreate" \
             "::GameTTT::onDestroy" \
             "::GameTTT::onRestart" \
             "::GameTTT::onStart" \
             "::GameTTT::onGameEnd" \
             "::GameTTT::onMessage" \
       ]
       
       set ret [::MSNGamesPlugins::register $name $pVer $appId $funcs]
       if {$ret != $pVer} {
             #oops, seems like plugin has older protocol version or registering was unsuccessful so unregister again
             status_log "registering tictactoe was unsuccessful, return code: $ret" red
             ::MSNGamesPlugins::unregister $name
       }
 }

 ::MSNGamesPlugins::unregister

proc unregister { name }

Parameters:

  • name: the unique name for your game plugin (the same you used for registering!)

Return value:

  • (none)

Make sure to always unregister your game when unloading the plugin, otherwise it will still be available in the games list although the plugin has been unloaded before!


The Events

Registering your game needs you to specify a bunch of procs that get called by the games stack when a game event occurs. They are listed in the order on how they have to be placed in the triggerProcs list:

onCreate

proc onCreate { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: (not used here)

Return value:

  • (none)

Description:

  • This event is triggered after one user has invited another user and the other user has accepted the invitation.
  • Note: The game doesn't start yet, it usually takes a few seconds, because after that, WLM users have to load the game and have to see the ads before being able to play.

onDestroy

proc onDestroy { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: (not used here)

Return value:

  • (none)

Description:

  • This event is triggered after the other user has closed the game session.
  • Note: I'm not sure at the moment, but I think this event can also get triggered after the game was closed locally! (TODO: check this!)
  • You need to clean up internal storage data (see one of the next topics!) ..

onRestart

proc onRestart { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: (not used here)

Return value:

  • (none)

Description:

  • This event is triggered after both players have confirmed to play another round (restart the game).
  • Note: This event doesn't replace the onRestart event, it replaces the onCreate event!

onStart

proc onStart { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: (not used here)

Return value:

  • (none)

Description:

  • This event is triggered after both users are ready loading their games (or have decided to restart the game) and the communication channel is established.
  • Note: This doesn't mean the game can begin now in all cases! The game itself may have an additional handshake mechanism to make sure the other player is ready, but this is the job of the game plugin!

onGameEnd

proc onGameEnd { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: (not used here)

Return value:

  • (none)

Description:

  • This event is triggered after a game round is finished and the other player has clicked the restart button.

onMessage

proc onMessage { sid param }

Parameters:

  • sid: a session id, identifying a single game session
  • param: a message received from the communication channel

Return value:

  • (none)

Description:

  • This event is triggered after a message has been received from the communication channel.
  • Note: Messages consist of the message itself and a channel identifier prepended, seperated by a :, to the message. The channel identifier can be 0 for a "system" message or 18 for the game channel. Usually the event shouldn't receive any "system" messages because the game stack interprets and filters them. So the messages received here usually look like that:
 18:this is a test message
     (or)
 18:-1


Interaction

You already know how to receive messages from the communication channel and how to receive events. Now you need to interact with the other player.

 ::MSNGamesInterface::send

proc send { sid data }

Parameters:

  • sid: the session id of the current game session
  • data: the message being sent to the communication channel

Return value:

  • (none)

Description:

  • You need to prepend the "18:", mentioned in the description of the onMessage event, to identify your message as a normal game message.


 ::MSNGamesInterface::restartGame

proc restartGame { sid }

Parameters:

  • sid: the session id of the current game session

Return value:

  • (none)

Description:

  • When a game round is finished and the player wants to restart the game, this proc has to be called after the player clicked the restart button.


 ::MSNGamesInterface::closeGame

proc closeGame { sid }

Parameters:

  • sid: the session id of the current game session

Return value:

  • (none)

Description:

  • This proc has to be called after the player has closed the game (window). The other player receives the message that the player has closed the game.
  • Note: The game session is still alive after that call. You still need to call the next proc if you want to finally close the communication channel and clean up the internal memory storage!


 ::MSNGamesInterface::destroyGame

proc destroyGame { sid }

Parameters:

  • sid: the session id of the current game session

Return value:

  • (none)

Description:

  • This proc closes the communication channel and cleans up all the internal memory storage.
  • Note: Make sure calling this proc is the last thing you do within in a session! After calling that proc the session ID gets invalidated, no events get triggered anymore and calling procs with the sid will fail!


Data Storage

Your plugin needs some data storage for sure, for example for storing the game state, scores or similar things. As your plugin can be called several times concurrently, you can't store your game dependent data in a global variable, because it would be valid to *all* running sessions. So you need to store your data in a variable depending on the session. There are two procs that help you managing these variables:

 ::MSNGamesInterface::setSetting

proc setSetting { sid key value }

Parameters:

  • sid: the session id of the current game session
  • key: the variable name
  • value: the value of the variable

Return value:

  • (none)

 ::MSNGamesInterface::getSetting

proc getSetting { sid key default }

Parameters:

  • sid: the session id of the current game session
  • key: the variable name
  • default: a default value, in the case the variable doesn't exist yet

Return value:

  • the value of the stored variable

Predefined variables/variables set by the games stack

There are some variables that get set by the games stack and contain useful information for a plugin:

  • opponentnick: the nick of the opponent player
  • inviter: 1 = the local player invited the other player, 0 = the local player was invited by the other player

... and some with only internal data, but you shouldn't use them:

  • started
  • handshakestate
  • opponentready
Personal tools