Video summary
The video introduces PPB, an open-source, idiomatic Python library designed for creating event-driven games with an educational focus. The presenter, Piper Sundstrom, explains that PPB simplifies game development by abstracting away the complex game loop typically required in other engines, allowing developers to start with just two lines of code. Instead of managing a traditional simulation loop manually, PPB handles rendering, updating, and event processing automatically. This approach encourages writing code as responses to specific events—such as mouse movements, key presses, or window updates—rather than relying on a rigid frame-by-frame structure. The library is particularly suited for educators because its design decisions are informed by feedback from teachers, ensuring it remains accessible and effective for learning environments.
A significant portion of the talk covers PPB's rendering capabilities and scene management system. The library uses raster graphics with pixel arrays under the hood but allows developers to focus on metadata like images, rotation, and scaling without worrying about low-level rendering details. Scenes act as containers that manage the game's state machine, enabling easy transitions between different screens such as menus, gameplay levels, splash screens, and game-over states. These scenes can be pushed onto or popped from a stack, making it straightforward to handle complex UI flows. Additionally, PPB supports custom event publishing, allowing objects to communicate with one another through signals. This system lets developers create dynamic interactions where any object in the scene can receive and respond to events broadcast by others, fostering a flexible architecture for building interactive features like achievements or multiplayer logic.
The final segment demonstrates how to make game objects interact using sprites and subsystems. Sprites in PPB are essentially data bags that can be attached with event handlers, allowing them to move, rotate, and react to inputs. The presenter shows multiple ways to link sprites together: passing other sprites as parameters, using tags to find and target specific objects, or utilizing a messaging system where objects signal each other to perform actions like following a leader or chasing a player. To illustrate extensibility, the video concludes with a live demonstration of building an achievement system from scratch using subsystems. By defining simple events that track progress and trigger conditions, developers can create sophisticated game mechanics without needing to rewrite core engine logic, proving that PPB's modular design makes it easy to add custom features while keeping code clean and maintainable.
Read the full video transcript
we got our next knock up Piper Buster is
gonna tell us about games let's see the
round of applause to fight all right
so specifically we're going to talk
about making games with ppb which most
of you probably haven't heard of yet so
I'm hiper Sundstrom I'm a software
engineer at a company called GLG I've
mostly do web development and database
program I'm also a community organizer
in the New York City Python area Python
community and I'm also the author of PDB
which is again why you probably haven't
heard of it yet if you want to follow me
or tweet about this at PA sundström and
app pursuit pie bear so what is ppb oh
this is did not work on this screen oh
okay so BBB we are an open source
idiomatic Python event-driven education
focused game library lots and lots of
words to apply to one resource we're
gonna kind of take them in order I don't
think I have to explain open source to
this room but I do to others so that's
why it's there when I say idiomatic
Python what I mean is the code you write
with ppb looks and feels like Python by
event-driven I mean that you write your
code as responses to events and not as a
game loop like you're probably used to
if you've done game programming and by
education focused I mean that primarily
when I need to make a decision on what
of three different engineering options
do we need to do I go and talk to a
bunch of teachers uh-huh
so that's what PPP is this is the team I
am my career at the top I'm PA comes
from on github
I am the API author and basically the
manager of the project jamie is my co
maintainer jamie is the actual one who
is actually the one who wrote the event
system and has done a lot of great work
and is currently trying to get an
animation framework over the line and
Nicko has done a
out of work on making our numbers stuff
all work better clearly not the person
to talk about it um so let's Wow that is
the wrong file to open this is why you
don't like good folks all right so let's
actually talk about making games when
important about this talk I'm not gonna
really cover these basics in a lot of
detail this is just a very quick primer
if you want more I've given as hard on
making games the actual concepts you can
find them on YouTube under my name
so all games at their core have an event
loop we actually call this a couple of
different things depending on who's
talking about it sometimes they're
called render loop sometimes their game
loops sometimes their simulation loops
they all kind of tell you what's going
on under the hood we want to respond to
events update the simulation and then
render usually in that order but it
doesn't actually matter that much
so in ppb though you don't have to write
this from loop anymore we make it as
easy as possible to get your first loop
going
so there we go we have a window open two
lines of code if anyone's ever played
with the other libraries this is a
little more less than you have to do
there um so this is just again the basic
everything needs a loop here's how we
handle it but let's talk about events
events are the things that a lot of
people have a little trouble wrapping
their minds around so what are events
anyway
events are things like mouse motion the
window trying to close the update event
in our case in general we also can use
this for like message passing so that
different objects can talk to each other
MPP B we have built the API so that it's
fairly simple to write new event
handlers so here we're gonna respond to
key presses
how did to do so we have a bunch of
constants defining all of the various
keys which is what you saw pop up there
and when I press the spacebar we're
going to just increase the size of the
object so we do this every time I press
space it grows so that's how simple it
is to actually write your event handlers
we have these four Mouse motion we have
them four there's an update event and a
couple of other features this is
basically where all of your actual game
logic is going to live is inside your
game objects inside event handlers so
let's talk about rendering I'm sure
you've noticed that we already do a lot
of rendering for you but we're gonna
demo some other stuff instead so when
we're talking graphics as far as ppb is
concerned we do raster graphics it's a
2d context we're using actual pixel
arrays under the hood but mostly you
don't actually have to think about this
we would rather you worry about the
metadata and not the actual process of
rendering so as you've seen a couple of
times already you know week we get a
square for free doesn't take much effort
that's just the base right there but you
can also do things like add images
this
all right so we run this oh wait let me
uncomment here we go all right so now we
have a ship on screen that's all it took
other features you can do just using
metadata in the same way you've kind of
already seen this but we'll do it again
and you can also manipulate the rotation
and so now we have a bigger one and a
reversed one and then additionally we've
made the all of these features composite
able so we can do all the things
with basically no extra code so
renderings nice and easy you can
manipulate all of those values as much
as you want so let's move on to the
actual architecture of how goo PV works
and then we'll get into the actual fun
stuff so we actually start at the top of
our tree this line of code is ugly and
there's a reason we hide it behind ppb
run so this is basically how you set up
your own custom engine normally inside
the context manager we would call a game
engine dot run but I'm actually trying
to show you some things so we're not
doing that here inside the engine though
there is a set of subsystems subsystems
are actually okay so these subsystems
are actually how we manage adding new
features to the game engine primarily
they were designed this way so that it
made it really easy for the developers
to do this but it also adds an API so
that if you want to add manipulations of
how the engine works you can add them to
this list and then once we start the
engine because it kind of does some lazy
work
once you start it you also have a whoa
that is the wrong file here we go all
right so if you look down at the bottom
here there is a list of scenes right now
there's only one because we haven't done
anything with them
we keep them in a list but we're using
it as a stack so you can push pop and
replace and to assist when that we
actually have this game engine current
scene which gives us whatever's on top
of the staff nice and easy
the neat thing about our scenes though
is they're actually containers so
they're iterable oh right
can't remove that so we do this and as
you can see we now have a object that
has two different objects inside of it
this is just a list because it's nicer
to print so the engine uses events to
manage them and I'll cover that in
detail since that's one of the advanced
features and then sprites what the
things inside are basically just data
bags as I kind of just demonstrated that
you can attach event handlers to in this
file I've done that up here
just so that the sprite actually
responds to the update event in the
moment all right so the engine is
actually also how we publish events
under the hood we you can send up a
signal so if you saw that signal
function and the parameters a bit ago
it's just a function on the engine we
can print the events just to show what's
there
all right so there is a DQ underneath
death whatever I can never remember how
to pronounce it and then if we call
publish it should it did not go through
I have to figure that out later
Oh in general though when you do GE
publish every object is actually going
to receive that event and it works when
you're actually running the engine I
don't know why it's not working here oh
all right so that is that's the boring
stuff this is the background information
you need to be able to understand what's
going on
so let's actually talk about making the
actual games themselves just close all
this down so
we've talked about system events that
kind of covered the kinds of things that
are in them but as I mentioned what
about manipulating them ourselves that
signal function we have here what we're
going to do is have this ship which
currently does this look wrong file
so this is what you've got so far what
we're going to actually do is make it so
that one of those two ships actually
sends another update event every time so
signal so here's that actual update
event and we're going to use the
existing ones time Delta before I
actually blow this up because I have
done it multiple times already
right so if we run this you saw about
how fast it was going they should go
about twice as fast so that's one way
you can do it you can signal any of the
existing events by doing this this is
less useful for actually making games
but it's good if you need to do things
like faking player input so you can make
your own classes just using data classes
actually so here we have a data class on
time dilation of basically the goal here
is we're going to instead of responding
to update events we're going to have the
time dilation ship change how often it
responds so we put our code here soft
accumulator plus equals self dot speed
Wow
[Music]
it's greater than or equal to one
so we can just raise our event and this
needed a time Delta as well so we want
to keep it the same and then down here
you have on time dilation is where we
actually do the movement so if I run
this now it'll break wonderful I think
it's this this is causing the weird
interaction so this should is not doing
the thing
this is why you don't like code oh yes I
did I I did this multiple times while
practicing and reminding myself not to
do it there we go now I should just work
so right now it's actually moving the
same speed because down here where we've
been San Shi edit it we've made speed
one but let's make speed whoa 13 it
would go very fast oh and there we've
made it faster it's running on the same
update speed as everything else but it's
not changing its speed it's actually
updating more times so the other cool
thing you can do actually do is
extending events um you could do let's
see right pebble eater so I need to
comment this out because I don't want
two engines running at once
mostly they won't run at once
so we write a little function up the
file we have a global called leader that
gets set during the set up and we call
GE dot run and up here we're going to
just print I missed a step here so here
we go we have to GE dot register we are
going to respond to the update event and
then our callback is add leader so now
despite it not being defined normally
you'll see that every time there's an
update event we've been getting output
of what's on that leader so this is one
way you can make objects available to
other things is by registering one of
these callbacks to add a new object to
each event that you care about so that's
events what about scenes I mentioned
changing scenes this is really just how
you manage the state machine that is the
staff so in this example we have a slash
thing I am going to warn this is going
to flash a little bit for anyone who
might have problems with that so to
start with we just signal
a start scene with our new game screen
and this fun bug this isn't actually
gonna do anything but it will not try to
instantiate the scene without it we're
working on that all right so if we run
this now we should have it'll go from
one to another okay so that was the
start scene in the middle of that what
you're going to get is the splash screen
here will actually receive a on pause
event
just to demo this so we run this and so
winix color changed the splash was
paused every scene when it gets started
actually receives a on scene started
which will see the function of in just a
moment so when we're done with the game
screen we're actually gonna move to this
game over screen and we have replaced
scene for that same idea we just pass it
our new scene and the quarks
all right so there's that so this is
going to last for about a second and
then it's going to switch to the game
over screen when it stops it's actually
going to print the runtime so you can
actually see some of the other features
here all right so we do this we get this
then this then this will close this and
as you can see when the first scene
pause we have that when the game tie
game started we saved that start time
and then when it stops we actually
printed the actual runtime which is
about a second and then the last thing
we need to do is be able to get back to
that initial scene that's all still on
the staff that one's even easier we just
need to tell it to stop the scene this
one doesn't have any examples but it
should turn back to that initial purple
color when we're done
oh it helps to actually spell my
libraries correctly so that's basically
all you need to know to start
manipulating scenes when you start
working with scenes just consider them a
piece of the game from levels to splash
strings to scoring screens to main menus
things like that and so you just use
that state machine to move between them
next tool you need to know how to use
sprites
so you've seen sprites being used
through all of these examples that are
like the core thing that puts things on
screen this is actually going to be
about how to make those sprites interact
with each other so the first thing we
can actually do is we can act their
Python classes we can pass other sprites
as parameters so in this sample we're
going to
here's our leader seemed to add our
leader
so here's this
just the same thing here
what seriously all right so we've done
this so this is going to put two three
objects on screen and then if we look at
the code on app on update the leader is
going to basically move nowhere because
it doesn't have a target all right no
right it's going to move towards the
center of the screen and then the other
ones are going to try to follow the
leader
which is basically what we get so that
was just using parameters you just pass
things around like you would any other
Python code but you can also use scene
get so what we're actually gonna do now
is we're gonna add a player
and just so I can demo some stuff that's
gonna crash you want a list of hashable
x' and not a strength oh so we're gonna
have this player if I run this as you
can see the player is going to follow
the mouse so that's done and so here
instead of going to this we need an
update scene so just like I mentioned
earlier where where you can extend the
event system the engine does its itself
so that the current scene is always
available on every single event you see
so in epic a team gets so the first
thing we can do is look by Kimes
and this is just gonna find everything
of that type and target is going to be
player top position so what this should
do is as it moves around the leader is
going to start following the player so
another simple way to do this in
addition you don't have to use kinds
there's also by tag which this should
work exactly the same way oh I should
change that to the actual thing we're
looking for so you can use that tag
system to also grab objects so if you
have multiple different types under the
same tag you'll get all of them and then
the last thing you can do is actually
just use the messaging system I don't
actually have a sample ready for this
but you've kind of seen this all in
order so what we'll do is
[Music]
we need data classes
all right so we've all seen this
so what we're going to do in here this
will actually go signal target move and
it will be that player dot position and
then down here
or we know if self-talk leader yep this
is a little backwards leader here is not
a boolean it's the actual leader itself
so I have to do all my logic in Reverse
so if we're not the leader we're
actually going to care more about this
target move so this will be self dot
target equals event dot position
and then up here
okay so now instead of following the
leader itself it's going to go where the
leader tells it to right
here we go okay well like I said I
didn't prep this one I'm not sure what's
wrong here
it's not callable do I try to call a
okay so we're gonna move on but that is
basically how it would work if I can
figure out where I'm trying to do that
oh wow that that's it's right here hey
there we go
and now they're all mostly chasing the
player so yeah there's the various ways
you can actually put sprites together to
do things together three different
systems you'll use them for different
things generally it depends on what
information you have at the time on
which one you're going to want to make
so the last step well let's talk about
subsystems
so I mentioned subsystems is how we
actually add features to the engine so I
am actually going to build an
achievement system right here in front
of you
remarkably it's more simple than you
think so
this is what it looks like so we just
have a very loose game here all right
so in order to get this started the
first thing we're actually going to need
is to start building let me delete that
one minute okay I might not be able to
get this done
all right so the basic idea is you would
make your you do this
all subsystems have to take args and
kwargs because they kind of receive
they're gonna receive all of the quarks
for all of the subsystems that's just
how things in instantiate goal equals 10
I'm not gonna get to show this one
running but basically you would write an
event that is the progress when you get
that self dot count plus equals one this
self goal if goal is greater than count
or reverse that all right raise an event
and then a sprite can be created which
you see somewhere no I didn't write that
part okay yeah you would just raise an
event and then can create a sprite in
response to that event on the scene and
you'd have a working achievement system
[Applause]