Gametype Plugins

Writing Clientside Plugins

The Red Corona Gaming Framework is designed to be an open framework, allowing third party developers to design and create new games. This document explains how to create a clientside plugin that will allow users to create, join and manage a game, using the example of the Bridge gametype which is provided by default.

Overview

A game type is a class which knows how to create games; effectively, a game factory with a little metadata capability. The game type class itself is usually very lightweight, creating an instance of a game class when a user enters a game (by starting one or entering a pre-existing one). Your game class will tend to have three parts: user interface, a client (which is used when you join a game hosted by someone else), and a server (which is only used if you host a game); naturally, a client for a serverside game will not have the server part.

The gaming framework uses a message based Sockets library, and all communication between players is done by sending messages to the server. Your client should respond to messages from the server to update the interface, and should respond to user actions by sending messages to the game owner, and, in the case of the game owner, broadcasting responses to other players in the game.

Requirements

The base classes and interfaces are defined in Lobby.dll, and are in the namespace RedCorona.Net.Games. Your game type must implement the IGameType interface:

	public interface IGameType {
		string URL { get; }
		string Version { get; }
		bool CanCreate { get; }
		int ValidateMaxPlayers(int value);
		IGame CreateClientsideGame(ClientLobbyProxy lobby, GameInfo gi);
	}

And the result of CreateClientsideGame must be of type IGame:

public interface IGame {
		bool ProcessCode(ClientLobbyProxy lobby, MemberInfo mem, uint code, byte[] bytes, int len);
		Form GetCustomSetupForm();
		void RequestStartGame();
		void StartGame();
		void CloseGame();
	}

Both of these classes you write must also be derived from MarshalByRefObject, as each game type is hosted in a separate AppDomain to allow unloading/reloading of plugins and multiple versions of the same game type to be available at the same time.

Fortunately, a default implementation of these is provided for you in the classes BaseGameType and BaseGame. You will also make a lot of use of the ReservedCodes struct, which contains the message numbers that are meaningful to the server.

The Game Type Class

The game type class is usually very simple. Here is the one for Bridge:

	public class BridgeGameType : BaseGameType {
		public override String URL { get { return "http://www.redcorona.com/GameType/Bridge"; } }
		public override String Version { get { return "1.0.1"; } }
		public override IGame CreateClientsideGame(ClientLobbyProxy cl, GameInfo gi){
			return new BridgeGame(cl, gi);
		}
	}

The URL is a nominal URL for the game type, it need not be real, although it is a useful place to put information about the game type. You should use your own domain, followed by a string which is unique to this game type.

The version should always start with a three part numeric version, which is used to compare versions – for example for the game client's auto-update mechanism or when attempting to join a game. You may include any arbitrary text after a space if you wish (for example '1.3.0 (Release Candidate 1)'); this will be displayed in the client when inspecting a game, but all versions with the same numeric part will be treated the same. It is recommended that you move the last digit when an upgrade is useful but does not greatly affect gameplay, the middle digit when a significant improvement is made and the first digit when old versions are not able to play at all any more; however whatever scheme you prefer will work as long as the version always increases and always has a three-part numeric section. It is also a good idea if the .Net assembly version matches the numeric part, but it is not required.

CreateClientsideGame is called when the client detects that you are in a game that it does not have an IGame instance for, so you must always return a valid IGame instance, which will be an instance of your custom game class.

The Game Class

The game class (inheriting from BaseGame) does all the work of managing an individual game, although the server manages players entering, leaving, disconnecting etc for you. You will typically make a lot of use of state variables.

The BaseGame class provides a lot of functionality; for a simple game, you will only need to provide a constructor, and override ProcessGameCode to process the custom messages you will need for your game. If you want a special setup form (so before the game is started, there is a form that allows players to chat and to set various status items about themselves) like Bridge has, you should create and show that form in the constructor, assigning it to SetupForm or MainForm so that it is removed when the game is closed.

You should override ProcessGameChat if you provide an in-game chat-area, which in most cases is useful:

		public override void ProcessGameChat(int MemberID, String msg, int scope){
			msg = lobby.Member(MemberID).Username + ": " + msg;
			((SetupForm)SetupForm).Chat.AddLine(ChatColors[scope], msg);
		}

ChatColors is simply an array of colours corresponding to the difference sorts of chat you can receive; only indices 2 (in-game) and 3 (PM) should be received.

To be completed