[MUSIC PLAYING]
Hello, everyone.
I'm Wouter van Oortmerssen and I'm
part of Fun Propulsion Labs at Google.
So what we do is we create libraries and tools
to try and improve game development
on Android and beyond.
One such library is FlatBuffers.
So FlatBuffers is a library that's
going to make your game load faster and use less memory.
Because ask yourself, how much time is your game spending
loading data?
Loading data can be expensive because usually game
data is represented differently on disk than it is in memory.
It might be compressed to save space
or it might be stored as text so that humans can edit it.
So the process of converting between the two
is what we call serialization.
Now serialization is kind of cool,
because data and memory can focus
on what it's good at, which means
being fast and easy to modify.
Meanwhile, data on disk can also focus
what it's good at, being compact,
machine-independent, and being forwards, backwards compatible.
But serialization also kind of sucks, because all this packing
and unpacking takes time.
It uses additional memory, since we
have to unpack this serialized data into objects
and format changes can be quite error-prone.
So in games, in particular, use a lot, as you know.
Is there a way we can fix this?
Well, this all comes from the assumption
that memory and disk must be inherently incompatible ways
of storing things.
But what if we try anyway?
Well, then you get FlatBuffers.
So what FlatBuffers really is is a portable binding format
that allows you to store things on disk
the same as in memory, meaning you
can move from one to the other without any conversion.
It works well on disks because it has fixed rules
for data sizes, alignment, an [? and additional ?] platforms.
It deals with forwards and backwards compatibility,
which means you can add and remove fields at will.
It also works well on memory.
Everything is reachable through offset, so it's very fast.
It works from read-only media, which is very cool.
And it's more compact and cache-friendly
than separately allocated objects.
So at this point, I can tell you're all convinced
and you just want to use FlatBuffers.
So how do you do that?
Well, first you write a schema.
Then you give this schema to our friendly compiler
and we'll generate code for you in your favorite language--
assuming your favorite language is one of these four.
Then you load up this generated code in your game.
And you read and write FlatBuffer data.
So a schema's pretty important for efficiency.
And it also allows you at access your data
without error checking.
And schemas can be changed without having
to regenerate all your data.
So for example, you can update your game,
and all your old saved games still work.
So what can you stick in a FlatBuffer?
There is the usual suspects over here.
Then, to support forwards and backwards compatibility,
we have tables where fields can be added and removed at will.
And this goes through an indirection
called a virtual table.
Then we also have structs.
If you want the maximum efficiency
these don't support format evolution,
but they're the fastest way to store data.
And finally, we have enums, unions, and other cool things.
So let's have a look at how to implement [? on the hood. ?]
So this is what an object looks like in memory.
It starts off with an offset to a virtual table, which
contains the offsets to the actual fields.
Now, these virtual tables are shared between similar objects
so they're actually not that expensive.
Then what follows is the actual fields all
in line, including the structs.
And then finally, if you have a reference to bigger data,
that goes through an offset indirection.
So let's look at some C++ code of how you would use this.
You'd first get a pointer to your root object.
Then you would use field accessors
to actually look at the data.
And these hide all the offset lookups for you.
So very convenient.
Creation using a FlatBuffer builder helper class.
And then you call these create functions,
which will create objects inside that buffer for you.
So I know this all sounds incredibly fast,
but how fast is it really?
So let's compare against some popular other serialization
solutions.
And, of course, you should take benchmarks
with a grain of salt.
But I still think you'll find these interesting.
So if you're going to read a FlatBuffer,
then you'll find it's over 1,000 times faster
than other solutions.
And this is, of course, because we're not actually parsing
or allocating anything.
Writing a FlatBuffer is still about 100 times faster.
It's still pretty good.
Then we're not actually allocating any objects
when we're reading, so that is great.
And finally, the code is also really small,
both to generate a code and a library code.
At this point though, you might say, I don't care.
I'm still going to use text because it's easier
to work with.
Well guess what?
FlatBuffers also supports JSON out of the box.
So that means you can convert to binary format
either on the fly in your game or as a pre-process
with our command line tool.
And that's everything I've got.
Come find us online or come talk to me at GDC.
Thank you.
[MUSIC PLAYING]