Building Blocks

achievements Module

Represents achievements

Achievements are badges that are assigned to the player as they play the game. An achievement is basically a condition that is met. When you meet the condition you get the badge.

class serge.blocks.achievements.Achievement(name, description, badge, secret, test_type, condition=None, condition_string=None)[source]

Bases: serge.serialize.Serializable

Represents an achievement

index = 0
init()[source]

Initialise the achievement from pickling

isMet()[source]

Return True if the achievement was met

makeReport(**kw)[source]

Make a report on this achievement

my_properties = ('', '', '', 0, '', <serge.serialize.Obj object at 0x11340b650>, '', 0, 0.0)
resetStatus()[source]

Reset the status of the achievement

class serge.blocks.achievements.AchievementBanner(tag, name, background_layer, foreground_layer, behaviours, theme)[source]

Bases: serge.actor.MountableActor

A banner to show an achievement

addedToWorld(world)[source]

Added the banner to the world

hideMe(world, actor, interval)[source]

Hide this object

meetAchievement(achievement, arg)[source]

An achievement is met

class serge.blocks.achievements.AchievementManager[source]

Bases: serge.serialize.Serializable, serge.common.Loggable, serge.common.EventAware

Manages all the achievements in the game

getAchievements()[source]

Return the list of achievements

init()[source]

Initialise

initialiseFromFile(filename)[source]

Initialise from the file

log = <logging.Logger object>
makeReport(test_type, **kw)[source]

Make a report on achievements

my_properties = (<serge.serialize.Obj object at 0x11340b690>,)
registerAchievement(achievement)[source]

Register an achievement

resetAchievements()[source]

Reset all the achievements so that they have not been met

safeRegisterAchievement(achievement)[source]

Register an achievement and do not worry if it is already registered

saveAchievements()[source]

Save achievements to a file

class serge.blocks.achievements.AchievementStatus(tag, name, background_layer, foreground_layer, achievement, G)[source]

Bases: serge.actor.MountableActor

A banner to show an achievement

addedToWorld(world)[source]

Added the banner to the world

updateAchievement()[source]

Update the achievement view

class serge.blocks.achievements.AchievementsGrid(G)[source]

Bases: serge.blocks.actors.ScreenActor

A grid to show achievements

addedToWorld(world)[source]

Added the grid to the world

updateAchievements(obj, arg)[source]

Update all achievements

exception serge.blocks.achievements.BadCondition[source]

Bases: exceptions.Exception

The condition was not valid

exception serge.blocks.achievements.BadReport[source]

Bases: exceptions.Exception

An error occurred while evaluating the report

exception serge.blocks.achievements.BadTestType[source]

Bases: exceptions.Exception

The test type was not found

exception serge.blocks.achievements.DuplicateAchievement[source]

Bases: exceptions.Exception

An achievement with this name already exists

serge.blocks.achievements.addAchievementsBannerToWorld(world, front_layer, back_layer, theme, manager)[source]

Add a banner for achievements to the world

serge.blocks.achievements.addAchievementsWorld(options, theme)[source]

Add a world for the achievements

serge.blocks.achievements.getManager()[source]
serge.blocks.achievements.initManager(name)[source]

Initialise and return the manager

actors Module

Blocks to help with actors

class serge.blocks.actors.AnimateThenDieActor(tag, name, sprite_name, layer_name, parent=None)[source]

Bases: serge.actor.Actor

An actor that shows its animation and then is removed from the world

addedToWorld(world)[source]

Added the actor to the world

updateActor(interval, world)[source]

Update the actor

class serge.blocks.actors.FPSDisplay(x, y, font_colour, font_size, font_name='DEFAULT')[source]

Bases: serge.blocks.actors.NumericText

Displays the current FPS on the screen

addedToWorld(world)[source]

Added to the world

updateActor(interval, world)[source]

Update the actor

class serge.blocks.actors.FocusManager(tag, name)[source]

Bases: serge.actor.CompositeActor

Manages focus between a number of entry widgets

actorEntry(obj, actor)[source]

An entry was accepted

actorSelected(obj, actor)[source]

An actor was selected

addChild(actor)[source]

Add an actor to the manager

addedToWorld(world)[source]

We were added to the world

resetFocus()[source]

Reset the focus to make sure it is on an active object

Call this when you are altering the activity of different items in the focus group.

updateActor(interval, world)[source]

Update the manager

class serge.blocks.actors.FormattedText(tag, name, format, colour, font_name='DEFAULT', font_size=12, justify='center', fixed_char_width=None, **kw)[source]

Bases: serge.blocks.animations.AnimatedActor

A text display that can be formatted

getValue(name)[source]

Get the values

setValue(name, value)[source]

Set the value

updateText()[source]

Update our text

class serge.blocks.actors.FullScreenMenu(tag, name, items, layout, callback, background_colour=(0, 0, 0), font_colour=(255, 255, 255), font_size=12, font_name='DEFAULT')[source]

Bases: serge.actor.MountableActor

A full screen menu

menuClick(obj, arg)[source]

Menu item was clicked

setLayerName(name)[source]

Set the layer for the menu

exception serge.blocks.actors.InvalidMenu[source]

Bases: exceptions.Exception

The menu was not valid

exception serge.blocks.actors.InvalidMenuItem[source]

Bases: exceptions.Exception

The menu item was not understood

class serge.blocks.actors.MuteButton(sprite_name, layer_name, mute_sound=True, mute_music=True, alpha=1.0)[source]

Bases: serge.actor.Actor

A button to mute sound

toggleSound(obj=None, arg=None)[source]

Clicked on the button

class serge.blocks.actors.NumericText(*args, **kw)[source]

Bases: serge.blocks.actors.FormattedText

A helper actor to display some text with a single number in there

updateText()[source]

Update our text

value
class serge.blocks.actors.RepeatedVisualActor(tag, name=None, repeat=5, spacing=10, orientation='horizontal')[source]

Bases: serge.blocks.animations.AnimatedActor

An actor that shows multiple copies of a visual representation

This actor is useful for showing the number of lives or missiles etc in a game.

getRepeat()[source]

Return the current repeat

increaseRepeat(amount=1)[source]

Increase the repeat by a certain amount

reduceRepeat(amount=1)[source]

Reduce the repeat by a certain amount

renderTo(renderer, interval)[source]

Render to the given renderer

resetRepeat()[source]

Reset the repeat to the initial value

setRepeat(value)[source]

Set the current repeat

class serge.blocks.actors.ScreenActor(*args, **kw)[source]

Bases: serge.actor.CompositeActor

An actor to represent the logic associated with a screen of the game

This actor is useful when encapsulating the logic associated with a specific screen in the game. The actor has useful properties and methods that make it easy to manage the logic.

addedToWorld(world)[source]

The actor was added to the world

class serge.blocks.actors.SimplePhysicsActor(name, tag, velocity, angular_velocity, bounds=None, gravity=None)[source]

Bases: serge.blocks.animations.AnimatedActor

An actor that obeys simple physics of motion and rotation

updateActor(interval, world)[source]

Update the actor

class serge.blocks.actors.StringText(tag, name, text, format='%s', colour=(255, 255, 255), font_name='DEFAULT', font_size=12, justify='center', **kw)[source]

Bases: serge.blocks.actors.FormattedText

A helper actor to display some text with text in there

updateText()[source]

Update our text

value
class serge.blocks.actors.TextEntryWidget(tag, name, width, height, colour, font_size, font_name='DEFAULT', justify='center', background_visual=None, background_layer='background', show_cursor=False, blink_time=0.5, has_focus=True)[source]

Bases: serge.actor.MountableActor

Implements a single line text entry widget

Support letters and numbers. Delete, backspace and left all delete the last character. Enter triggers an ACCEPT event.

addedToWorld(world)[source]

Added to the world

getFocus()[source]

Get the focus

getText()[source]

Return the text value

hasFocus()[source]

Return True if we have focus

loseFocus()[source]

Lose the focus

setCursorAtEnd()[source]

Set the cursor at the end position

setCursorAtStart()[source]

Set the cursor at the start position

setLayerName(layer_name)[source]

Set the layer name

setText(text)[source]

Set the text value

updateActor(interval, world)[source]

Update the entry widget

class serge.blocks.actors.ToggledMenu(tag, name, items, layout, default, on_colour, off_colour, width=100, height=100, callback=None, font_colour=(255, 255, 255, 255), font_name='DEFAULT', font_size=12, mouse_over_colour=None)[source]

Bases: serge.actor.MountableActor

Implements a menu of options that can be toggled

The layout of the options will be determined by the layout object. Items will be added to the layout in the order they are specified.

The callback provided will be called whenever the selection changes. The function will be called with the menu object and the name of the option selected.

callback(menuObject, newOption)
clearSelection()[source]

Clear the active selection

getSelection()[source]

Return the current selection

getSelectionIndex()[source]

Return the current selection index

selectItem(name, do_callback=True)[source]

Select an item by name

selectItemIndex(index)[source]

Select an item by its index

setLayerName(layer_name)[source]

Set the layer name

setupMenu(items)[source]

Setup all the menu items

updateActor(interval, world)[source]

Update the actor

animations Module

Classes to help animating actors

exception serge.blocks.animations.AlreadyPaused[source]

Bases: exceptions.Exception

Tried to pause when an animation was already paused

class serge.blocks.animations.AnimatedActor(tag, name=None)[source]

Bases: serge.actor.Actor

Implements an actor that can have animations applying to it

addAnimation(animation, name)[source]

Add an animation to this actor

addRegisteredAnimation(name)[source]

Add an animation from the animation registry

addRegisteredAnimations(names)[source]

Add a number of animations from the animation registry

animationsPaused()[source]

Return True if our animations are paused

completeAnimations()[source]

Complete all animations

getAnimation(name)[source]

Return the named animation

getAnimations()[source]

Return all the animations

pauseAnimations(safe=False)[source]

Pause all animations

removeAnimation(name)[source]

Remove a named animation

removeAnimations()[source]

Remove all the animations

removeAnimationsMatching(pattern)[source]

Remove all animations matching a matching pattern

restartAnimations()[source]

Restart all animations

unpauseAnimations(safe=False)[source]

Start all animations

updateActor(interval, world)[source]

Update the actor

class serge.blocks.animations.Animation(duration=1000, done=None, loop=False, paused=False)[source]

Bases: serge.blocks.effects.Effect

The basic animation class

finish()[source]

Finish the effect

init()[source]

Initialise the properties

my_properties = (0.0, 0.0, 0.0)
pauseAtNextCycle()[source]

Set the animation to pause at the next time it renews a cycle

restart()[source]

Restart the animation

setActor(actor)[source]

Set our actor

setName(name)[source]

Set our name

unpause()[source]

Un-pause the animation

update()[source]

The main method implementing the animation effect

This is the method you should implement

updateActor(interval, world)[source]

Update the animation effect

exception serge.blocks.animations.AnimationExists[source]

Bases: exceptions.Exception

An animation already exists with the same name

exception serge.blocks.animations.AnimationNotFound[source]

Bases: exceptions.Exception

The animation was not found

class serge.blocks.animations.AnimationRegistry[source]

Bases: serge.registry.GeneralStore

A place to register animations so they can be easily re-used

getItem(name)[source]

Return an animation

We need to deepcopy the animation to avoid returning the same one each time.

class serge.blocks.animations.ColourCycle(obj, start_colour, end_colour, duration, attribute='colour', loop=False, done=None)[source]

Bases: serge.blocks.animations.Animation

Animate the colour property of an object between a beginning and end

setColour(colour)[source]

Set the colour

update()[source]

Update the colour of the object

class serge.blocks.animations.ColourText(obj, start_colour, end_colour, duration, attribute='colour', loop=False, done=None)[source]

Bases: serge.blocks.animations.ColourCycle

Animate the colour of a text object by calling its setColour method

setColour(colour)[source]

Set the colour

class serge.blocks.animations.MouseOverAnimation(duration, mouse_over_only, loop=False, done=None, paused=False)[source]

Bases: serge.blocks.animations.Animation

A base class to use for animations that can be activated by mouse over

Animations extending this class can set mouse_over_only to True and then the animation will run only when the mouse is over the actor. When the mouse moves out then the animation will run to the beginning of the cycle and then stop.

init()[source]

Initialise the animation

my_properties = (0,)
updateActor(interval, world)[source]

Update the animation

class serge.blocks.animations.MouseOverSound(sound)[source]

Bases: serge.blocks.animations.Animation

Plays a sound when mousing over something

init()[source]

Initialise the animation

my_properties = ('', 0)
update()[source]

Update the animation

class serge.blocks.animations.MoveWithVelocity[source]

Bases: serge.blocks.animations.Animation

Animate the motion of an actor with a constant velocity

my_properties = (0.0, 0.0)
update()[source]

Update the actor

class serge.blocks.animations.MovementTweenAnimation(obj, *args, **kw)[source]

Bases: serge.blocks.animations.TweenAnimation

Tweens the position of an actor between two locations

setValue(value)[source]

Set the position

exception serge.blocks.animations.NotPaused[source]

Bases: exceptions.Exception

Tried to start when an animation was not paused

class serge.blocks.animations.PulseRotate(min_angle, max_angle, duration, loop=False, done=None, mouse_over_only=False, paused=False)[source]

Bases: serge.blocks.animations.MouseOverAnimation

Cycle the rotation of an actor between a high and low value

The rotation limits are set as the min and max angle. The actual start point of the animation is half way between the two. This means that if you stop it on a cycle it will return to the mid point.

my_properties = (0.0, 0.0)
update()[source]

Update the angle of the object

class serge.blocks.animations.PulseZoom(start_zoom, end_zoom, duration, loop=False, done=None, mouse_over_only=False, paused=False)[source]

Bases: serge.blocks.animations.MouseOverAnimation

Cycle the zoom of an actor between a high and low value

my_properties = (0.0, 0.0)
update()[source]

Update the zoom of the object

class serge.blocks.animations.PulsedVisibility(duration, on_fraction=0.5)[source]

Bases: serge.blocks.animations.Animation

An animation that turns an actor on and off with visibility

my_properties = (0.5,)
update()[source]

Update the animation

class serge.blocks.animations.TweenAnimation(obj, attribute, start, end, duration, function=None, delay=0, after=None, repeat=False, ping_pong=True, integer=False, set_immediately=True, is_method=False)[source]

Bases: serge.blocks.animations.Animation

Tween a variable

static colourTween(fraction, start, end)[source]

Tween a colour

static linearTween(fraction, start, end)[source]

Linear tween from start to end

static randomColour(fraction, start, end)[source]

Tween a random colour

setValue(value)[source]

Set the value

static sinInOut(fraction, start, end)[source]

Sine out tween

static sinOut(fraction, start, end)[source]

Sine out tween

update()[source]

Perform the tween

behaviours Module

Classes the implement behaviours

class serge.blocks.behaviours.AvoidActor(actor, x_speed=1, y_speed=1, distance=10)[source]

Bases: serge.blocks.behaviours.Behaviour

Move away from an actor until you reach a certain distance

class serge.blocks.behaviours.AvoidActorsWithTag(tag, x_speed=1, y_speed=1, distance=10)[source]

Bases: serge.blocks.behaviours.Behaviour

Move away from multiple actors until you read a certain distance

class serge.blocks.behaviours.Behaviour[source]

Bases: serge.common.Loggable

Base class for all behaviours

exception serge.blocks.behaviours.BehaviourAlreadyPaused[source]

Bases: exceptions.Exception

The behaviour was already paused

class serge.blocks.behaviours.BehaviourManager(*args, **kw)[source]

Bases: serge.actor.Actor

Manages the behaviour of multiple actors in a world

assignBehaviour(actor, behaviour, name)[source]

Assign a behaviour to an actor

hasBehaviour(record)[source]

Return True if we have a particular behaviour record

pauseBehaviours(name)[source]

Pause all behaviours with the name

removeBehaviour(record)[source]

Remove a particular behaviour

removeBehaviourByName(actor, name)[source]

Remove the named behaviour for an actor based on its name

removeBehaviours(behaviours)[source]

Remove a list of behaviours

removeBehavioursByName(name)[source]

Remove the named behaviour for all actors based on a name

restartBehaviours(name)[source]

Restart all behaviours with the name

updateActor(world, interval)[source]

Perform all our behaviours

exception serge.blocks.behaviours.BehaviourNotPaused[source]

Bases: exceptions.Exception

The behaviour was not paused

class serge.blocks.behaviours.BehaviourRecord(actor, behaviour, name)[source]

Bases: object

Represents a record of a requested behaviour

getBehaviour()[source]

Return the behaviour we are executing

involvesActor(actor)[source]

Return True if the behaviour involves the actor

isComplete()[source]

Return True if we are complete

isRunning()[source]

Return True if we are running

markComplete()[source]

Mark the behaviour as complete

The manage can now remove us and no longer try calling.

matches(actor, name)[source]

Return True if this behaviour matches the actor and name

matchesName(name)[source]

Return True if this behaviour matches the name

pause()[source]

Pause the behaviour

performBehaviour(interval, world)[source]

Perform the actual behaviour

restart()[source]

Restart the behaviour

Bases: serge.blocks.behaviours.Behaviour

Blink an actor on the screen

class serge.blocks.behaviours.ConstantVelocity(vx, vy)[source]

Bases: serge.blocks.behaviours.Behaviour

Move an actor with a constant velocity

class serge.blocks.behaviours.Delay(interval)[source]

Bases: serge.blocks.behaviours.TimedOneshotCallback

A delay - just waits and then completes

Usefor for sequences

exception serge.blocks.behaviours.DuplicateBehaviour[source]

Bases: exceptions.Exception

The behaviour was already recorded

class serge.blocks.behaviours.FlashFor(actor, time)[source]

Bases: serge.blocks.behaviours.Behaviour

Flash an actor on the screen

When the actor is flashing the property flashing is True.

class serge.blocks.behaviours.KeyboardBackWorld(key=27, sound_name=None, safe_quit=True)[source]

Bases: serge.blocks.behaviours.Behaviour

Return to the previous world based on a keypress

class serge.blocks.behaviours.KeyboardNSEW(speed, n=273, s=274, e=275, w=276)[source]

Bases: serge.blocks.behaviours.Behaviour

Move an actor in ordinal directions according to the keyboard

Set the n, s, e and w to the keys you want to move the actor. If you do not want any motion then set that direction to None. Set the speed to be the amount to move per keypress.

class serge.blocks.behaviours.KeyboardNSEWToVectorCallback(method, event='key-clicked', speed=1, n=273, s=274, e=275, w=276)[source]

Bases: serge.blocks.behaviours.Behaviour

Calls a method with direction vector from ordinal directions according to the keyboard

Set the n, s, e and w to the keys you want to move the actor. If you do not want any motion then set that direction to None. Set the speed to be the amount to move per keypress.

This is useful when you want to move an object but you need to do some preprocessing first. This behaviour will allow you to capture the keypresses.

class serge.blocks.behaviours.KeyboardQuit(key=27)[source]

Bases: serge.blocks.behaviours.Behaviour

Quit the game based on a keypress

exception serge.blocks.behaviours.MissingBehaviour[source]

Bases: exceptions.Exception

Could not locate the behaviour

class serge.blocks.behaviours.MoveTowardsActor(actor, x_speed=1, y_speed=1)[source]

Bases: serge.blocks.behaviours.Behaviour

Move an actor towards another actor

class serge.blocks.behaviours.MoveTowardsPoint(point, x_speed=1, y_speed=1, remove_when_there=False)[source]

Bases: serge.blocks.behaviours.Behaviour

Move an actor towards a point

class serge.blocks.behaviours.MoveWithMouse(actor)[source]

Bases: serge.blocks.behaviours.Behaviour

Move the actor with the mouse

class serge.blocks.behaviours.OneShotSequence(sequence)[source]

Bases: serge.blocks.behaviours.Behaviour

A behaviour that calls a sequence of other behaviours

class serge.blocks.behaviours.Optional(behaviour, arg, selector)[source]

Bases: serge.blocks.behaviours.TwoOptions

A behaviour that is turned on and off by an option

class serge.blocks.behaviours.ParallaxMotion[source]

Bases: serge.blocks.behaviours.Behaviour

Move one object in relation to another

Parameters:
  • parent – the object to move relative to
  • sx – fraction of x movement relative to parent (0.0 = no parallax, 1.0 = stationary)
  • sy – fraction of y movement relative to parent
class serge.blocks.behaviours.RemoveWhenOutOfRange(x_range, y_range)[source]

Bases: serge.blocks.behaviours.Behaviour

Remove an actor from the world when it is out of a certain range

class serge.blocks.behaviours.SnapshotOnKey(key=115, size=(0, 0, 800, 600), location='', overwrite=True)[source]

Bases: serge.blocks.behaviours.Behaviour

Take a snapshot of the screen when the user presses a key

class serge.blocks.behaviours.SpringTowardsPoint(point, spring_constant, damping, dead_zone=0.1)[source]

Bases: serge.blocks.behaviours.Behaviour

Move an actor towards a point as if on a spring

class serge.blocks.behaviours.TimedCallback(interval, callback)[source]

Bases: serge.blocks.behaviours.Behaviour

A callback that gets called at a certain interval

class serge.blocks.behaviours.TimedOneshotCallback(interval, callback)[source]

Bases: serge.blocks.behaviours.TimedCallback

A callback that gets called once and only once at an interval

class serge.blocks.behaviours.Tooltip(actors, theme, attribute_name)[source]

Bases: serge.blocks.behaviours.Behaviour

A tooltip behaviour that displays a message when you mouse over one of a number of actors

You specify a list of actors and some parameters of the tip via the theme and the name of an attribute to use from the actor. The attribute is the text used for the tip. If the content of the attribute is None then the tooltip will not be shown.

You give the theme object of the tooltip theme. It should contain,

size : (width, height), backcolour : (r,g,b), strokecolour : (r,g,b), strokewidth : int, layer : layer_name, fontsize : int, fontcolour : (r, g, b) hidetime : seconds_to_hide
class serge.blocks.behaviours.TwoOptions(b1, b2, arg, selector)[source]

Bases: serge.blocks.behaviours.Behaviour

A behaviour that chooses between two optional behaviours

behaviourtree Module

Implementation of behaviour trees for AI

class serge.blocks.behaviourtree.Action(name)[source]

Bases: serge.blocks.behaviourtree.Node

An action node - performs an action that could take many ticks

doAction(context)[source]

Perform the action - should be a generator

onStart()[source]

Initialise the action

onTick(context)[source]

Tick the node

class serge.blocks.behaviourtree.AlwaysFail(name, node)[source]

Bases: serge.blocks.behaviourtree.Decorator

A decorator node that always results in failure

postProcessNode(context)[source]

Post process result

class serge.blocks.behaviourtree.AlwaysSucceed(name, node)[source]

Bases: serge.blocks.behaviourtree.Decorator

A decorator node that always results in success

postProcessNode(context)[source]

Post process result

class serge.blocks.behaviourtree.Condition(name, fn)[source]

Bases: serge.blocks.behaviourtree.Node

A condition node that checks for something

onTick(context)[source]

Tick the node

class serge.blocks.behaviourtree.Decorator(name, node)[source]

Bases: serge.blocks.behaviourtree.Node

A decorator - calls a child and does something

onTick(context)[source]

Tick the node

postProcessNode(context)[source]

Post process the node

resetNode()[source]

Reset the node

class serge.blocks.behaviourtree.IterationNode(name, nodes)[source]

Bases: serge.blocks.behaviourtree.Node

A base class of nodes that iterate over their children

pass_through_state = 'none'
resetNode()[source]

Reset the node

class serge.blocks.behaviourtree.Loop(name, node)[source]

Bases: serge.blocks.behaviourtree.Decorator

A looping node - loops its child as long as it returns success

postProcessNode(context)[source]

Post process - if the node is finished then reset it and continue running

class serge.blocks.behaviourtree.Node(name)[source]

Bases: serge.common.Loggable

A node in the tree

S_EXCEPTION = 'exception'
S_FAILURE = 'failure'
S_NONE = 'none'
S_RUNNING = 'running'
S_SUCCESS = 'success'
getNiceName()[source]

Nice name for debugging etc

onStart()[source]

Do node initialisation

onTick(context)[source]

Tick the node

resetNode()[source]

Reset the node to its initial state

class serge.blocks.behaviourtree.Parallel(name, nodes)[source]

Bases: serge.blocks.behaviourtree.IterationNode

A parallel node - child nodes are processed each iteration

The resulting state comes from the highest priority from failure, running, success.

node_priorities = {'failure': 1, 'none': 0, 'running': 2, 'success': 3}
onTick(context)[source]

Tick the node

pass_through_state = 'failure'
class serge.blocks.behaviourtree.Selector(name, nodes)[source]

Bases: serge.blocks.behaviourtree.SeriesIteration

A selector node - child nodes are processed in sequence until one succeeds

pass_through_state = 'failure'
processChildNodes(context)[source]

Process the children - return True if we should keep processing

class serge.blocks.behaviourtree.Sequence(name, nodes)[source]

Bases: serge.blocks.behaviourtree.SeriesIteration

A sequence node - child nodes are processed in sequence until all succeed or one fails

pass_through_state = 'success'
processChildNodes(context)[source]

Process the children - return True if we should keep processing

class serge.blocks.behaviourtree.SeriesIteration(name, nodes)[source]

Bases: serge.blocks.behaviourtree.IterationNode

Process children in series

onStart()[source]

Initialise the node

onTick(context)[source]

Tick the sequence

processChildNodes(context)[source]

Process the children - return True if we should keep processing

class serge.blocks.behaviourtree.Tree[source]

Bases: serge.common.Loggable

A behaviour tree implementation

addNode(node)[source]

Add a node

addNodes(nodes)[source]

Add nodes

numberOfNodes()[source]

Return the number of nodes

onTick(context)[source]

Tick the tree

cards Module

Simple card system

class serge.blocks.cards.Card(name)[source]

Bases: object

A card for use in a card game

class serge.blocks.cards.CardCollection[source]

Bases: object

A collection of cards

addCardToTop(card)[source]

Add a card to the top of the deck

addCardsToTop(cards)[source]

Add multiple cards to the top of the deck

clearCards()[source]

Clear all the cards

containsCard(card)[source]

Return True if the collection contains the card

drawSpecificCard(card)[source]

Withdraw a specific card from the collection

drawTopCard()[source]

Draw the top card

drawTopCards(number)[source]

Return a number of cards from the top of the deck

getCards()[source]

Return all the cards

numberOfCards()[source]

Return the number of cards in the deck

shuffleCards()[source]

Shuffle the cards

exception serge.blocks.cards.CardNotFound[source]

Bases: exceptions.Exception

The card was not found

class serge.blocks.cards.Deck[source]

Bases: serge.blocks.cards.CardCollection

A deck of cards

exception serge.blocks.cards.NoCard[source]

Bases: exceptions.Exception

The collection was empty

class serge.blocks.cards.StandardCard(suit, card)[source]

Bases: serge.blocks.cards.Card

A standard card

CLUB = 'Club'
DIAMOND = 'Diamond'
HEART = 'Heart'
SPADE = 'Spade'
SUITS = ['Heart', 'Diamond', 'Club', 'Spade']
class serge.blocks.cards.StandardDeck[source]

Bases: serge.blocks.cards.Deck

A deck of standard cards

concurrent.futures Module

Execute computations asynchronously using threads or processes.

conversation Module

Represents a conversation

A conversation is a set of nodes with optional branches afterwards.

Each node has some text, either a single line or multiple lines.

exception serge.blocks.conversation.BadOption[source]

Bases: exceptions.Exception

The option was not found

class serge.blocks.conversation.ConversationManager(tree, callback=None, root=None, variables=None)[source]

Bases: serge.common.Loggable, serge.common.EventAware

Manages a conversation

chooseOption(name)[source]

Choose an option named name

findNode(*names)[source]

Return the node with the given name

findNodeByID(ID)[source]

Return the node with the given ID

classmethod fromXMLFile(filename)[source]

Load from an XML filename

getChild()[source]

Return the first child

getChildren()[source]

Return the children

Return a link or None if we don’t have one

getNewManager(parent)[source]

Return a new manager pointing to the parent

getNodeVariables(node)[source]

Return the variables for this node

getParent()[source]

Return the parent node

getText()[source]

Return the text for this node

getVariable(name)[source]

Return the value of a variable

moveNext()[source]

Move on to the next node

parseRichText(lines, data)[source]

Return the variables and text from a rich text list

processNodeVariables(node)[source]

Process variables in the current node

restartConversation()[source]

Try to restart the conversation

setCallback(callback)[source]

Set the callback

exception serge.blocks.conversation.InvalidFile[source]

Bases: exceptions.Exception

The XML file was not valid

exception serge.blocks.conversation.NodeNotFound[source]

Bases: exceptions.Exception

The node was not found in the tree

directions Module

Utilities to do with cardinal directions

serge.blocks.directions.getAngleFromCardinal(direction)[source]

Return the angle for a cardinal direction

serge.blocks.directions.getAngleFromVector(vector)[source]

Return the angle for a vector

serge.blocks.directions.getCardinalFromAngle(angle)[source]

Return the cardinal for an angle

serge.blocks.directions.getCardinalFromVector(vector)[source]

Return the cardinal name from the vector

serge.blocks.directions.getCardinals()[source]

Return the cardinal directions by name

serge.blocks.directions.getOppositeCardinal(cardinal)[source]

Return the opposite cardinal direction

serge.blocks.directions.getOppositeVector(vector)[source]

Return the opposite vector

serge.blocks.directions.getVectorFromCardinal(direction)[source]

Return the vector for a cardinal direction

dragndrop Module

Implements drag and drop behaviour

exception serge.blocks.dragndrop.AlreadyATarget[source]

Bases: exceptions.Exception

The actor is a target already

exception serge.blocks.dragndrop.BadConstraint[source]

Bases: exceptions.Exception

The constraint was invalid

class serge.blocks.dragndrop.DragController(tag='controller', name='controller', start=None, stop=None, hit=None, miss=None)[source]

Bases: serge.blocks.actors.ScreenActor

Controls objects which are draggable

addActor(actor, start=None, stop=None, x_constraint=None, y_constraint=None)[source]

Add an actor to be controlled and callback to be called when dragging start and stops

addDropTarget(actor, fn=None)[source]

Add a target to drop to

checkForDrops(actor)[source]

Check to see if we dropped our actor onto a target or not - return False if the drop is not allowed

If we dropped on a target then we can call the callback. If we didn’t drop on a target then we call the miss callback.

The callback can raise DropNotAllowed to cause the drop not to occur

clickedActor()[source]

The mouse was released over an actor

getDraggable(actor)[source]

Return the draggable for the actor

getDraggedActor()[source]

Return the actor being dragged

isDragging()[source]

Return True if we are dragging an object

mouseDown()[source]

The mouse was down over an actor

removeActor(actor)[source]

Remove an actor from being controlled

removeDropTarget(actor)[source]

Remove an actor as a drop target

setCallbacks(start, stop)[source]

Set the callbacks to use when starting and stopping a drag

setDropCallbacks(hit, miss)[source]

Set the callback to use when dropping on a target

updateActor(interval, world)[source]

Update the controller

class serge.blocks.dragndrop.DragItem(obj, start, stop, x_constraint, y_constraint)[source]

Bases: object

An item to be dragged

getXYValue(dx, dy)[source]

Return the new x and y value honoring the constraints

exception serge.blocks.dragndrop.DropNotAllowed[source]

Bases: exceptions.Exception

Cannot drop here

exception serge.blocks.dragndrop.DuplicateActor[source]

Bases: exceptions.Exception

The actor is already controlled

exception serge.blocks.dragndrop.NotATarget[source]

Bases: exceptions.Exception

The actor is not a target

exception serge.blocks.dragndrop.NotDragging[source]

Bases: exceptions.Exception

No actor is being dragged

effects Module

Some effects which can alter properties of actors or visuals

class serge.blocks.effects.AttributeFade(obj, attribute_name, *args, **kw)[source]

Bases: serge.blocks.effects.MethodCallFade

Linearly move an attribute

The attribute changes between a start and an end with a decay. The decay is the length of time taken to get from the start to the end.

If persistent is set to true then the effect remains in the world to be re-used. If false then it will be removed when completed.

class serge.blocks.effects.ColourPhaser(red, green, blue, *args, **kw)[source]

Bases: serge.blocks.effects.Effect

An effect that causes colours on the whole screen to fade in and out

addedToWorld(world)[source]

We were added to a wolrd

postRender(obj, arg)[source]

Update this effect

worldChange(obj, active)[source]

The world changed its state

Since we are linked to a renderer event we will be called from all worlds but we only want to be active when our world is the ative one. We use the world activation events to toggle our state.

class serge.blocks.effects.Effect(done=None, persistent=False)[source]

Bases: serge.actor.Actor

A generic effect

finish()[source]

End the effect

init()[source]

Initialise the effect

my_properties = (0, 0, 0, 0)
pause()[source]

Pause the effect

restart()[source]

Restart the effect

unpause()[source]

Unpause the effect

exception serge.blocks.effects.InvalidMotion[source]

Bases: exceptions.Exception

The motion type was not recognized

class serge.blocks.effects.MethodCallFade(method, start, end, decay, persistent=False, done=None, motion='linear')[source]

Bases: serge.blocks.effects.Effect

Repeated call a method linearly changing the parameter over time

The attribute changes between a start and an end with a decay. The decay is the length of time taken to get from the start to the end.

If persistent is set to true then the effect remains in the world to be re-used. If false then it will be removed when completed.

A method can be provided through the done parameter which will be called when the effect has completed.

The way the variable is moved is dependent on the motion type. This can be ‘linear’ or ‘accelerated’.

updateActor(interval, world)[source]

Update this effect

class serge.blocks.effects.PanActor(actor, speed, done=None, persistent=False, linear=True)[source]

Bases: serge.blocks.effects.Effect

Pan an actor across the screen

restart()[source]

Restart the panning

updateActor(interval, world)[source]

Update the panning

class serge.blocks.effects.Pause(time, done, persistent=False)[source]

Bases: serge.blocks.effects.Effect

A simple pause

Used in conjunction with other effects. Calls the done method when the pause has completed.

updateActor(interval, world)[source]

Update this effect

fractals Module

Some fractal utilities

serge.blocks.fractals.fractalLine(start, end, number_steps, distance_per_step, decay)[source]

Return a fractal line, broken into # steps with each step being a random distance

serge.blocks.fractals.fractalShape(points, number_steps, distance_per_step, decay)[source]

Return a shape where the straight lines are converted to fractal lines

fysom Module

USAGE

from fysom import Fysom

fsm = Fysom({

‘initial’: ‘green’, ‘events’: [

{‘name’: ‘warn’, ‘src’: ‘green’, ‘dst’: ‘yellow’}, {‘name’: ‘panic’, ‘src’: ‘yellow’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘yellow’}, {‘name’: ‘clear’, ‘src’: ‘yellow’, ‘dst’: ‘green’}

]

})

... will create an object with a method for each event:

  • fsm.warn() - transition from ‘green’ to ‘yellow’
  • fsm.panic() - transition from ‘yellow’ to ‘red’
  • fsm.calm() - transition from ‘red’ to ‘yellow’
  • fsm.clear() - transition from ‘yellow’ to ‘green’

along with the following members:

  • fsm.current - contains the current state

  • fsm.isstate(s) - return True if state s is the current state

  • fsm.can(e) - return True if event e can be fired in the current

    state

  • fsm.cannot(e) - return True if event s cannot be fired in the

    current state

MULTIPLE SRC AND TO STATES FOR A SINGLE EVENT

fsm = Fysom({

‘initial’: ‘hungry’, ‘events’: [

{‘name’: ‘eat’, ‘src’: ‘hungry’, ‘dst’: ‘satisfied’}, {‘name’: ‘eat’, ‘src’: ‘satisfied’, ‘dst’: ‘full’}, {‘name’: ‘eat’, ‘src’: ‘full’, ‘dst’: ‘sick’}, {‘name’: ‘rest’, ‘src’: [‘hungry’, ‘satisfied’, ‘full’, ‘sick’],

‘dst’: ‘hungry’}

]

})

This example will create an object with 2 event methods:

  • fsm.eat()
  • fsm.rest()

The rest event will always transition to the hungry state, while the eat event will transition to a state that is dependent on the current state.

NOTE the rest event in the above example can also be specified as multiple events with the same name if you prefer the verbose approach.

CALLBACKS

4 callbacks are available if your state machine has methods using the following naming conventions:

You can affect the event in 2 ways:

  • return False from an onbefore_event_ handler to cancel the event.
  • return False from an onleave_state_ handler to perform an asynchronous state transition (see next section)

For convenience, the 2 most useful callbacks can be shortened:

In addition, a generic onchangestate() calback can be used to call a single function for all state changes.

All callbacks will be passed one argument ‘e’ which is an object with following attributes:

  • fsm Fysom object calling the callback

  • event Event name

  • src Source state

  • dst Destination state

  • (any other keyword arguments you passed into the original event

    method)

Note that when you call an event, only one instance of ‘e’ argument is created and passed to all 4 callbacks. This allows you to preserve data across a state transition by storing it in ‘e’. It also allows you to shoot yourself in the foot if you’re not careful.

Callbacks can be specified when the state machine is first created:

def onpanic(e): print ‘panic! ‘ + e.msg def oncalm(e): print ‘thanks to ‘ + e.msg def ongreen(e): print ‘green’ def onyellow(e): print ‘yellow’ def onred(e): print ‘red’

fsm = Fysom({

‘initial’: ‘green’, ‘events’: [

{‘name’: ‘warn’, ‘src’: ‘green’, ‘dst’: ‘yellow’}, {‘name’: ‘panic’, ‘src’: ‘yellow’, ‘dst’: ‘red’}, {‘name’: ‘panic’, ‘src’: ‘green’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘yellow’}, {‘name’: ‘clear’, ‘src’: ‘yellow’, ‘dst’: ‘green’}

], ‘callbacks’: {

‘onpanic’: onpanic, ‘oncalm’: oncalm, ‘ongreen’: ongreen, ‘onyellow’: onyellow, ‘onred’: onred

}

})

fsm.panic(msg=’killer bees’) fsm.calm(msg=’sedatives in the honey pots’)

Additionally, they can be added and removed from the state machine at any time:

def printstatechange(e):
print ‘event: %s, src: %s, dst: %s’ % (e.event, e.src, e.dst)

del fsm.ongreen del fsm.onyellow del fsm.onred fsm.onchangestate = printstatechange

ASYNCHRONOUS STATE TRANSITIONS

Sometimes, you need to execute some asynchronous code during a state transition and ensure the new state is not entered until you code has completed.

A good example of this is when you run a background thread to download something as result of an event. You only want to transition into the new state after the download is complete.

You can return False from your onleave_state_ handler and the state machine will be put on hold until you are ready to trigger the transition using transition() method.

Example: TODO

INITIALIZATION OPTIONS

How the state machine should initialize can depend on your application requirements, so the library provides a number of simple options.

By default, if you don’t specify any initial state, the state machine will be in the ‘none’ state and you would need to provide an event to take it out of this state:

fsm = Fysom({
‘events’: [
{‘name’: ‘startup’, ‘src’: ‘none’, ‘dst’: ‘green’}, {‘name’: ‘panic’, ‘src’: ‘green’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘green’},

]

}) print fsm.current # “none” fsm.startup() print fsm.current # “green”

If you specifiy the name of you initial event (as in all the earlier examples), then an implicit ‘startup’ event will be created for you and fired when the state machine is constructed:

fsm = Fysom({

‘initial’: ‘green’, ‘events’: [

{‘name’: ‘panic’, ‘src’: ‘green’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘green’},

]

}) print fsm.current # “green”

If your object already has a startup method, you can use a different name for the initial event:

fsm = Fysom({

‘initial’: {‘state’: ‘green’, ‘event’: ‘init’}, ‘events’: [

{‘name’: ‘panic’, ‘src’: ‘green’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘green’},

]

}) print fsm.current # “green”

Finally, if you want to wait to call the initiall state transition event until a later date, you can defer it:

fsm = Fysom({

‘initial’: {‘state’: ‘green’, ‘event’: ‘init’, ‘defer’: True}, ‘events’: [

{‘name’: ‘panic’, ‘src’: ‘green’, ‘dst’: ‘red’}, {‘name’: ‘calm’, ‘src’: ‘red’, ‘dst’: ‘green’},

]

}) print fsm.current # “none” fsm.init() print fsm.current # “green”

Of course, we have now come full circle, this last example pretty much functions the same as the first example in this section where you simply define your own startup event.

So you have a number of choices available to you when initializing your state machine.

class serge.blocks.fysom.Fysom(cfg)[source]

Bases: object

can(event)[source]
cannot(event)[source]
isstate(state)[source]
exception serge.blocks.fysom.FysomError[source]

Bases: exceptions.Exception

hexgrid Module

Implementation of a hexagonal grid

class serge.blocks.hexgrid.HexGridCell(tag, name, location, grid, colour, stroke_colour=None, stroke_width=0)[source]

Bases: serge.actor.Actor

A grid cell on the screen

class serge.blocks.hexgrid.HexGridDisplay(tag, name='', size=(1, 1), width=None, height=None, background_colour=None, background_layer=None, hexagon_size=1, cell_colour=(255, 255, 255), stroke_colour=(255, 255, 255), stroke_width=1, cell_cls=<class 'serge.blocks.hexgrid.HexGridCell'>)[source]

Bases: serge.blocks.layout.BaseGrid

Displays and manages a hexagonal grid on the screen

addedToWorld(world)[source]

Added to the world

getCell(x, y)[source]

Return the cell

getCellDistance(loc1, loc2)[source]

Return the distance between two cells

getGrid()[source]

Return the underlying grid

getNeighbourCells(cell)[source]

Get the neighbours of a cell

getNeighbourCellsWithin(x, y, distance)[source]

Return the neighbour cells in a certain distance

iterLocations()[source]

Iterate through the cell locations

setGrid(size)[source]

Set the new grid

updateActor(interval, world)[source]

Update the display

class serge.blocks.hexgrid.HexagonalGrid(width, height, hexagon_size=1)[source]

Bases: serge.common.Loggable

A hexagonal grid

The grid is referenced by an x, y pair with 0, 0 being the top left.

cellIsInGrid(x, y)[source]

Return True if the cell is in the grid

clearGrid()[source]

Clear the grid

getCell(x, y)[source]

Return the cell contents

getCellContaining(x, y)[source]

Return the cell containing the point

getCellCoordsContaining(px, py)[source]

Return the coordinates of a cell containing the point

getCellDirection()[source]

Get the direction of one cell from another

getCellDistance()[source]

Return the distance between two cells

getCellLocation(x, y)[source]

Return the location of cell center based on the top left being 0, 0

getCellPoints(x, y)[source]

Return the points for the given cell

getNeighbourCellsWithin(x, y, distance)[source]

Return all the neighbour cells within a certain distance of the point

getNeighbourLocations(x, y)[source]

Return the neighbouring cells of a cell

getNeighbourLocationsWithin(x, y, distance)[source]

Return all the neighbour cell locations within a certain distance of the point

getNeighbours(x, y)[source]

Return the neighbour cells of the specified location

getRelativeCell(x, y, direction)[source]

Return the cell at a relative offset to this one

getRelativeCellCoords(x, y, direction)[source]

Return the coordinates of the cell at a certain direction from this

iterCells()[source]

Iterate through the cells

iterLocations()[source]

Iterate through the locations

setCell(x, y, cell)[source]

Set the cell contents

exception serge.blocks.hexgrid.OutOfRange[source]

Bases: exceptions.Exception

The cell was out of range of the grid

layout Module

Blocks to help with laying out things on the screen

exception serge.blocks.layout.AlreadyInCell[source]

Bases: exceptions.Exception

The actor was already in this cell

class serge.blocks.layout.Bar(tag, name='', width=None, height=None, background_colour=None, background_layer=None, background_sprite=None, item_width=None, item_height=None)[source]

Bases: serge.blocks.layout.Container

A bar of actors - useful for user interfaces

addActor(actor, layer_name=None)[source]

Add an actor to the bar

addBlanks(number)[source]

Add blank entries into the bar

class serge.blocks.layout.BaseGrid(tag, name='', size=(1, 1), width=None, height=None, background_colour=None, background_layer=None)[source]

Bases: serge.blocks.layout.Container

A grid of actors

clearGrid()[source]

Clear the entire grid

getCellFromLocation()[source]

Return the cell coords that a point on the screen would related to

This is useful for determining which cell the mouse is over.

getCoords()[source]

Return the coordinates of a location

getLocation()[source]

Return the location in the grid based on coordinates

getSize()[source]

Return the size of the container

removeActor()[source]

Remove the actor at a certain location

removeChildren()[source]

Remove all the children

setGrid()[source]

Set the size of the grid

This also removes all the current actors from the world. Note that this can be tricky if you want to re-add some of the actors since the actors are not actually removed until the next world update and so you cannot re-add them before this or you will get a duplicate actor error from the world.

exception serge.blocks.layout.CellEmpty[source]

Bases: exceptions.Exception

The cell being accessed was empty

exception serge.blocks.layout.CellOccupied[source]

Bases: exceptions.Exception

Tried to put an actor in an occupied cell

class serge.blocks.layout.Container(tag, name='', width=None, height=None, background_colour=None, background_layer=None, background_sprite=None, item_width=None, item_height=None)[source]

Bases: serge.actor.MountableActor

A layout container that contains actors

getSize()[source]

Return the size of the container

moveTo(x, y, no_sync=False, override_lock=True)[source]

Move this actor

reflowChildren()[source]

Relocate all children

setBackgroundColour(colour)[source]

Sets the background colour

setBackgroundSprite(name)[source]

Sets the background sprite

setLayerName(name)[source]

Set the layer name

class serge.blocks.layout.Grid(tag, name='', size=(1, 1), width=None, height=None, background_colour=None, background_layer=None)[source]

Bases: serge.blocks.layout.BaseGrid

A grid where a cell can only contain a single actor

addActor()[source]

Add an actor to the grid

autoAddActor(actor)[source]

Automatically add an actor to the next cell in the grid

This fills horizontally and then vertically

findActorLocation(actor)[source]

Find the location of an actor

getActorAt()[source]

Return the actor at a certain location

moveActor()[source]

Move an actor from wherever it is to the new location

class serge.blocks.layout.HorizontalBar(tag, name='', width=None, height=None, background_colour=None, background_layer=None, background_sprite=None, item_width=None, item_height=None)[source]

Bases: serge.blocks.layout.Bar

A horizontal bar of actors

getCoords(i)[source]

Return the coordinates of our ith location

class serge.blocks.layout.ManualUpdateGrid(tag, name='', size=(1, 1), width=None, height=None, background_colour=None, background_layer=None)[source]

Bases: serge.blocks.layout.Grid

A grid where the actors do not render themselves automatically

This grid is used as an optimization where you have a grid of actors that rarely change their appearance. The grid will render them once to a large surface.

When they change you call the updateRendering and the entire grid will refresh. This means that each frame you are not updating the rendering of all the actors and can just write out the pre-rendered image.

The grid implements this by adjusting the “visible” attribute of each actor so do not change this.

addActor()[source]

Add an actor

Each actor will be made invisible to control their rendering

updateRendering()[source]

Update our pre-rendered surface

class serge.blocks.layout.MultiGrid(tag, name='', size=(1, 1), width=None, height=None, background_colour=None, background_layer=None)[source]

Bases: serge.blocks.layout.BaseGrid

A grid where each cell can contain multiple actors

addActor()[source]

Add an actor to the grid

findActorLocation(actor)[source]

Find the location of an actor

getActorsAt()[source]

Return the actors at a certain location

moveActor()[source]

Move an actor from wherever it is to the new location

removeActor()[source]

Remove the actor at a certain location

removeActors()[source]

Remove all the actor from a certain location

exception serge.blocks.layout.OutOfRange[source]

Bases: exceptions.Exception

Tried to find something outside the range of the container

exception serge.blocks.layout.UnknownActor[source]

Bases: exceptions.Exception

The actor was not found

class serge.blocks.layout.VerticalBar(tag, name='', width=None, height=None, background_colour=None, background_layer=None, background_sprite=None, item_width=None, item_height=None)[source]

Bases: serge.blocks.layout.Bar

A vertical bar of actors

lighting Module

Implements a lighting approach

class serge.blocks.lighting.DirectionalLight(x, y, intensity, distance, angle, beam_width, particle, randomize_rays=False)[source]

Bases: serge.blocks.lighting.Light

Represents a light that shines in a direction

drawTo(light_field)[source]

Draw this light to a light field

setAngle(angle)[source]

Set the angle of the light

setIntensity(intensity)[source]

Set the light intensity

class serge.blocks.lighting.GlowingPointLight(x, y, particle, intensity=1.0, min_intensity=0.0, max_intensity=1.0)[source]

Bases: serge.blocks.lighting.Pointlight

A point light that varies its glow level

updateLight(interval)[source]

Update the light

class serge.blocks.lighting.Light[source]

Bases: serge.common.Loggable

A light that can be added to the display

drawTo(light_field)[source]

Draw this light to a light field

class serge.blocks.lighting.LightDolly(name, light, path, path_traversal_time, spring_strength, damping, mass=1.0, loop='none', face_velocity=False)[source]

Bases: serge.actor.Actor

A dolly to move a light along a path

updateActor(interval, world)[source]

Update the path motion

class serge.blocks.lighting.LightField(tag, name, field_size_ratio, fade_amount=0.9)[source]

Bases: serge.actor.Actor

Represents a field of light that will be drawn on top of the screen

addLight(light)[source]

Add some lights to the field

addLightParticle(particle_sprite, x, y)[source]

Add a light particle at screen coordinates x and y

addLights(lights)[source]

Add a number of lights to the screen

addPolygon(polygon)[source]

Set the lines used for geometry

addedToWorld(world)[source]

The actor was added to the world

blend_mode = 8
clearAmbientLight()[source]

Clear the ambient light

clearBakedLightField()[source]

Clear the baked lights

drawLightRay(start, end, light_particle, distance_range)[source]

Draw a light ray

drawLines()[source]

Draw the lines on the screen

fade_lights = True
is_baked = False
particle_blend_mode = 0
renderTo(renderer, interval)[source]

Render to a surface

setAmbientLight(light)[source]

Set an ambient light

setBakedLightField(baked_lights)[source]

Set the visual field of baked lights

traceRay(ray, particle, distance)[source]

Trace a ray to its destination

updateActor(interval, world)[source]

Update the actor

updateLightField()[source]

Update the overlal light field

class serge.blocks.lighting.LightParticle(base_sprite_name, size_range=(1.0, 1.0), alpha_range=(1.0, 0.0), max_steps=15, step_size=20, degrees_per_ray=10)[source]

Bases: serge.visual.Drawing

A particle of light to draw on the screen

calculateParticleSteps(intensity=1.0)[source]

Calculate the images for the particle steps

getSurfaceForDistanceFraction(fraction)[source]

Return the surface for the given step

class serge.blocks.lighting.Pointlight(x, y, particle, intensity=1.0)[source]

Bases: serge.blocks.lighting.Light

A point of light

drawTo(light_field)[source]

Draw to the light field

setIntensity(intensity)[source]

Set the intensity

lsystem Module

Implements an L-System generator

class serge.blocks.lsystem.LSystem[source]

Bases: object

Implements an L-System generator

addRule(rule)[source]

Add a rule to the system

addRules(rules)[source]

Add multiple rules to the system

doStep()[source]

Step the generation by one

doSteps(number)[source]

Do a number of steps all at once

getState()[source]

Return the current state

reset()[source]

Reset the generator

setAxiom(axiom)[source]

Set the axiom

class serge.blocks.lsystem.Rule(predecessor, successor, probability=1.0)[source]

Bases: object

A rule for the L-System

process(state)[source]

Process the state

If we match then return the pattern we generate and the length of the state that we consumed. If we do not match then return nothing and a zero cursor offset.

onlinescores Module

Interface to the online high-score system

class serge.blocks.onlinescores.AsyncOnlineScoreTable(app_url, game, max_workers=1)[source]

Bases: serge.blocks.onlinescores.OnlineScoreTable

Asynchronous version of the high score table

All the methods of the high score table return futures to the results. If you want callbacks then you can add a callback to the future once you get it back.

createPlayer(player)[source]

Create a new player

getCategories()[source]

Return the categories for a game

getScores(category, player, number)[source]

Return the scores for a game

recordScore(player, category, score)[source]

Record the score for a game

class serge.blocks.onlinescores.BaseHighScoreInterface(app_url, secret_user=False)[source]

Bases: object

Base class for interacting with the high score system

class serge.blocks.onlinescores.HighScoreSystem(app_url, secret_user=False)[source]

Bases: serge.blocks.onlinescores.BaseHighScoreInterface

Wrapper for useful functions to manage the high score system

categoryExists(game, category)[source]

Return True if the named category exists for the named game

createGame(name)[source]

Create a game

createGameCategory(name, category, value_name, sort_ascending, max_player_scores)[source]

Rename a game

deleteGame(name)[source]

Delete a game

gameExists(name)[source]

Return True if the named game exists

renameGame(name, new_name)[source]

Rename a game

exception serge.blocks.onlinescores.OnlineMethodCallFailed[source]

Bases: exceptions.Exception

Calling the online method resulted in an error

class serge.blocks.onlinescores.OnlineScoreTable(app_url, game)[source]

Bases: serge.blocks.onlinescores.BaseHighScoreInterface

Simple interface to the online high score table

createPlayer(player)[source]

Creates a new player

getCategories()[source]

Return the category names

getScores(category, player, number)[source]

Return the game scores for the given category and the given player (or * for all players)

recordScore(player, category, score)[source]

Record a score

class serge.blocks.onlinescores.SimpleHSTableView(tag, name, app_url, game_name, category_name, player_name, max_scores, layout, theme, fmt='%(num)d %(player)s %(score)s')[source]

Bases: serge.actor.MountableActor

A simple view of a high score table utilizing a layout

You can supply a theme and it will style using hs-font-colour, hs-font-size etc

The format of the text should be a format string using the names num, player and score.

addedToWorld(world)[source]

Added the table to the world

ensurePlayer()[source]

Ensure that our player is defined

recordScore(score)[source]

Record a new score

updateActor(interval, world)[source]

Update the actor

updateScores(done=None)[source]

Try to update the scores

polygons Module

Visuals which are polygons

class serge.blocks.polygons.PolygonVisual(points, colour, width=1, closed=False)[source]

Bases: serge.visual.Drawing

A visual that renders a polygon

getAngle()[source]

Return the angle

getPoints()[source]

Return the points including the effect of rotation

renderTo()[source]

Render the visual

setAngle(angle)[source]

Set the angle of the graphic

setPoints(points)[source]

Set the points for the polygon

scores Module

Handling high score type tables

exception serge.blocks.scores.BadCategory[source]

Bases: exceptions.Exception

The category was not found

exception serge.blocks.scores.BadData[source]

Bases: exceptions.Exception

The data provided for a category was not valid

class serge.blocks.scores.Category(name, number=None, sort_columns=None, directions=('ascending', ))[source]

Bases: list

A category for an individual score table

addScore(name, *args)[source]

Add a new score

resetCategory()[source]

Reset this category, deleting all the data but maintaining the configuration

exception serge.blocks.scores.DuplicateCategory[source]

Bases: exceptions.Exception

The category was already added

class serge.blocks.scores.HighScoreTable[source]

Bases: serge.serialize.Serializable

A high score table

The table can contain scores in a number of categories. Each category is a table with multiple columns. The table can be sorted by any one column and can have a limited set of values

addCategory(name, number=None, sort_columns=None, directions=('ascending', ))[source]

Add a new category

addScore(category_name, name, *args)[source]

Add a score to a category

getCategory(category_name)[source]

Return a category

my_properties = ({},)
resetCategory(category_name)[source]

Reset the category name

resetTable()[source]

Clear the entire table

exception serge.blocks.scores.InvalidSort[source]

Bases: exceptions.Exception

The sort direction was invalid

exception serge.blocks.scores.InvalidSortColumn[source]

Bases: exceptions.Exception

The column specified for sorting was not valid

settings Module

Blocks to make handling settings very easy

class serge.blocks.settings.Bag[source]

Bases: object

A bag to store objects in

init(defaults=None)[source]

Initialise the bag

class serge.blocks.settings.Settings(name)[source]

Bases: serge.common.Loggable

Handles settings

getLocation()[source]

Return the location to store and retrieve files from

restoreValues()[source]

Restore all the values from a file

safeRestoreValues()[source]

Restore values if the file is there. If not just restore a blank set

saveValues()[source]

Serialize all the values to a file

setLocation(location)[source]

Set the location to store and retrieve files from

sounds Module

Useful blocks for sounds

class serge.blocks.sounds.ActorsWithTagSound(sound, world, tag, dropoff)[source]

Bases: serge.blocks.sounds.AmbientSound

A series of sounds that are located on actors who are in the world and have a certain tag

get_scaled_volume(listener_position)[source]

Update the sound volume according to the listener position

class serge.blocks.sounds.AmbientSound(sound)[source]

Bases: serge.sound.SoundItem

A sound located everywhere in space

get_scaled_volume(listener_position)[source]

Return the sound volume according to the listener position

class serge.blocks.sounds.LocationalSound(sound, location, dropoff)[source]

Bases: serge.blocks.sounds.AmbientSound

A sound that is located somewhere in space

get_scaled_volume(listener_position)[source]

Update the sound volume according to the listener position

class serge.blocks.sounds.LocationalSounds(sound, locations, dropoff)[source]

Bases: serge.blocks.sounds.AmbientSound

A series of sounds that are located at a number of places in space but generate only a single sound

get_scaled_volume(listener_position)[source]

Update the sound volume according to the listener position

exception serge.blocks.sounds.NoListener[source]

Bases: exceptions.Exception

Positional sound enabled but there is no listener set

class serge.blocks.sounds.ProbabalisticSound(sound, probability)[source]

Bases: serge.sound.SoundItem

A sound that plays with a certain probability

try_to_play(interval)[source]

Try to play the sound

class serge.blocks.sounds.RectangularRegionSound(sound, region)[source]

Bases: serge.blocks.sounds.AmbientSound

A sound that is located in a rectangular region

Inside the region the volume is full and outside the region the volume is zero.

get_scaled_volume(listener_position)[source]

Update the sound volume according to the listener position

class serge.blocks.sounds.SoundTexture(tag, name, damping=None)[source]

Bases: serge.actor.Actor

An actor that manages a number of sounds to create a texture

The actor can control sounds that are produced either ambiently (everywhere) or at specific locations. For the sounds at specific locations the sounds will get louder as the listener gets closer to them.

addAmbientSound(sound)[source]

Add an ambient sound to the texture

An ambient sound plays at the same volume no matter where the listener is. Ambient sounds still get paused with the other sounds.

Parameters:sound – the serge sound object that should be played
addPositionalSound(sound)[source]

Add a positional sound to the texture

A position sound plays at one or more locations in space and its volume is dependent on the location of the listener.

Parameters:sound – the sound object that should be played. It should inherit from AmbientSound
addRandomSound(sound, probability)[source]

Add a random sound to the texture

A random sound plays with a likelihood of probability/second.

Parameters:
  • sound – the serge sound object that should be played
  • probability – the probability that the sound will play in a given second
getListener()[source]

Return the listener

getSounds()[source]

Return all the sounds that we are controlling

get_volume()[source]

Return the master value setting

pause()[source]

Pause the sounds

play(loops=0)[source]

Play the sounds

Parameters:loops – number of times to loop the sounds (0=never, -1=for ever)
setListener(listener)[source]

Set the listener for the sounds

The listener is an actor and the sounds play at a volume determined by the location of the listener relative to each sound.

Parameters:listener – an actor
set_volume(volume)[source]

Set the master volume

This affects the volume of all sounds. The target volume for a sound is multiplied by this master.

Parameters:volume – master volume setting (0=silent, 1=full volume)
stop()[source]

Stop the sounds

updateActor(interval, world)[source]

Update the actor

singletons Module

Implement a store for singletons

class serge.blocks.singletons.SingletonStore[source]

Bases: serge.registry.GeneralStore

A store for global objects

statemachine Module

Classes to help in running and / or chaining long running statefull operations This is useful if you want to implement long running processes (ie across many frames). You can write these as simple generators and you don’t have to worry about keeping track of where you are in the sequence as this is done for you. The sequence can include many steps and can branch and repeat etc. The normal way to use these classes is to make your State a subclass of StateMachine. This requires you to implement two methods to set up and render your on screen items. There is nothing special going on here, it just keeps your logic away from the statefull machinery. 1. When initialising the state will call a method initUI that you must implement. You can do whatever you want in there but normally you would initialise any UI components. 2. Calls drawUI(surface, scale) whenever you need to redraw the current frame. The rest is where the magic happens, You can start a long running process with a call to add_generator(‘<name>’, some_generator) Your generator will be called repeatedly until it exits. You can also stop it manually by calling stop_generator() on the state, by calling stop() on the StateExecutor that is returned by add_generator, or by raising a StopIteration in the generator. Your generator can yield in two ways, A - “yield”: stops execution and returns to the same point next frame B - “yield <N>: stops execution and returns to the same point <N> ms later For an example of usage, let’s say the player does something and you want to move a card across the screen, flash it three times, then move it down the screen. If the player clicks somewhere else in the meantime then the motion should stop. The generator approach allows you to write this very logically and not worry about keeping state (moving across, flashing, moving down etc). In your State you would detect two conditions a) the motion should state, b) the motion should be interrupted, and a generator method move_card()

class MyState(StateMachine):
def drawUI(self, surface, scale):

... if condition_to_initiate_motion:

self.card_mover = self.add_generator(‘move-card’, self.move_card(50, 100))
if condition_to_interrupt_card:
self.card_mover.stop()

...

def move_card(self, dx, dy):

# Move card over to the right for x in range(dx):

self.card.x += 1 yield 100 # Pause for 100ms

# Flash the card three times for repeat in range(dy):

self.card.visible = False yield 100 # Hide for short time self.card.visible = True yield 900 # Show for a longer time

# Move the card down for y in range(100):

self.card.y -= 1 yield 100 # Pause for 100ms

The above example shows how a single stateful operation can be written very cleanly. Another use case is to chain states together. Suppose you want to show cards shuffling, then being dealt and then being turned over, one-by-one. You can chain these by calling add_generator at the end of each operation.

class State(StateMachine):
def drawUI(...):
if condition_to_start_dealing:
self.add_generator(‘shuffle-cards’, self.shuffle_cards())
def shuffle_cards(self):
... code to show shuffling of cards (runs over many frames, yielding as needed) ... self.add_generator(‘deal-cards’, self.deal_cards())
def deal_cards(self):
... code to move cards from deck to table (like move_card above) ... self.add_generator(‘turn-cards’, self.turn_cards)
def turn_cards(self):
for card in self.cards:
card.turn_over() yield 1000

... add_generator for the next step in the process ...

You states can easily wait for conditions, eg if you detect a click on a card by setting a property “card_selected” on the state.

def wait_for_card_selection(self):
while self.card_selected is None:
yield # We will wait in this state until a card is selected
if self.card_selected in deck:
self.add_generator(‘move-from-deck’, self.move_card_from_deck(self.card_selected)
else:
self.add_generator(‘move-from-hand’, self.move_card_from_hand(self.card_selected)
exception serge.blocks.statemachine.NextStep(step)[source]

Bases: exceptions.StopIteration

Move to the next step

exception serge.blocks.statemachine.NotFound[source]

Bases: exceptions.Exception

Generator was not found

class serge.blocks.statemachine.StateExecutor(name, generator, delay=0)[source]

Bases: serge.common.Loggable

Executes a generator through a sequence with delays

get_fraction_to_go()[source]

Return the fraction of our time to go

next_step()[source]

Immediately make the generator go to the next step

stop()[source]

Stop this executor

update(dt)[source]

Update the state

update_interval(interval)[source]

Update the interval we are waiting for This behaves as though the last delay requested is immediately changed to the specified value. If we have already waited for the specified time then immediately go to the next step

class serge.blocks.statemachine.StateMachine(tag, name)[source]

Bases: serge.actor.Actor

A state machine to use for handling the screen

add_generator(name, generator)[source]

Add a new generator to run

stop_generator(name)[source]

Stop a generator with a specific name

updateActor(interval, world)[source]

Update the game state

verbose = True

storage Module

Classes to help with storage of detailed information about a game in sql tables.

This is good for high scores, achievements etc.

The objects here allow persisting between versions and handle schema updates to the tables.

exception serge.blocks.storage.ConnectionError[source]

Bases: exceptions.Exception

Could not connect to database

class serge.blocks.storage.Storage(name, path=None)[source]

Bases: serge.common.Loggable

The main storage object

addDefaultRows(table_name, row_key, rows, override=False)[source]

Add some default rows to the database

The row_key specifies which of the columns is used as the key. If a row already exists in the database with that key then the default row will not be added.

The rows is a list of lists of values. The row_key is in the first position.

addTable(name, sql)[source]

Add a new table

close()[source]

Close the database

get(sql, params=None)[source]

Return results

save()[source]

Save the current database

textgenerator Module

Implements a class to help with randomized text generation

class serge.blocks.textgenerator.FactDatabase[source]

Bases: object

Stores facts about the world

addFact(fact_id, *params)[source]

Add a fact to the database

getFactInstances(fact_id)[source]

Return all instances of a certain fact

getLastFactParameters(fact_id)[source]

Return the parameters for the last time the fact occurred

getLastOccurrence(fact_id)[source]

Return the last instance of an event

getLastOccurrenceTime(fact_id)[source]

Return the last time a fact occurred

getNumberOfOccurrences(fact_id)[source]

Return the number of times a fact has occurred

getOccurrenceFrequency(fact_id)[source]

Return the frequency with which a fact as occurred

getTime()[source]

Return the current time

hasOccurred(fact_id)[source]

Return True if the fact has occurred

setTime(time)[source]

Set the current time

exception serge.blocks.textgenerator.InvalidTime[source]

Bases: exceptions.Exception

The time specified was invalid

class serge.blocks.textgenerator.MarkovNameGenerator(names, chainlen=2)[source]

Bases: object

A name from a Markov chain

getName(max_length=9)[source]

New name from the Markov chain

class serge.blocks.textgenerator.Mdict[source]
add_key(prefix, suffix)[source]
get_suffix(prefix)[source]
exception serge.blocks.textgenerator.NameNotFound[source]

Bases: exceptions.Exception

An expansion for the name was not found

exception serge.blocks.textgenerator.NoOccurrence[source]

Bases: exceptions.Exception

There was no occurrence of a fact

class serge.blocks.textgenerator.RechargingRule(rule_id, clauses, recharge_time)[source]

Bases: serge.blocks.textgenerator.Rule

A rule that must recharge once it fires

fireRule(db)[source]

Fire the rule

isMatched(db)[source]

Return True if we are matched - must match and not be charging

class serge.blocks.textgenerator.Rule(rule_id, clauses)[source]

Bases: object

Implements a rule

fireRule(db)[source]

Call this when the rule should fire

Override this method to give particular rule behaviours

isMatched(db)[source]

Return True if the rule is matched

class serge.blocks.textgenerator.RuleSystem(db)[source]

Bases: object

Implements a rule checking system

FactNotOccurred(fact_id)[source]

Return a checker for a fact not occurring

FactNotOccurredExactNumberOfTimes(fact_id, number)[source]

Return a checker for a fact not occurring a number of times

FactNotOccurredFrequency(fact_id, frequency)[source]

Return a checker for a fact occurring at most the given frequency

FactNotOccurredNumberOfTimes(fact_id, number)[source]

Return a checker for a fact not occurring a number of times

FactNotRecentlyOccurred(fact_id, interval)[source]

Return a checker for a fact not occurring in the last time interval

FactOccurred(fact_id)[source]

Return a checker for a fact

FactOccurredExactNumberOfTimes(fact_id, number)[source]

Return a checker for a fact occurring a number of times

FactOccurredFrequency(fact_id, frequency)[source]

Return a checker for a fact occurring at least the given frequency

FactOccurredNumberOfTimes(fact_id, number)[source]

Return a checker for a fact occurring a number of times

FactRecentlyOccurred(fact_id, interval)[source]

Return a checker for a fact occurring in the last time interval

addRule(rule, priority=None)[source]

Add a rule to the system

getBestMatchingRule()[source]

Return the best rule matching the current world

class serge.blocks.textgenerator.TextGenerator[source]

Bases: object

Generate text from forms

A form gives the possible values for something, for example the form for colour might give [red, green, blue].

You can then convert sentences like ‘the @colour@ book’

Conversion can be hierarchical like:
objects are [book, table, @{colour}@ cat]

Sentence ‘the @{object}@’ would give a “book” or a “red cat”.

When looking up examples from text or files the form should be:

type: example1 type: example2

Or

type {
example1 example2

}

addExample(name, conversion)[source]

Add a new form

addExampleFromText(text)[source]

Add an example from text - the name is ‘:’ separated from the conversion

addExamplesFromFile(filename)[source]

Add multiple examples from a file

addExamplesFromText(text)[source]

Add a number of examples from text

getRandomFormCompletion(name, properties=None)[source]

Return the comletion of a form randomly

getRandomSentence(text, properties=None)[source]

Return a random sentence from the text

themes Module

Classes to implement themes

Themes are sets of settings that may affect anything. The idea is that you may have a number of settings to do with visuals on a world and you want to control those centrally, potentially also allowing things to switch during a game.

The themes are managed by a manager.

exception serge.blocks.themes.BadInheritance[source]

Bases: exceptions.Exception

A theme subclass was not found

exception serge.blocks.themes.BadThemeDefinition[source]

Bases: exceptions.Exception

The theme was not of the right format

exception serge.blocks.themes.BadThemeFile[source]

Bases: exceptions.Exception

The specified theme file was not found

exception serge.blocks.themes.InvalidFormat[source]

Bases: exceptions.Exception

The format for the data was invalid

class serge.blocks.themes.Manager[source]

Bases: object

Manages a theme

getProperty(name, from_theme=None)[source]

Return the named property

getPropertyWithDefault(name, default, from_theme=None)[source]

Return a property and if it is missing then return the default value

Use this method sparingly. It puts default values in source code rather than in the theme files.

getTheme(name)[source]

Return a theme object with a default of the given name

hasTheme(name)[source]

Return True if we have this theme

load(themes)[source]

Load definitions from a dictionary

loadFrom(text)[source]

Load a theme from some text

The theme is a dictionary where each entry is either a theme or the definition of the schema or the special entry __default__, which gives the name of the default theme.

If there is an entry then it is a tuple with the name of the base theme class followed by a dictionary of entries which overide the base class.

Classes are really just the name of another theme.

loadFromFile(filename)[source]

Load a theme definition from a file

selectTheme(name)[source]

Select the named theme

setProperty(name, value, from_theme=None)[source]

Set a property in a theme

updateFromString(string)[source]

Update the theme from a string of data

Data should be provided as comma separated values like
name=”bob”,value=123,etc
exception serge.blocks.themes.MissingDefault[source]

Bases: exceptions.Exception

There was no default theme

exception serge.blocks.themes.MissingSchema[source]

Bases: exceptions.Exception

There was no schema in the theme definition

exception serge.blocks.themes.PropertyNotFound[source]

Bases: exceptions.Exception

Could not find a property

exception serge.blocks.themes.ThemeNotFound[source]

Bases: exceptions.Exception

The named scheme was not found

tiled Module

Implements an interface to Tiled files

exception serge.blocks.tiled.BadLayer[source]

Bases: exceptions.Exception

The layer specification was invalid

exception serge.blocks.tiled.BadTiledFile[source]

Bases: exceptions.Exception

The tiled file could not be found

class serge.blocks.tiled.Layer(tiled, name, layer_type, width=None, height=None, tiles=None, properties=None)[source]

Bases: serge.common.Loggable

A layer in a tilemap

addObject(obj)[source]

Add an object

Parameters:obj – the object to add to the layer
getLocationsWithSpriteName(sprite_name)[source]

Return all tile locations with a specific tile

Parameters:sprite_name – the name of the sprite you are looking for
getLocationsWithTile()[source]

Return all tile locations with a tile

getLocationsWithoutTile()[source]

Return all tile locations without a tile

getObject(name)[source]

Return the named object

Parameters:name – the name of the object to return
getObjects()[source]

Return all the objects

getSize()[source]

Return the size of the layer

getSpriteFor()[source]

Return the sprite for a certain location

iterCellLocations()[source]

Return an interation of the cell locations

setSpriteFor()[source]

Set a sprite at a certain position

validateSchemas(schema, strict_mode=False)[source]

Validate that all objects with a given type have the right properties

exception serge.blocks.tiled.NotFound[source]

Bases: exceptions.Exception

The object was not found

exception serge.blocks.tiled.SchemaNotMet[source]

Bases: exceptions.Exception

An object schema was not met

class serge.blocks.tiled.TileImageObject(name, x, y, source, properties)[source]

Bases: serge.blocks.tiled.TileObject

Initialise the object

getSurface()[source]

“Return the surface

class serge.blocks.tiled.TileMap[source]

Bases: serge.common.Loggable

A representation of a 2d map of tiles

addLayer(layer)[source]

Add a layer

classmethod addLayerTypes(layer_types)[source]

Add more layer types

getLayer(name)[source]

return the tile with a certain name

getLayerByType(type_name)[source]

Return the layer with a given type

getLayers()[source]

Return the layers of tiles

getLayersByType(type_name)[source]

Return the layer with a given type

getLayersForTile()[source]

Return a list of the layers that the tile at x, y is set on

getPropertiesFrom(nodes)[source]

Return a property disction from the node

getPropertyBagArray(sprite_layers, boolean_layers, property_layers, prototype=None, optional_layers=None)[source]

Return an array of property bags for the tile array

You pass a series of lists of layer types, which are treated like:
sprite_layers = tile based layers to treat as identifying sprites boolean_layers = tile layers where if a tile is set (to anything) then a boolean flag is True property_layers = tile layers where if a tile is set then the item recieves all the properties of the layer
getSize()[source]

Return the size of the map using the first layer as a guide

getTypeFrom(name, properties)[source]

Return the layer type, checking validity which we do it

classmethod resetLayerTypes()[source]

Reset the layer types to default

class serge.blocks.tiled.TileObject(name, object_type, x, y, width, height, properties, sprite_name=None, sprite_id=None, points=None, rotation=0)[source]

Bases: serge.geometry.Rectangle, serge.common.Loggable

A tile

getStringTuple(attribute_name, default)[source]

Return a tuple of a string comma separated list

class serge.blocks.tiled.Tiled(filename)[source]

Bases: serge.blocks.tiled.TileMap

An interface to tiled files

getObjectLayer(name)[source]

Return an object layer with a certain name

getObjectLayers()[source]

Return the object layers

getObjectLayersByType(type_name)[source]

Return the object layers with a given type

getSpriteId(name)[source]

Return the sprite id from a sprite name

getSpriteName(idx)[source]

Return the sprite name for an index

layer_types = ['visual', 'adhoc-visual', 'movement', 'visibility', 'object', 'resistance']

utils Module

Some utilities that speed up common operations

class serge.blocks.utils.BidirectionalDict[source]

Bases: dict

A dictionary that can access items by key or by value

deleteReverse(value)[source]

Delete the item from the value

getReverse(value)[source]

Return the key from the value

class serge.blocks.utils.LoadingScreen(font_colour, font_size, font_name, position, layer_name, justify='center', background=None, background_position=None, background_layer=None, icon_name=None, icon_position=None)[source]

Bases: serge.world.World

Implements a loading screen

showScreen(text='Loading ...')[source]

Show the loading screen

class serge.blocks.utils.MovieRecorder(path, make_movie=False, rate=1, in_memory=False)[source]

Bases: object

Will record a movie of the game

clearFrames()[source]

Clear all current frames

makeFrame(obj, arg)[source]

Make a frame

makeMovie(obj, arg)[source]

Convert the frames to movie

class serge.blocks.utils.ProbabilityChooser(options, interpolate=False)[source]

Bases: object

Returns choices from a list of possibilities with probabilities

choose()[source]

Return an item chosen at random from our list

chooseMultiple(number)[source]

Return a number of items chosen at random

class serge.blocks.utils.ProbabilityFunctionChooser(fn, low=0.0, high=1.0, number=10)[source]

Bases: serge.blocks.utils.ProbabilityChooser

Returns values chosen from a range with a probability function

static getTriangle(low, mid, high, multiplier=1.0)[source]

Return a triangle function

class serge.blocks.utils.RecordDesktop(filename)[source]

Bases: serge.common.Loggable

Use record my desktop to record the action

stop(obj, arg)[source]

Stop the recording

serge.blocks.utils.addActorToWorld(world, actor, sprite_name=None, layer_name=None, center_position=None, physics=None, origin=None)[source]

Create a new actor in the world

If the center position is not specified then it is placed at the center of the screen.

serge.blocks.utils.addMuteButtonToWorlds(button, center_position, world_names=None)[source]

Add a particular mute button to various worlds

If worlds is not specified then add to all the worlds currently in the engine.

serge.blocks.utils.addSpriteActorToWorld(world, tag, name, sprite_name, layer_name, center_position=None, physics=None, actor_class=<class 'serge.actor.Actor'>)[source]

Create a new actor in the world and set the visual to be the named sprite

If the center position is not specified then it is placed at the center of the screen.

serge.blocks.utils.addTextItemsToWorld(world, items, theme, layer_name, actor_class=<class 'serge.actor.Actor'>)[source]

Add multiple text items to the world

serge.blocks.utils.addTextToWorld(world, text, name, theme, layer_name, actor_class=<class 'serge.actor.Actor'>)[source]

Add some text to the world

serge.blocks.utils.addVisualActorToWorld(world, tag, name, visual, layer_name, center_position=None, physics=None, actor_class=<class 'serge.actor.Actor'>)[source]

Create a new actor in the world and set the visual

If the center position is not specified then it is placed at the center of the screen.

serge.blocks.utils.backToPreviousWorld(sound=None)[source]

Return an event callback to switch back to the previous world

serge.blocks.utils.checkNetworkXVersion(need_version)[source]

Check a suitable version of NetworkX is installed

serge.blocks.utils.checkPyOpenGLVersion(need_version)[source]

Check a suitable PyOpenGL is installed

serge.blocks.utils.checkPythonVersion()[source]

Check a suitable Python version is installed

serge.blocks.utils.createLayers(engine, layers, cls)[source]

Create a number of layers in the engine using the given class of layer

serge.blocks.utils.createLayersForEngine(engine, layers)[source]

Add a number of layers to the engine

The layers parameter is a list of layer names. The layers are added to the renderer of the engine as successive layers in order.

serge.blocks.utils.createVirtualLayersForEngine(engine, layers)[source]

Add a number of virtual layers to the engine

The layers parameter is a list of layer names. The layers are added to the renderer of the engine as successive layers in order.

The layers are created as virtual, meaning that this will render quicker than the real layers version, although compositing will not be possible.

serge.blocks.utils.createWorldsForEngine(engine, worlds, world_class=<class 'serge.world.World'>)[source]

Add a number of worlds to the engine

The words parameter is a list of names of the worlds to create. Each world is created with a single active zone which is quite large.

serge.blocks.utils.debugMethod(obj, method_name, logger=None, fmt='')[source]

Create a debug logged method

serge.blocks.utils.getGamePath(*parts)[source]

Return a path based on the main game folder

serge.blocks.utils.getSimpleSetup(width, height)[source]

Return an engine with a single world, zone and a few layers

serge.blocks.utils.getUniqueID()[source]

Returns a unique ID string for this computer

serge.blocks.utils.takeScreenshot(filename)[source]

Take a screenshot

serge.blocks.utils.worldCallback(name, sound=None)[source]

Return an event callback to switch to a certain world

visualblocks Module

Useful blocks for visual rendering

class serge.blocks.visualblocks.BlockedProgressBar(size, block_size, vertical, value_ranges, use_back_colour=True)[source]

Bases: serge.visual.SurfaceDrawing

A progress bar made of a series of blocks

The progress bar shows a series of rectangle on the screen which you can use to show progress or represent the number of certain items. The bar is made of a series of rectangles that can change colour within certain ranges.

Use the value property to set the current value of the bar.

Parameters:
  • size – (w, h) the size of the bar
  • block_size – (w, h) the size of each block
  • vertical – True/False whether to display vertical or horizontal
  • value_ranges – [(high, colour, back-colour), ...] list of coloured ranges, assumed to start at 0
  • use_back_colour – if True then the back colour will be draw for inactive blocks
getValue()[source]

Return the value

setValue(value)[source]

Set the value

class serge.blocks.visualblocks.Circle(radius, colour, stroke_width=0, stroke_colour=None)[source]

Bases: serge.visual.SurfaceDrawing

A circle

colour
radius
setAngle(angle)[source]

Set the angle

Pass through as this is a circle!

class serge.blocks.visualblocks.CircleText(text, text_colour, radius, circle_colour, font_size=12, font_name='DEFAULT', stroke_width=0, stroke_colour=None, justify='center')[source]

Bases: serge.visual.Drawing

A circle with some text on it

getSize()[source]

Return the size of the drawing

renderTo()[source]

Render to a surface

exception serge.blocks.visualblocks.InvalidParameters[source]

Bases: exceptions.Exception

The parameters for the shape were not valid

exception serge.blocks.visualblocks.InvalidSprite[source]

Bases: exceptions.Exception

The selected sprite was not valid

exception serge.blocks.visualblocks.OutOfRange[source]

Bases: exceptions.Exception

The value was outside the valid range

exception serge.blocks.visualblocks.OverlappingRanges[source]

Bases: exceptions.Exception

The ranges for the progress bar were overlapping

class serge.blocks.visualblocks.Polygon(points, colour, stroke_width=0, stroke_colour=None)[source]

Bases: serge.visual.SurfaceDrawing

A polygon

colour
class serge.blocks.visualblocks.ProgressBar(size, value_ranges, border_width=0, border_colour=(255, 255, 255, 255))[source]

Bases: serge.visual.SurfaceDrawing

A progress bar

The progress bar shows a rectangle on the screen which you can use to show progress or represent the number of certain items. The bar can be a single colour or can change colour within certain ranges.

Use the value property to set the current value of the bar.

Parameters:
  • size – (w, h) the size of the bar
  • value_ranges – [(low, high, colour), ...] list of coloured ranges
value
exception serge.blocks.visualblocks.RangesNotContiguous[source]

Bases: exceptions.Exception

The ranges for the progress bar had gaps in them

class serge.blocks.visualblocks.Rectangle[source]

Bases: serge.visual.SurfaceDrawing

A rectangle

colour
class serge.blocks.visualblocks.RectangleText(text, text_colour, rect_dimensions, rect_colour, font_size=12, font_name='DEFAULT', stroke_width=0, stroke_colour=None, justify='center')[source]

Bases: serge.visual.Drawing

A rectangle with some text on it

renderTo()[source]

Render to a surface

class serge.blocks.visualblocks.SpriteText(text, text_colour, sprite_name, font_size=12, font_name='DEFAULT', stroke_width=0, stroke_colour=None, justify='center')[source]

Bases: serge.visual.Sprite

A sprite with some text on it

renderTo()[source]

Render to a surface

setText(text)[source]

Set the text

text
class serge.blocks.visualblocks.TextToggle(*args, **kw)[source]

Bases: serge.blocks.visualblocks.SpriteText

A sprite text item that has multiple cells and can be used as a toggle

You can set the cells directly of use On=0 and Off=1.

isOff()[source]

Return if we are on

isOn()[source]

Return if we are on

setOff()[source]

Set to off

setOn()[source]

Set to on

toggle()[source]

Toggle the state

class serge.blocks.visualblocks.Toggle(sprite_name)[source]

Bases: serge.blocks.visualblocks.TextToggle

Like a text toggle but with no text

visualeffects Module

Visual effects

class serge.blocks.visualeffects.FadingLayer(name, order)[source]

Bases: serge.render.Layer

A layer that you can fade in and out

postRender()[source]

After rendering the surface

class serge.blocks.visualeffects.FadingScreen[source]

Bases: object

Fade in and out everything

deleteFade()[source]

Remove the fade

postRender(obj, arg)[source]

After rendering the surface

class serge.blocks.visualeffects.Shadow(source, colour)[source]

Bases: serge.visual.SurfaceDrawing

Creates a shadow from an image

createShadow()[source]

Create the shadow now

Most of the logic here from http://pygame.org/wiki/ShadowEffects

class serge.blocks.visualeffects.ShadowLayer(name, order, colour, offset)[source]

Bases: serge.render.Layer

A layer that renders with a shadow beneath it

initSurface(renderer)[source]

Initialise the surface

render(surface)[source]

Render to a surface

When rendering to the surface we first create our shadow then render this to the surface followed by our normal rendering.

serge.blocks.visualeffects.darkenSurf(img, amount)[source]

Darken a surface

serge.blocks.visualeffects.darkenSurf2(img, amount)[source]

Darken the given surface by the given amount

serge.blocks.visualeffects.fadeSurface(surface, v)[source]

Fade the given suface by an amount 0 to 255 - 0 is completely faded

serge.blocks.visualeffects.gaussianBlur(surface, sigma)[source]

This function takes a pygame surface, converts it to a numpy array carries out gaussian blur, converts back then returns the pygame surface.

worker Module

Some helper classes to implement various parallel processing workers

serge.blocks.worker.SkippableQueue()[source]

Return A queue where only one item is retained

serge.blocks.worker.getSurfaceProcessingPipeline(target, start=True)[source]

Return a pair of queues to implement a surface processing pipeline

An input and output queue are returned. The queues are passed a tuple of items and the first one is a surface which is marshalled to the target function.

The function must also return a tuple, the first of which is assumed to be a surface which will be marshalled.

serge.blocks.worker.marshallSurface(surface)[source]

Return a surface that can be passed from one process to another

serge.blocks.worker.pipelineProcessor(qin, qout, target)[source]

Implements the surface processing pipeline

serge.blocks.worker.unmarshallSurface(width, height, fmt, string)[source]

Return a surface returned from another process