You are here: start » charon » past » alfastreet

Alfalfa Project (2004-2006)

Alfastreet manufactures gambling devices, among others, multi-player casino games such as single-wheel multi-client roulette, multi-client keno, etc. I designed and coded the platform library for the next generation of multi-player games, intended to be running on LINUX based computers.

Alfastreet prototype screenshot Alfastreet prototype screenshot

“Alfalfa”, the platform library I developed included the following features:

Encapsulated GUI system

Included with the library was a compiler for PSD (Photoshop Document) files. Each PSD file represented a single GUI box object, and together with an optional script, it was compiled into a series of rle-compressed images and an encapsulated GUI box object file. Unless the behavior was altered by the additional script, each layer in the PSD file would map to a single GUI control. An additional functionality of the compiler was its ability to generate raster fonts from TrueType, also based on definition provided by the script, incorporating such fonts into the GUI box object. Thus, each GUI box was at once a layered screen composed of GUI controls, but also a library of fonts, colors, typefaces and special effects. Since parenthood between GUI boxes was supported, features like skinning, multiple language variants and similar, became trivial. Also, the procedure of data exchange between the artist / GUI designer, and the programer, was greatly simplified.

All GUI related objects were then presented to the high level programmer as encapsulated objects. An example is given for GUI layer, a component of GUI box that represents either a single layer in the box, or a group of layers:

struct                tGUILayer {
  tPChar              name();
  GUI_layer           type();
  int                 id();
  int                 layers();
  tGUILayer*          layer(int sublayer);
  bool                shown();
  float               x();
  float               y();
  int                 z();
  GUI_align           alignX();
  //...
  tGUIBrush*          brush();
  GUI_blend           blend();
  float               opacity();
  GUI_select          select();
  int                 slide();
  void                move(float dx, float dy);
  //...
  void                restore_xy();
  void                restore_brush();
  void                restore_blend();
  //...
  void                run(tGUIFX* fx);
  void                run(const char* fx_template_name);
  tGUIFX*             running_first();
  int                 propI(const char* prop);
  float               propF(const char* prop);
  tPChar              propS(const char* prop);
  bool                pack(tPacket* dst);
  bool                unpack(tPacket* src);  
  tEventPipe*         pipe();
  void                set_pipe(tEventPipe* pipe);
};

Effects were scriptable, and plugins could be coded to extend the functionality. Effects included things like moving GUI controls around, or making a scrolling text appear inside a control, etc. Such approach offloads the burden of propagation of timed events from the main application.

I coded two renderers for Alfalfa GUI: a software renderer that supported features like alpha-blending and antialiased line rendering, and a hardware accelerated OpenGL renderer.

Persistence of objects

Every object supported by the library (even tPacket itself) may be stored into a tPacket object. tPacket object may then be sent through a tChannel to a different tProcess, saved into a file or some other persistent media.

This made it trivial to capture, for example, the current state of GUI and send it over to another process, reconstructing it there to mirror the state of the original.

Intermodular communication

I developed a system of pipes, queues and events. As the software in question needs resilience to be of industrial quality, all communication inside a process was to use the same mechanism as communication between processes. This would make logging and debugging much easier.

Interprocess communication

The intermodular communication was extended to support sending packets or events across to another process. This was done using a TCP/IP based protocol that supported up to 255 nodes within a private network of servers and clients. A single multiplayer game would therefore be organised as a small network with a fixed or variable number of clients and even servers.

State machine

An extension to the library was a state machine language, used to define and declare state machines that responded to events. An example of the language is given here:

BEGIN_MACHINE_EX(       hopper, tDeviceMachine)
  MACHINE_STATE(        ST_INIT)
  MACHINE_STATE(        ST_ERROR)
  MACHINE_STATE(        ST_DISCONNECTING)
  MACHINE_STATE(        ST_DONE)
  MACHINE_STATE(        ST_READY)
  MACHINE_STATE(        ST_BUSY)

  MACHINE_HANDLER(      on_INIT)
  MACHINE_HANDLER(      on_READY)
  MACHINE_HANDLER(      on_BUSY)
  MACHINE_HANDLER(      on_ERROR)
  MACHINE_HANDLER(      on_DISCONNECTING)
  MACHINE_HANDLER(      on_DONE)
  MACHINE_HANDLER(      on_PAYOUT)
  MACHINE_HANDLER(      on_BUSY_PAYOUT)

  MACHINE_FUNCTION(     void loop())
END_MACHINE
BEGIN_STATE(hopper,     ST_INIT)
  BEGIN_STATE_MAP
    MAP_TRANSITION(     ON_CONNECT,     ST_READY)
    MAP_TRANSITION(     ON_DISCONNECT,  ST_INIT)
    MAP_TRANSITION(     ON_ERROR,       ST_INIT)
    MAP_TRANSITION(     ON_QUIT,        ST_INIT)
  END_STATE_MAP

  STATE_SWITCHIN(       on_INIT)
END_STATE

The idea that I used here was specific in that only one file is used to actually declare and define all necessary classes, structures and functions to support a state machine class. Then this same file was included in (following the given example) both “hopper.h” and “hopper.cpp”, removing all the redundant duplication that often comes with meta programming.

Prototype

To demonstrate the capabilities of the library, I also created a fully working prototype for the TaiSai game. An actual 8-player machine was built, with a working wheel and a game server to support it. The only feature that was missing was the actual handling of accounting-related hardware, such as coin and bill acceptors, and the accounting itself.


Back to homepage

 
charon/past/alfastreet.txt · Last modified: 2015/11/18 07:37 by matija
Recent changes · Show pagesource · Login