Getting Oriented with the Sifteo SDK

posted by daniel, 08 Jan 2013


Greetings gamemakers,

Welcome to the world of development on Sifteo cubes. Sifteo development is really cool, and the platform allows you to build games on hardware unlike anything else in the gaming world. That being said, building for Sifteo can be a bit different from what you might be used to, especially if you’re coming from a background like Flash or Processing. But do not despair, we’ve got a lot of great resources to get you up and running.

A note on audience. If you’re already an experienced C++ developer, the first few sections of this article should get you oriented with where to find what you need. Creators looking for a bit more direction will probably find the examples further down useful.

1. Getting Started: Download the free Sifteo SDK

Thanks to our cycle accurate hardware simulator, dubbed the “Siftulator” and packaged along with the SDK, you don’t need any hardware to begin developing on Sifteo. You’ll just need to download our SDK and open up your development environment of choice. Once you’re ready to deploy to some cubes, any of the sets available online or in stores will work for development.

To download the SDK, head over to www.sifteo.com/developers and click “Download Now”. Once you’ve set up a free developer account and accepted the terms of service you’ll be able to download the SDK. Feel free to unzip it wherever you’d like. Though a warning to Mac users, some functionality won’t work if the path to the SDK has spaces. For a more detailed description of what’s inside, and getting your first build running in just a few minutes, check out the Getting Started guide in our documentation.

2. Getting Familiarized: SDK Documentation and Examples

This is probably a good time to get familiarized with two of the best resources at your disposal when working on Sifteo, the SDK documentation and examples. The SDK docs include a full reference for all Sifteo libraries, and a great set of topic specific guides. The “/examples” folder in the SDK contains sets of working code examples that show off exactly how to implement many of Sifteo’s unique features.

The most peculiar thing you’ll see in Sifteo development is our mode-based graphics engine. The Sifteo cubes and base-station pack a lot into a very small, and relatively low cost package. This means there’s some interesting constraints the team had to work around developing the system. To handle the unique, multi-screen, distributed format, the platform employs a tile based rendering engine. It’s a system not unlike those you’d see on an old school NES or Gameboy. Its not hard to learn but you’ll want to peruse the documentation’s Graphics Engine guide sooner rather than later.

Along with how the graphics engine works, you’ll want to learn a bit about how to build assets for your games. The SDK docs have you covered here with the “Asset Workflow” guide.

3. Getting to Code: A quick guide to the examples folder

In our experience, a lot of folks like to start off looking through the Stars* demo, found in the examples folder. Stars uses the most common graphics mode you will see in Sifteo development, “BG0_SPR_BG1”, and is a solid example of how to:

  • initialize your program
  • draw assets to the screen
  • respond to accelerometer inputs from the cubes

Stars Running in the Siftulator

There’s a lot to be gained just from hacking about with Stars for a while and it can provide a base for a lot of good prototyping. We’ll deconstruct some of example’s code later in this post.

If you’re interested in how to interact with the cubes’ sensors, the Sensors example is the place to go. Sensors implements a program that covers neighboring, reading from the accelerometer, touches to the top screen, battery level, plus cube connection and disconnection events. It also demonstrates a production proper implementation of the SDK’s events architecture.

Once you’re familiar with the basics of how things work, the Membrane example is a fully functional game, with production quality code and architecture. Together, these three code examples cover a lot of useful information for new Sifteo developers.

4. Getting Running: Breaking Down Drawing with the Stars Example

As said above, the Stars example is a great place to get started learning about building a prototype with the Sifteo SDK. We’re going to look at how the example covers a few of the more common tasks new developers will want to understand. Things like basic setup, drawing to the screen with the most common graphics mode.

This breakdown assumes some knowledge of object oriented programming techniques and a very high level understanding of the C++ language. We’re not going to go into huge detail about each line of the example but we will cover where to find many of the basic concepts developers will be interested in.

The stars example is located in [sdkRoot]/examples/stars. Most everything in this example happens in the main.cpp file so lets open it up and take a look. The opening lines in the Stars demo handle a few things. Again, we won’t get into the details here, but at a basic level they are:

  • Define how many cubes the game expects.
  • Setup asset loading
  • Define the game’s metadata for the base’s loader. This covers things like what icon to use in the main menu.
using namespace Sifteo;

static const unsigned gNumCubes = 2;
Random gRandom;

static AssetSlot MainSlot = AssetSlot::allocate()
    .bootstrap(GameAssets);

static Metadata M = Metadata()
    .title("Stars SDK Example")
    .package("com.sifteo.sdk.stars", "1.0")
    .icon(Icon)
    .cubeRange(gNumCubes);

Before looking anywhere else, lets jump down to the main() method at the bottom of the program, line 195. Main is going to be where our game’s execution begins. Here we’ll initialize our cubes and define our game’s loop. The loop will be the commands that cycle repeatedly as long as the player has the game open.

void main()
{
    static StarDemo instances[gNumCubes];

    AudioTracker::play(Music);

    for (unsigned i = 0; i < arraysize(instances); i++)
        instances[i].init(i);
    
    TimeStep ts;
    while (1) {
        for (unsigned i = 0; i < arraysize(instances); i++)
            instances[i].update(ts.delta());

        System::paint();
        ts.next();
    }
}

Main initializes our instances of the StarDemo class and gets our main loop going. Within this loop, main calls the update function for each of our StarDemo instances, giving them each a chance to run their game logic. Once the instances are updated for this cycle it calls System::paint() to draw the new game state to the cubes. This explanation is an oversimplification of the graphics engine but is an accurate enough description for the purposes of getting started.

Next lets take a look at that init function we called earlier.

void init(CubeID cube)
{
    frame = 0;
    bg.x = 0;
    bg.y = 0;

    vid.initMode(BG0_SPR_BG1);
    vid.attach(cube);
    
    for (unsigned i = 0; i < numStars; i++)
        initStar(i);

    // Our background is 18x18 to match BG0, and it seamlessly tiles
    vid.bg0.image(vec(0,0), Background);

    // Allocate 16x2 tiles on BG1 for text at the bottom of the screen
    vid.bg1.setMask(BG1Mask::filled(vec(0,14), vec(16,2)));
}

Theres some pretty useful stuff in here. The first thing you may notice is that back in main() we passed init an int value but here we see that init takes a CubeID as it’s argument. What’s happening here is that CubeID is actually being implicitly cast to type int. Implicit casting is relatively common C++ concept but one that can throw off unfamiliar users.

Moving into the method body we get into our first bit of drawing code.

vid.initMode(BG0_SPR_BG1);
vid.attach(cube);

Here we’re taking our StarDemo’s instance of vid and initializing it to the graphics mode BG0_SPR_BG1. If you’ve looked through the Graphics Engine guide, you’ll recognize this as the mode that allows us to draw:

  • A background layer (BG0)
  • A layer with up to 8 individual sprites (SPR)
  • A foreground layer (BG1)

Background: BG0

The next interesting piece of video code is setting up the starfield background.

// Our background is 18x18 to match BG0, and it seamlessly tiles
vid.bg0.image(vec(0,0), Background);

We want to fill our background layer with a starfield image. vid.bg0.image draws an image to the BG0 layer. It takes a tile location and an image name (we get that image name from the assets.lua file in the example root.) For more on this look at the Asset Workflow guide).

Sifteo cubes use a left handed coordinate space. 0,0 is in the top left of the cube, with +X moving out to the right and +Y moving down. This is the same coordinate space you’re used to if you’re coming from Flash.

Foreground: BG1

Next we’re going to draw some text to the foreground layer, BG1.

// Allocate 16x2 tiles on BG1 for text at the bottom of the screen
vid.bg1.setMask(BG1Mask::filled(vec(0,14), vec(16,2)));

For Stars we want a 16 tile X 2 tile (128px X 16px) strip at the bottom of the cube to display text in front of everything else happening on screen. The above code masks that 16x2 strip so we can later draw to it the update loop, which begins on line 52.

Next we actually want to draw the text to BG1. You’ll note the series of calls to the writeText() function which is where this happens.

void writeText(const char *str)
{
    // Text on BG1, in the 16x2 area we allocated
    vid.bg1.text(vec(0,14), Font, str);
}

Writing text to BG1, is as simple as calling id.bg1.text and giving it a tile location (note this is the same location as our mask), a font to use (defined in our assets.lua) and the text to print.

Sprites

Now we can draw our star sprites. While sprites have an additional size constraint (each side must be a power of 2, starting with 8, though the sides do not have to be identical), they can be moved independently, in 1 pixel increments. This makes them very flexible.

Line 142 is the first line of a For loop where we iterate through all our active stars.

for (unsigned i = 0; i < numStars; i++) {
    const Float2 center = { 64 - 3.5f, 64 - 3.5f };
    vid.sprites[i].setImage(Star, frame % Star.numFrames());
    vid.sprites[i].move(stars[i].pos + center);
}

The VideoBuffer stores each of its 8 sprites at an index in its sprites array. So to tell the buffer that sprite 0 is a star, we say vid.sprites[0].setImage and pass it the image, Star, along with in this case a frame number. We’ll cover setting up animations soon in another tutorial but for now, know that the frames are setup in “assets.lua”. We place the sprite by calling vid.sprites[0].move which takes a Float2 variable representing the pixel location of the top left corner of the sprite.

So we’ve covered some of the basics of drawing to the BG0, SPR, and BG1 layers. There’s a lot more happening in the Stars example and you’re encouraged to read through more, change things around, and see what you can make. In the near future, we’ll share more examples on how to handle things like accelerometer input and animations, but in the meantime check out the docs and code examples, theres a lot there.

5. Getting Help: A few final points

We’re working hard to provide as much reference material as we can, but we know there’s always issues that crop up or things that don’t quite make sense. If you have any questions, comments, or feedback we’d love to hear them! The best place to get ahold of us is our support forums, at http://support.sifteo.com/categories/20026413-developer-info-forums. For some additonal reading, and some great advice on designing great Sifteo games, check out 12 tips for making a great Sifteo game by our Creative Director, Scott Kim.

Thanks for reading and happy game making!

blog comments powered by Disqus