BombSquad on fireTV!

I’m happy to announce BombSquad’s third official platform: Amazon Fire TV.
The game runs quite nicely on this little guy; I was able to crank the quality to high and add anti-aliasing and a few other bells and whistles. It supports GameCircle leaderboards and achievements, and I even got the remote usable as a controller.

12 controllers with a fireTV
12 controllers with a fireTV


I finally got around to putting together a little trailer for BombSquad… ¬†I apparently didn’t get the memo that this sort of things is generally done *before* a game is released ūüėČ

I’ll probably keep tweaking it over time, so let me know if you have any thoughts on it…


BombSquad Modding Guide Episode 6: Meteor Shower

Ok; enough with the expositional stuff already‚Ķ today we’re going to make an actual, playable, (hopefully) enjoyable mini-game.

It’s called ‘Meteor Shower’, and it’s pretty simple. You run around a platform as bombs fall from the sky at an ever increasing rate. The last team/player alive wins.

Here’s a video of me testing it:

To play, simply download the following file and stick it in BombSquad’s user-scripts dir. ¬†Poke the “Settings”->”Advanced”->”Show-Mods-Folder” button if you forgot where that is. You can then launch BombSquad, create a new teams or free-for-all playlist, and you should be able to add a ‘Meteor Shower’ game to it.

..And that’s it… To see what’s going on, just open the file and take a look at the code. I’ve commented it so you should be able to follow along. If you’re brave, take a stab at modifying it; see if you can change where or when the bombs fall, or change it to use a different map. Good luck!

BombSquad Modding Guide Episide 5: Core Concepts

This episode is just a brain-dump of basic scripting types and concepts, intended to be used as a reference guide. We’ll get back to writing code next episide. ¬†Anyway, let’s dive right in:

Classes to Be Familiar With:


Represents the entire set of games you are playing, and is in charge of swapping in activities for games, score-screens, etc. Current session types include Co-op, Teams, and Free-for-All.


An activity represents a single sub-unit of a session, of which one is current at a time (though multiple can exist briefly during transitions). Examples of activities include mini-games and score-screens.


These are BombSquad’s low level building blocks. At the most basic level, a BombSquad game script creates and manipulates these to construct a game experience.


Timers are used to run code at some point in the future, either once or in a repeating fashion. If the timer object dies (due to its reference count falling to zero) the timer will be cancelled, so make sure to store it as a field on your game/actor/etc if you want to keep it running.

If you want to create a single-shot timer that can’t be cancelled, you can use the bs.gameTimer() or bs.realTimer() functions.


Actors are a high-level building block implemented purely in Python. They generally encompass one or more nodes and handle message passing with other actors. Some example actors include bsSpaz.Spaz which is the standard character class and bsBomb.Bomb which is the standard explosive unit.


Concepts & Guidelines to Keep in Mind:

Reference counts, WeakRefs, and Activities

There are a few key concepts related to Python garbage collection to keep in mind when working in BombSquad. CPython, which BombSquad uses, has two methods for garbage-collection; in most cases objects are simply cleaned up when their reference-counts drop to zero, but there is also a fancier garbage-collector that runs periodically to clean up cases such as cyclical references. (Object A referencing object B which also references A). Be aware that BombSquad disables this second type of garbage collection to avoid hitches (though it does explicitly run it periodically at ‘safe’ times such as between games). Because of this, you should make sure to avoid dependency loops in your code, using weak-references or other methods as necessary.

A good way to debug references is to add a __del__() method to your objects containing a simple print statement. If you never see this print, your object is still alive because there’s a reference to it out there somewhere.

On a related note, be aware that BombSquad Activities are told to begin *only* after the previous Activity has been cleaned up, so you should be very careful about holding strong references to Activities. If you’re writing a Mini-Game and it gets ‘stuck’ after it ends, this is probably the problem. Familiarize yourself with weakref.ref and bs.WeakCall to help combat this.

bs.Call and bs.WeakCall

bs.Call is a convenient way to wrap up a Python callable along with arguments/keywords into a single callable object. This can be handy to pass to timers or other things that take callables as arguments. Example:


this will run myFunction(myArg1,myArg2) after 1 second of game time.  Be sure to avoid this common mistake:


The above code is calling myFunction *immediately* and passing the result to bs.gameTimer, which is most likely not what you want.

Bound methods and references

One important concept to keep in mind is that a bound method of an instance is actually a little object containing a reference to the instance (“self”) as well as to the method to call, so if you pass a bound method as a callback you’re going to keep that object instance alive, which is something you may not want.
Example: avoid things like this:


In this example the timer is going to hold onto the bound method (myActivity.handleTimeExpired) for 99 seconds, thus keeping a reference to myActivity, thus keeping it from being garbage collected and preventing another activity from starting for that 99 seconds.  Doh.
The proper thing to do here would be to use bs.WeakCall. This is just like Call, except if given a bound-method it will only keep a weak-reference to the instance, allowing it to be garbage-collected if its ref-count hits zero. (in which case calling it results in a no-op).
So the correct code would be:

bs.gameTimer(99000,bs.WeakCall(myActivity.handleTimeExpired)) this new code we won’t inadvertently keep myActivity alive, but it’ll still get its handleTimeExpired method called in 99 seconds if its still around.

Internal functions/variables

Please keep in mind that functions, classes, and variables starting with an underscore (‘_’) should be considered ‘private’ to BombSquad and not used, as they are subject to change at any time. Actually this is a general coding convention in Python; not just with BombSquad. If you need functionally that is not available via a public class or function, please email me and we’ll arrange something.

Avoid globals

This restriction may be eased in the future, but currently all nodes/textures/materials/etc become invalidated between sessions, so make sure to create and store these as part of your game/actor/etc; not in a global fashion.

BombSquad Modding Guide Episode 4: Writing Your First Mini-Game

Tutorial 3 was pretty long-winded, so if you made it through that it’s time for something simpler. ¬†Today we’re gonna write our very first mini-game.

Make sure you’ve done Tutorial 1 so you know how to issue commands to the game and Tutorial 3 so you know where to put game scripts.

This mini-game we’ll be making doesn’t actually do anything; it just ends after 5 seconds and gives all teams a score of 0, so the game comes out a draw. ¬†That’s ok though; the point is to show what a bare-bones mini-game looks like; we’ll make it fancier in a later tutorial.

When BombSquad gathers its list of mini-games, it simply scans through all modules in its user and system scripts directories looking for ones that define a ‘getGames()’ function.. ¬†so to add a game we simply have to write a module that provides that function.

Create a file named (or whatever you want to call it), paste the following code in, and drop it into BombSquad’s user-scripts directory. ¬† You can use the ‘Show Mods Folder’ button in Settings->Advanced if you’ve forgotten where this is. (‘mods folder’ is just another term for the user scripts directory).

import bs

# scripts specify an API-version they were written against
# so the game knows to ignore out-of-date ones.
def bsGetAPIVersion():
    return 3
# how BombSquad asks us what games we provide
def bsGetGames():
    return [HelloWorldGame]

class HelloWorldGame(bs.TeamGameActivity):

    def getName(cls):
        return 'Hello World Game'

    def getDescription(cls,sessionType):
        return 'Just a test game.'

    def onBegin(self):
        # game's starting - let's just set a timer to end it in 5 seconds
        bs.screenMessage("Hello World!  Ending in 5 seconds...")
        self._endGameTimer = bs.Timer(5000,bs.WeakCall(self.endGame))

    def endGame(self):
        # game's over - set a score for each team and tell our activity to finish
        ourResults = bs.TeamGameResults()
        for team in self.teams: ourResults.setTeamScore(team,0)

Now, to try out your shiny new mini-game, launch BombSquad, create a new game list, and add a game to it. ¬†You should see ‘Hello World Game’ in the list of available game types. ¬†When you run the game you should just see it print its message and end.

If you’d like documentation on any of these classes or methods, take a look at the BombSquad Python API Docs.

Well, that’s it for this tutorial.. ¬†next time we’ll start to add logic to our game to make it actually worth playing… stay tuned. ¬†(or if you’re impatient, you can look through BombSquad’s system scripts directory at all the built-in mini-games as reference)

The stuff of Eric Froemling