| FlatBuffers An open source project by FPL.

- Programmer's Guide
- Platform / Language / Feature support
- Benchmarks
- FlatBuffers white paper
- FlatBuffers internals
- Grammar of the schema language
- API Reference
- Contributing

Tutorial

## Overview

This tutorial provides a basic example of how to work with FlatBuffers. We will step through a simple example application, which shows you how to:

- Write a FlatBuffer `schema` file.
- Use the `flatc` FlatBuffer compiler.
- Parse JSON files that conform to a schema into FlatBuffer binary files.
- Use the generated files in many of the supported languages (such as C++, Java, and more.)

During this example, imagine that you are creating a game where the main character, the hero of the story, needs to slay some `orc`s. We will walk through each step necessary to create this monster type using FlatBuffers.

Please select your desired language for our quest: C++ Java C# Go Python JavaScript PHP C

## Where to Find the Example Code

Samples demonstating the concepts in this example are located in the source code package, under the `samples` directory. You can browse the samples on GitHub here.

Note: The above does not apply to C, instead look here.

For your chosen language, please cross-reference with:

sample_binary.cpp
SampleBinary.java
SampleBinary.cs
sample_binary.go
sample_binary.py
samplebinary.js
SampleBinary.php
monster.c

## Writing the Monsters' FlatBuffer Schema

To start working with FlatBuffers, you first need to create a `schema` file, which defines the format for each data structure you wish to serialize. Here is the `schema` that defines the template for our monsters:

1 // Example IDL file for our monster's schema.
2
3 namespace MyGame.Sample;
4
5 enum Color:byte { Red = 0, Green, Blue = 2 }
6
7 union Equipment { Weapon } // Optionally add more tables.
8
9 struct Vec3 {
10 x:float;
11 y:float;
12 z:float;
13 }
14
15 table Monster {
16 pos:Vec3; // Struct.
17 mana:short = 150;
18 hp:short = 100;
19 name:string;
20 friendly:bool = false (deprecated);
21 inventory:[ubyte]; // Vector of scalars.
22 color:Color = Blue; // Enum.
23 weapons:[Weapon]; // Vector of tables.
24 equipped:Equipment; // Union.
25 path:[Vec3]; // Vector of structs.
26 }
27
28 table Weapon {
29 name:string;
30 damage:short;
31 }
32
33 root_type Monster;

As you can see, the syntax for the `schema` Interface Definition Language (IDL) is similar to those of the C family of languages, and other IDL languages. Let's examine each part of this `schema` to determine what it does.

The `schema` starts with a `namespace` declaration. This determines the corresponding package/namespace for the generated code. In our example, we have the `Sample` namespace inside of the `MyGame` namespace.

Next, we have an `enum` definition. In this example, we have an `enum` of type `byte`, named `Color`. We have three values in this `enum`: `Red`, `Green`, and `Blue`. We specify `Red = 0` and `Blue = 2`, but we do not specify an explicit value for `Green`. Since the behavior of an `enum` is to increment if unspecified, `Green` will receive the implicit value of `1`.

Following the `enum` is a `union`. The `union` in this example is not very useful, as it only contains the one `table` (named `Weapon`). If we had created multiple tables that we would want the `union` to be able to reference, we could add more elements to the `union Equipment`.

After the `union` comes a `struct Vec3`, which represents a floating point vector with `3` dimensions. We use a `struct` here, over a `table`, because `struct`s are ideal for data structures that will not change, since they use less memory and have faster lookup.

The `Monster` table is the main object in our FlatBuffer. This will be used as the template to store our `orc` monster. We specify some default values for fields, such as `mana:short = 150`. All unspecified fields will default to `0` or `NULL`. Another thing to note is the line `friendly:bool = false (deprecated);`. Since you cannot delete fields from a `table` (to support backwards compatability), you can set fields as `deprecated`, which will prevent the generation of accessors for this field in the generated code. Be careful when using `deprecated`, however, as it may break legacy code that used this accessor.

The `Weapon` table is a sub-table used within our FlatBuffer. It is used twice: once within the `Monster` table and once within the `Equipment` enum. For our `Monster`, it is used to populate a `vector of tables` via the `weapons` field within our `Monster`. It is also the only table referenced by the `Equipment` enum.

The last part of the `schema` is the `root_type`. The root type declares what will be the root table for the serialized data. In our case, the root type is our `Monster` table.

#### More Information About Schemas

You can find a complete guide to writing `schema` files in the Writing a schema section of the Programmer's Guide. You can also view the formal Grammar of the schema language.

## Compiling the Monsters' Schema

After you have written the FlatBuffers schema, the next step is to compile it.

If you have not already done so, please follow these instructions to build `flatc`, the FlatBuffer compiler.

Once `flatc` is built successfully, compile the schema for your language:

Note: If you're working in C, you need to use the separate project FlatCC which contains a schema compiler and runtime library in C for C.
See flatcc build instructions.
Please be aware of the difference between `flatc` and `flatcc` tools.
1 cd flatbuffers/sample
2 ./../flatc --cpp samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --java samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --csharp samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --go samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --python samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --javascript samples/monster.fbs
1 cd flatbuffers/sample
2 ./../flatc --php samples/monster.fbs
1 cd flatcc
2 mkdir -p build/tmp/samples/monster
3 bin/flatcc -a -o build/tmp/samples/monster samples/monster/monster.fbs
4 # or just
5 flatcc/samples/monster/build.sh

For a more complete guide to using the `flatc` compiler, please read the Using the schema compiler section of the Programmer's Guide.

## Reading and Writing Monster FlatBuffers

Now that we have compiled the schema for our programming language, we can start creating some monsters and serializing/deserializing them from FlatBuffers.

#### Creating and Writing Orc FlatBuffers

The first step is to import/include the library, generated files, etc.

#include "monster_generate.h" // This was generated by `flatc`.
using namespace MyGame::Sample; // Specified in the schema.
import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder;
using FlatBuffers;
using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.)
1 import (
2 flatbuffers "github.com/google/flatbuffers/go"
3 sample "MyGame/Sample"
4 )
1 import flatbuffers
2
3 # Generated by `flatc`.
4 import MyGame.Sample.Color
5 import MyGame.Sample.Equipment
6 import MyGame.Sample.Monster
7 import MyGame.Sample.Vec3
8 import MyGame.Sample.Weapon
// The following code is for JavaScript module loaders (e.g. Node.js). See
// below for a browser-based HTML/JavaScript example of including the library.
var flatbuffers = require('/js/flatbuffers').flatbuffers;
var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
//--------------------------------------------------------------------------//
// The following code is for browser-based HTML/JavaScript. Use the above code
// for JavaScript module loaders (e.g. Node.js).
<script src="../js/flatbuffers.js"></script>
<script src="monster_generated.js"></script> // Generated by `flatc`.
// It is recommended that your use PSR autoload when using FlatBuffers in PHP.
// Here is an example from `SampleBinary.php`:
function __autoload($class_name) {
// The last segment of the class name matches the file name.
$class = substr($class_name, strrpos($class_name, "\\") + 1);
$root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
// Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files.
$paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
foreach ($paths as $path) {
$file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
if (file_exists($file)) {
require($file);
break;
}
}
}
#include "monster_builder.h" // Generated by `flatcc`.
// Convenient namespace macro to manage long namespace prefix.
#undef ns
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
// A helper to simplify creating vectors from C-arrays.
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))

Now we are ready to start building some buffers. In order to start, we need to create an instance of the `FlatBufferBuilder`, which will contain the buffer as it grows. You can pass an initial size of the buffer (here 1024 bytes), which will grow automatically if needed:

// Create a `FlatBufferBuilder`, which will be used to create our
// monsters' FlatBuffers.
flatbuffers::FlatBufferBuilder builder(1024);
// Create a `FlatBufferBuilder`, which will be used to create our
// monsters' FlatBuffers.
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
// Create a `FlatBufferBuilder`, which will be used to create our
// monsters' FlatBuffers.
var builder = new FlatBufferBuilder(1024);
1 // Create a `FlatBufferBuilder`, which will be used to create our
2 // monsters' FlatBuffers.
3 builder := flatbuffers.NewBuilder(1024)
1 # Create a `FlatBufferBuilder`, which will be used to create our
2 # monsters' FlatBuffers.
3 builder = flatbuffers.Builder(1024)
// Create a `flatbuffer.Builder`, which will be used to create our
// monsters' FlatBuffers.
var builder = new flatbuffers.Builder(1024);
// Create a `FlatBufferBuilder`, which will be used to create our
// monsters' FlatBuffers.
$builder = new Google\FlatBuffers\FlatbufferBuilder(1024);
flatcc_builder_t builder, *B;
B = &builder;
// Initialize the builder object.
flatcc_builder_init(B);

After creating the `builder`, we can start serializing our data. Before we make our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.

auto weapon_one_name = builder.CreateString("Sword");
short weapon_one_damage = 3;
auto weapon_two_name = builder.CreateString("Axe");
short weapon_two_damage = 5;
// Use the `CreateWeapon` shortcut to create Weapons with all the fields set.
auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage);
auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage);
int weaponOneName = builder.createString("Sword")
short weaponOneDamage = 3;
int weaponTwoName = builder.createString("Axe");
short weaponTwoDamage = 5;
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
int sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
var weaponOneName = builder.CreateString("Sword");
var weaponOneDamage = 3;
var weaponTwoName = builder.CreateString("Axe");
var weaponTwoDamage = 5;
// Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
var sword = Weapon.CreateWeapon(builder, weaponOneName, (short)weaponOneDamage);
var axe = Weapon.CreateWeapon(builder, weaponTwoName, (short)weaponTwoDamage);
1 weaponOne := builder.CreateString("Sword")
2 weaponTwo := builder.CreateString("Axe")
3
4 // Create the first `Weapon` ("Sword").
5 sample.WeaponStart(builder)
6 sample.Weapon.AddName(builder, weaponOne)
7 sample.Weapon.AddDamage(builder, 3)
8 sword := sample.WeaponEnd(builder)
9
10 // Create the second `Weapon` ("Axe").
11 sample.WeaponStart(builder)
12 sample.Weapon.AddName(builder, weaponTwo)
13 sample.Weapon.AddDamage(builder, 5)
14 axe := sample.WeaponEnd(builder)
1 weapon_one = builder.CreateString('Sword')
2 weapon_two = builder.CreateString('Axe')
3
4 # Create the first `Weapon` ('Sword').
5 MyGame.Sample.Weapon.WeaponStart(builder)
6 MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
7 MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
8 sword = MyGame.Sample.Weapon.WeaponEnd(builder)
9
10 # Create the second `Weapon` ('Axe').
11 MyGame.Sample.Weapon.WeaponStart(builder)
12 MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
13 MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
14 axe = MyGame.Sample.Weapon.WeaponEnd(builder)
var weaponOne = builder.createString('Sword');
var weaponTwo = builder.createString('Axe');
// Create the first `Weapon` ('Sword').
MyGame.Sample.Weapon.startWeapon(builder);
MyGame.Sample.Weapon.addName(builder, weaponOne);
MyGame.Sample.Weapon.addDamage(builder, 3);
var sword = MyGame.Sample.Weapon.endWeapon(builder);
// Create the second `Weapon` ('Axe').
MyGame.Sample.Weapon.startWeapon(builder);
MyGame.Sample.Weapon.addName(builder, weaponTwo);
MyGame.Sample.Weapon.addDamage(builder, 5);
var axe = MyGame.Sample.Weapon.endWeapon(builder);
// Create the `Weapon`s using the `createWeapon()` helper function.
$weapon_one_name = $builder->createString("Sword");
$sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one_name, 3);
$weapon_two_name = $builder->createString("Axe");
$axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two_name, 5);
// Create an array from the two `Weapon`s and pass it to the
// `CreateWeaponsVector()` method to create a FlatBuffer vector.
$weaps = array($sword, $axe);
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
ns(Weapon_ref_t) weapon_one_name = flatbuffers_string_create_str(B, "Sword");
uint16_t weapon_one_damage = 3;
ns(Weapon_ref_t) weapon_two_name = flatbuffers_string_create_str(B, "Axe");
uint16_t weapon_two_damage = 5;
ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage));
ns(Weapon_ref_t) axe = ns(Weapon_create(B, weapon_two_name, weapon_two_damage));

Now let's create our monster, the `orc`. For this `orc`, lets make him `red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him a large pool of hit points with `300`. We can give him a vector of weapons to choose from (our `Sword` and `Axe` from earlier). In this case, we will equip him with the `Axe`, since it is the most powerful of the two. Lastly, let's fill his inventory with some potential treasures that can be taken once he is defeated.

Before we serialize a monster, we need to first serialize any objects that are contained there-in, i.e. we serialize the data tree using depth-first, pre-order traversal. This is generally easy to do on any tree structures.

// Serialize a name for our monster, called "Orc".
auto name = builder.CreateString("Orc");
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
unsigned char treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto inventory = builder.CreateVector(treasure, 10);
// Serialize a name for our monster, called "Orc".
int name = builder.createString("Orc");
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int inv = Monster.createInventoryVector(builder, treasure);
// Serialize a name for our monster, called "Orc".
var name = builder.CreateString("Orc");
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
// Note: Since we prepend the bytes, this loop iterates in reverse order.
Monster.StartInventoryVector(builder, 10);
for (int i = 9; i >= 0; i--)
{
builder.AddByte((byte)i);
}
var inv = builder.EndVector();
1 // Serialize a name for our monster, called "Orc".
2 name := builder.CreateString("Orc")
3
4 // Create a `vector` representing the inventory of the Orc. Each number
5 // could correspond to an item that can be claimed after he is slain.
6 // Note: Since we prepend the bytes, this loop iterates in reverse.
7 sample.MonsterStartInventoryVector(builder, 10)
8 for i := 9; i >= 0; i-- {
9 builder.PrependByte(byte(i))
10 }
11 int := builder.EndVector(10)
1 # Serialize a name for our monster, called "Orc".
2 name = builder.CreateString("Orc")
3
4 # Create a `vector` representing the inventory of the Orc. Each number
5 # could correspond to an item that can be claimed after he is slain.
6 # Note: Since we prepend the bytes, this loop iterates in reverse.
7 MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
8 for i in reversed(range(0, 10)):
9 builder.PrependByte(i)
10 inv = builder.EndVector(10)
// Serialize a name for our monster, called 'Orc'.
var name = builder.createString('Orc');
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
// Serialize a name for our monster, called "Orc".
$name = $builder->createString("Orc");
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
$treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
$inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
// Serialize a name for our monster, called "Orc".
// The _str suffix indicates the source is an ascii-z string.
flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc");
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
flatbuffers_uint8_vec_ref_t inventory;
// `c_vec_len` is the convenience macro we defined earlier.
inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure));

We serialized two built-in data types (`string` and `vector`) and captured their return values. These values are offsets into the serialized data, indicating where they are stored, such that we can refer to them below when adding fields to our monster.

Note: To create a `vector` of nested objects (e.g. `table`s, `string`s, or other `vector`s), collect their offsets into a temporary data structure, and then create an additional `vector` containing their offsets.

For example, take a look at the two `Weapon`s that we created earlier (`Sword` and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in memory. Therefore we can create a FlatBuffer `vector` to contain these offsets.

// Place the weapons into a `std::vector`, then convert that into a FlatBuffer `vector`.
std::vector<flatbuffers::Offset<Weapon>> weapons_vector;
weapons_vector.push_back(sword);
weapons_vector.push_back(axe);
auto weapons = builder.CreateVector(weapons_vector);
// Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
// create a FlatBuffer vector.
int[] weaps = new int[2];
weaps[0] = sword;
weaps[1] = axe;
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
int weapons = Monster.createWeaponsVector(builder, weaps);
var weaps = new Offset<Weapon>[2];
weaps[0] = sword;
weaps[1] = axe;
// Pass the `weaps` array into the `CreateWeaponsVector()` method to create a FlatBuffer vector.
var weapons = Monster.CreateWeaponsVector(builder, weaps);
1 // Create a FlatBuffer vector and prepend the weapons.
2 // Note: Since we prepend the data, prepend them in reverse order.
3 sample.MonsterStartWeaponsVector(builder, 2)
4 builder.PrependUOffsetT(axe)
5 builder.PrependUOffsetT(sword)
6 weapons := builder.EndVector(2)
1 # Create a FlatBuffer vector and prepend the weapons.
2 # Note: Since we prepend the data, prepend them in reverse order.
3 MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
4 builder.PrependUOffsetTRelative(axe)
5 builder.PrependUOffsetTRelative(sword)
6 weapons = builder.EndVector(2)
// Create an array from the two `Weapon`s and pass it to the
// `createWeaponsVector()` method to create a FlatBuffer vector.
var weaps = [sword, axe];
var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
// Create an array from the two `Weapon`s and pass it to the
// `CreateWeaponsVector()` method to create a FlatBuffer vector.
$weaps = array($sword, $axe);
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
// We use the internal builder stack to implement a dynamic vector.
ns(Weapon_vec_start(B));
ns(Weapon_vec_push(B, sword));
ns(Weapon_vec_push(B, axe));
ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B));
Note there's additional convenience overloads of `CreateVector`, allowing you to work with data that's not in a `std::vector`, or allowing you to generate elements by calling a lambda. For the common case of `std::vector<std::string>` there's also `CreateVectorOfStrings`.

Note that vectors of structs are serialized differently from tables, since structs are stored in-line in the vector. For example, to create a vector for the `path` field above:

Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
auto path = fbb.CreateVectorOfStructs(points, 2);
Monster.startPathVector(fbb, 2);
Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f);
int path = fbb.endVector();
Monster.StartPathVector(fbb, 2);
Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f);
var path = fbb.EndVector();
1 sample.MonsterStartPathVector(builder, 2)
2 sample.CreateVec3(builder, 1.0, 2.0, 3.0)
3 sample.CreateVec3(builder, 4.0, 5.0, 6.0)
4 path := builder.EndVector(2)
1 MyGame.Example.Monster.MonsterStartPathVector(builder, 2)
2 MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
3 MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
4 path = builder.EndVector(2)
MyGame.Example.Monster.startPathVector(builder, 2);
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
var path = builder.endVector();
\MyGame\Example\Monster::StartPathVector($builder, 2);
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
$path = $builder->endVector();
// TBD

We have now serialized the non-scalar components of the orc, so we can serialize the monster itself:

// Set his hit points to 300 and his mana to 150.
int hp = 300;
int mana = 150;
// Finally, create the monster using the `CreateMonster` helper function
// to set all fields.
auto orc = CreateMonster(builder, Vec3(1.0f, 2.0f, 3.0f), mana, hp, name,
inventory, Color_Red, weapons, Equipment_Weapon,
axe.Union(), path);
// Create our monster using `startMonster()` and `endMonster()`.
Monster.startMonster(builder);
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
Monster.addName(builder, name);
Monster.addColor(builder, Color.Red);
Monster.addHp(builder, (short)300);
Monster.addInventory(builder, inv);
Monster.addWeapons(builder, weapons);
Monster.addEquippedType(builder, Equipment.Weapon);
Monster.addEquipped(builder, axe);
Monster.addPath(builder, path);
int orc = Monster.endMonster(builder);
// Create our monster using `StartMonster()` and `EndMonster()`.
Monster.StartMonster(builder);
Monster.AddPos(builder, Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f));
Monster.AddHp(builder, (short)300);
Monster.AddName(builder, name);
Monster.AddInventory(builder, inv);
Monster.AddColor(builder, Color.Red);
Monster.AddWeapons(builder, weapons);
Monster.AddEquippedType(builder, Equipment.Weapon);
Monster.AddEquipped(builder, axe.Value); // Axe
Monster.AddPath(builder, path);
var orc = Monster.EndMonster(builder);
1 // Create our monster using `MonsterStart()` and `MonsterEnd()`.
2 sample.MonsterStart(builder)
3 sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0))
4 sample.MonsterAddHp(builder, 300)
5 sample.MonsterAddName(builder, name)
6 sample.MonsterAddInventory(builder, inv)
7 sample.MonsterAddColor(builder, sample.ColorRed)
8 sample.MonsterAddWeapons(builder, weapons)
9 sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
10 sample.MonsterAddEquipped(builder, axe)
11 sample.MonsterAddPath(builder, path)
12 orc := sample.MonsterEnd(builder)
1 # Create our monster by using `MonsterStart()` and `MonsterEnd()`.
2 MyGame.Sample.Monster.MonsterStart(builder)
3 MyGame.Sample.Monster.MonsterAddPos(builder,
4 MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
5 MyGame.Sample.Monster.MonsterAddHp(builder, 300)
6 MyGame.Sample.Monster.MonsterAddName(builder, name)
7 MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
8 MyGame.Sample.Monster.MonsterAddColor(builder,
9 MyGame.Sample.Color.Color().Red)
10 MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
11 MyGame.Sample.Monster.MonsterAddEquippedType(
12 builder, MyGame.Sample.Equipment.Equipment().Weapon)
13 MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
14 MyGame.Sample.Monster.MonsterAddPath(builder, path)
15 orc = MyGame.Sample.Monster.MonsterEnd(builder)
// Create our monster by using `startMonster()` and `endMonster()`.
MyGame.Sample.Monster.startMonster(builder);
MyGame.Sample.Monster.addPos(builder,
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
MyGame.Sample.Monster.addHp(builder, 300);
MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
MyGame.Sample.Monster.addName(builder, name);
MyGame.Sample.Monster.addInventory(builder, inv);
MyGame.Sample.Monster.addWeapons(builder, weapons);
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
MyGame.Sample.Monster.addEquipped(builder, axe);
MyGame.Sample.Monster.addPath(builder, path);
var orc = MyGame.Sample.Monster.endMonster(builder);
// Create our monster by using `StartMonster()` and `EndMonster()`.
\MyGame\Sample\Monster::StartMonster($builder);
\MyGame\Sample\Monster::AddPos($builder,
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0));
\MyGame\Sample\Monster::AddHp($builder, 300);
\MyGame\Sample\Monster::AddName($builder, $name);
\MyGame\Sample\Monster::AddInventory($builder, $inv);
\MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
\MyGame\Sample\Monster::AddWeapons($builder, $weapons);
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
\MyGame\Sample\Monster::AddEquipped($builder, $axe);
\MyGame\Sample\Monster::AddPath($builder, $path);
$orc = \MyGame\Sample\Monster::EndMonster($builder);
// Set his hit points to 300 and his mana to 150.
uint16_t hp = 300;
uint16_t mana = 150;
// Define an equipment union. `create` calls in C has a single
// argument for unions where C++ has both a type and a data argument.
ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red),
weapons, equipped, path));

Note how we create `Vec3` struct in-line in the table. Unlike tables, structs are simple combinations of scalars that are always stored inline, just like scalars themselves.

Important: Unlike structs, you should not nest tables or other objects, which is why we created all the strings/vectors/tables that this monster refers to before `start`. If you try to create any of them between `start` and `end`, you will get an assert/exception/panic depending on your language.

Note: Since we are passing `150` as the `mana` field, which happens to be the default value, the field will not actually be written to the buffer, since the default value will be returned on query anyway. This is a nice space savings, especially if default values are common in your data. It also means that you do not need to be worried of adding a lot of fields that are only used in a small number of instances, as it will not bloat the buffer if unused.

If you do not wish to set every field in a `table`, it may be more convenient to manually set each field of your monster, instead of calling `CreateMonster()`. The following snippet is functionally equivalent to the above code, but provides a bit more flexibility.
// You can use this code instead of `CreateMonster()`, to create our orc
// manually.
MonsterBuilder monster_builder(builder);
monster_builder.add_pos(&pos);
monster_builder.add_hp(hp);
monster_builder.add_name(name);
monster_builder.add_inventory(inventory);
monster_builder.add_color(Color_Red);
monster_builder.add_weapons(weapons);
monster_builder.add_equipped_type(Equipment_Weapon);
monster_builder.add_equpped(axe);
auto orc = monster_builder.Finish();
If you do not wish to set every field in a `table`, it may be more convenient to manually set each field of your monster, instead of calling `create_monster_as_root()`. The following snippet is functionally equivalent to the above code, but provides a bit more flexibility.
// It is important to pair `start_as_root` with `end_as_root`.
ns(Monster_start_as_root(B));
ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f));
// or alternatively
//ns(Monster_pos_add(&pos);
ns(Monster_hp_add(B, hp));
// Notice that `Monser_name_add` adds a string reference unlike the
// add_str and add_strn variants.
ns(Monster_name_add(B, name));
ns(Monster_inventory_add(B, inventory));
ns(Monster_color_add(B, ns(Color_Red)));
ns(Monster_weapons_add(B, weapons));
ns(Monster_equipped_add(B, equipped));
// Complete the monster object and make it the buffer root object.
ns(Monster_end_as_root(B));

Before finishing the serialization, let's take a quick look at FlatBuffer `union Equipped`. There are two parts to each FlatBuffer `union`. The first, is a hidden field `_type`, that is generated to hold the type of `table` referred to by the `union`. This allows you to know which type to cast to at runtime. Second, is the `union`'s data.

In our example, the last two things we added to our `Monster` were the `Equipped Type` and the `Equipped` union itself.

Here is a repetition these lines, to help highlight them more clearly:

monster_builder.add_equipped_type(Equipment_Weapon); // Union type
monster_builder.add_equipped(axe); // Union data
Monster.addEquippedType(builder, Equipment.Weapon); // Union type
Monster.addEquipped(axe); // Union data
Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
Monster.AddEquipped(builder, axe.Value); // Union data
1 sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon) // Union type
2 sample.MonsterAddEquipped(builder, axe) // Union data
1 MyGame.Sample.Monster.MonsterAddEquippedType( # Union type
2 builder, MyGame.Sample.Equipment.Equipment().Weapon)
3 MyGame.Sample.Monster.MonsterAddEquipped(builder, axe) # Union data
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); // Union type
MyGame.Sample.Monster.addEquipped(builder, axe); // Union data
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon); // Union type
\MyGame\Sample\Monster::AddEquipped($builder, $axe); // Union data
// Add union type and data simultanously.
ns(Monster_equipped_Weapon_add(B, axe));

After you have created your buffer, you will have the offset to the root of the data in the `orc` variable, so you can finish the buffer by calling the appropriate `finish` method.

// Call `Finish()` to instruct the builder that this monster is complete.
// Note: Regardless of how you created the `orc`, you still need to call
// `Finish()` on the `FlatBufferBuilder`.
builder.Finish(orc); // You could also call `FinishMonsterBuffer(builder,
// orc);`.
// Call `finish()` to instruct the builder that this monster is complete.
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
// Call `Finish()` to instruct the builder that this monster is complete.
builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`.
1 // Call `Finish()` to instruct the builder that this monster is complete.
2 builder.Finish(orc)
1 # Call `Finish()` to instruct the builder that this monster is complete.
2 builder.Finish(orc)
// Call `finish()` to instruct the builder that this monster is complete.
builder.finish(orc); // You could also call `MyGame.Example.Monster.finishMonsterBuffer(builder,
// orc);`.
// Call `finish()` to instruct the builder that this monster is complete.
$builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer(
// $builder, $orc);`.
// Because we used `Monster_create_as_root`, we do not need a `finish` call in C`.

The buffer is now ready to be stored somewhere, sent over the network, be compressed, or whatever you'd like to do with it. You can access the buffer like so:

// This must be called after `Finish()`.
uint8_t *buf = builder.GetBufferPointer();
int size = builder.GetSize(); // Returns the size of the buffer that
// `GetBufferPointer()` points to.
// This must be called after `finish()`.
java.nio.ByteBuffer buf = builder.dataBuffer();
// The data in this ByteBuffer does NOT start at 0, but at buf.position().
// The number of bytes is buf.remaining().
// Alternatively this copies the above data out of the ByteBuffer for you:
bytes[] buf = builder.sizedByteArray();
// This must be called after `Finish()`.
var buf = builder.DataBuffer; // Of type `FlatBuffers.ByteBuffer`.
// The data in this ByteBuffer does NOT start at 0, but at buf.Position.
// The end of the data is marked by buf.Length, so the size is
// buf.Length - buf.Position.
// Alternatively this copies the above data out of the ByteBuffer for you:
bytes[] buf = builder.SizedByteArray();
1 // This must be called after `Finish()`.
2 buf := builder.FinishedBytes() // Of type `byte[]`.
1 # This must be called after `Finish()`.
2 buf = builder.Output() // Of type `bytearray`.
// This must be called after `finish()`.
var buf = builder.asUint8Array(); // Of type `Uint8Array`.
// This must be called after `finish()`.
$buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
// The data in this ByteBuffer does NOT start at 0, but at buf->getPosition().
// The end of the data is marked by buf->capacity(), so the size is
// buf->capacity() - buf->getPosition().
uint8_t *buf;
size_t size;
// Allocate and extract a readable buffer from internal builder heap.
// The returned buffer must be deallocated using `free`.
// NOTE: Finalizing the buffer does NOT change the builder, it
// just creates a snapshot of the builder content.
buf = flatcc_builder_finalize_buffer(B, &size);
// use buf
free(buf);
// Optionally reset builder to reuse builder without deallocating
// internal stack and heap.
flatcc_builder_reset(B);
// build next buffer.
// ...
// Cleanup.
flatcc_builder_clear(B);

Now you can write the bytes to a file, send them over the network.. Make sure your file mode (or tranfer protocol) is set to BINARY, not text. If you transfer a FlatBuffer in text mode, the buffer will be corrupted, which will lead to hard to find problems when you read the buffer.

#### Reading Orc FlatBuffers

Now that we have successfully created an `Orc` FlatBuffer, the monster data can be saved, sent over a network, etc. Let's now adventure into the inverse, and deserialize a FlatBuffer.

This section requires the same import/include, namespace, etc. requirements as before:

#include "monster_generate.h" // This was generated by `flatc`.
using namespace MyGame::Sample; // Specified in the schema.
import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder;
using FlatBuffers;
using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.)
1 import (
2 flatbuffers "github.com/google/flatbuffers/go"
3 sample "MyGame/Sample"
4 )
1 import flatbuffers
2
3 # Generated by `flatc`.
4 import MyGame.Sample.Any
5 import MyGame.Sample.Color
6 import MyGame.Sample.Monster
7 import MyGame.Sample.Vec3
// The following code is for JavaScript module loaders (e.g. Node.js). See
// below for a browser-based HTML/JavaScript example of including the library.
var flatbuffers = require('/js/flatbuffers').flatbuffers;
var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
//--------------------------------------------------------------------------//
// The following code is for browser-based HTML/JavaScript. Use the above code
// for JavaScript module loaders (e.g. Node.js).
<script src="../js/flatbuffers.js"></script>
<script src="monster_generated.js"></script> // Generated by `flatc`.
// It is recommended that your use PSR autoload when using FlatBuffers in PHP.
// Here is an example from `SampleBinary.php`:
function __autoload($class_name) {
// The last segment of the class name matches the file name.
$class = substr($class_name, strrpos($class_name, "\\") + 1);
$root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
// Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files.
$paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
foreach ($paths as $path) {
$file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
if (file_exists($file)) {
require($file);
break;
}
}
}
// Only needed if we don't have `#include "monster_builder.h"`.
#include "monster_reader.h"
#undef ns
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.

Then, assuming you have a buffer of bytes received from disk, network, etc., you can create start accessing the buffer like so:

Again, make sure you read the bytes in BINARY mode, otherwise the code below won't work

uint8_t *buffer_pointer = /* the data you just read */;
// Get a pointer to the root object inside the buffer.
auto monster = GetMonster(buffer_pointer);
// `monster` is of type `Monster *`.
// Note: root object pointers are NOT the same as `buffer_pointer`.
byte[] bytes = /* the data you just read */
java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes);
// Get an accessor to the root object inside the buffer.
Monster monster = Monster.getRootAsMonster(buf);
byte[] bytes = /* the data you just read */
var buf = new ByteBuffer(bytes);
// Get an accessor to the root object inside the buffer.
var monster = Monster.GetRootAsMonster(buf);
1 var buf []byte = /* the data you just read */
2
3 // Get an accessor to the root object inside the buffer.
4 monster := sample.GetRootAsMonster(buf, 0)
5
6 // Note: We use `0` for the offset here, which is typical for most buffers
7 // you would read. If you wanted to read from `builder.Bytes` directly, you
8 // would need to pass in the offset of `builder.Head()`, as the builder
9 // constructs the buffer backwards, so may not start at offset 0.
1 buf = /* the data you just read, in an object of type "bytearray" */
2
3 // Get an accessor to the root object inside the buffer.
4 monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
5
6 # Note: We use `0` for the offset here, which is typical for most buffers
7 # you would read. If you wanted to read from the `builder.Bytes` directly,
8 # you would need to pass in the offset of `builder.Head()`, as the builder
9 # constructs the buffer backwards, so may not start at offset 0.
var bytes = /* the data you just read, in an object of type "Uint8Array" */
var buf = new flatbuffers.ByteBuffer(bytes);
// Get an accessor to the root object inside the buffer.
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
$bytes = /* the data you just read, in a string */
$buf = Google\FlatBuffers\ByteBuffer::wrap($bytes);
// Get an accessor to the root object inside the buffer.
$monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
// Note that we use the `table_t` suffix when reading a table object
// as opposed to the `ref_t` suffix used during the construction of
// the buffer.
ns(Monster_table_t) monster = ns(Monster_as_root(buffer));
// Note: root object pointers are NOT the same as the `buffer` pointer.

If you look in the generated files from the schema compiler, you will see it generated accessors for all non-`deprecated` fields. For example:

auto hp = monster->hp();
auto mana = monster->mana();
auto name = monster->name()->c_str();
short hp = monster.hp();
short mana = monster.mana();
String name = monster.name();
// For C#, unlike other languages support by FlatBuffers, most values (except for
// vectors and unions) are available as propreties instead of asccessor methods.
var hp = monster.Hp
var mana = monster.Mana
var name = monster.Name
1 hp := monster.Hp()
2 mana := monster.Mana()
3 name := string(monster.Name()) // Note: `monster.Name()` returns a byte[].
1 hp = monster.Hp()
2 mana = monster.Mana()
3 name = monster.Name()
var hp = $monster.hp();
var mana = $monster.mana();
var name = $monster.name();
$hp = $monster->getHp();
$mana = $monster->getMana();
$name = monster->getName();
uint16_t hp = ns(Monster_hp(monster));
uint16_t mana = ns(Monster_mana(monster));
flatbuffers_string_t name = ns(Monster_name(monster));

These should hold `300`, `150`, and `"Orc"` respectively.

Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.

To access sub-objects, in the case of our `pos`, which is a `Vec3`:

auto pos = monster->pos();
auto x = pos->x();
auto y = pos->y();
auto z = pos->z();
Vec3 pos = monster.pos();
float x = pos.x();
float y = pos.y();
float z = pos.z();
var pos = monster.Pos.Value;
var x = pos.X;
var y = pos.Y;
var z = pos.Z;
1 pos := monster.Pos(nil)
2 x := pos.X()
3 y := pos.Y()
4 z := pos.Z()
5
6 // Note: Whenever you access a new object, like in `Pos()`, a new temporary
7 // accessor object gets created. If your code is very performance sensitive,
8 // you can pass in a pointer to an existing `Vec3` instead of `nil`. This
9 // allows you to reuse it across many calls to reduce the amount of object
10 // allocation/garbage collection.
1 pos = monster.Pos()
2 x = pos.X()
3 y = pos.Y()
4 z = pos.Z()
var pos = monster.pos();
var x = pos.x();
var y = pos.y();
var z = pos.z();
$pos = $monster->getPos();
$x = $pos->getX();
$y = $pos->getY();
$z = $pos->getZ();
ns(Vec3_struct_t) pos = ns(Monster_pos(monster));
float x = ns(Vec3_x(pos));
float y = ns(Vec3_y(pos));
float z = ns(Vec3_z(pos));

`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.

Note: Had we not set `pos` during serialization, it would be a `NULL`-value.

Similarly, we can access elements of the inventory `vector` by indexing it. You can also iterate over the length of the array/vector representing the FlatBuffers `vector`.

auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
auto inv_len = inv->Length();
auto third_item = inv->Get(2);
int invLength = monster.inventoryLength();
byte thirdItem = monster.inventory(2);
int invLength = monster.InventoryLength;
var thirdItem = monster.Inventory(2);
1 invLength := monster.InventoryLength()
2 thirdItem := monster.Inventory(2)
1 inv_len = monster.InventoryLength()
2 third_item = monster.Inventory(2)
var invLength = monster.inventoryLength();
var thirdItem = monster.inventory(2);
$inv_len = $monster->getInventoryLength();
$third_item = $monster->getInventory(2);
// If `inv` hasn't been set, it will be null. It is valid get
// the length of null which will be 0, useful for iteration.
flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster));
size_t inv_len = flatbuffers_uint8_vec_len(inv);

For `vector`s of `table`s, you can access the elements like any other vector, except your need to handle the result as a FlatBuffer `table`:

auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
auto weapon_len = weapons->Length();
auto second_weapon_name = weapons->Get(1)->name()->str();
auto second_weapon_damage = weapons->Get(1)->damage()
int weaponsLength = monster.weaponsLength();
String secondWeaponName = monster.weapons(1).name();
short secondWeaponDamage = monster.weapons(1).damage();
int weaponsLength = monster.WeaponsLength;
var secondWeaponName = monster.Weapons(1).Name;
var secondWeaponDamage = monster.Weapons(1).Damage;
1 weaponLength := monster.WeaponsLength()
2 weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
3 // to capture the output of the function.
4 if monster.Weapons(weapon, 1) {
5 secondWeaponName := weapon.Name()
6 secondWeaponDamage := weapon.Damage()
7 }
1 weapons_length = monster.WeaponsLength()
2 second_weapon_name = monster.Weapons(1).Name()
3 second_weapon_damage = monster.Weapons(1).Damage()
var weaponsLength = monster.weaponsLength();
var secondWeaponName = monster.weapons(1).name();
var secondWeaponDamage = monster.weapons(1).damage();
$weapons_len = $monster->getWeaponsLength();
$second_weapon_name = $monster->getWeapons(1)->getName();
$second_weapon_damage = $monster->getWeapons(1)->getDamage();
ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster));
size_t weapons_len = ns(Weapon_vec_len(weapons));
// We can use `const char *` instead of `flatbuffers_string_t`.
const char *second_weapon_name = ns(Weapon_name(ns(Weapon_vec_at(weapons, 1))));
uint16_t second_weapon_damage = ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1))));

Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created the `union`, we need to get both parts of the `union`: the type and the data.

We can access the type to dynamically cast the data as needed (since the `union` only stores a FlatBuffer `table`).

auto union_type = monster.equipped_type();
if (union_type == Equipment_Weapon) {
auto weapon = static_cast<const Weapon*>(monster->equipped()); // Requires `static_cast`
// to type `const Weapon*`.
auto weapon_name = weapon->name()->str(); // "Axe"
auto weapon_damage = weapon->damage(); // 5
}
int unionType = monster.EquippedType();
if (unionType == Equipment.Weapon) {
Weapon weapon = (Weapon)monster.equipped(new Weapon()); // Requires explicit cast
// to `Weapon`.
String weaponName = weapon.name(); // "Axe"
short weaponDamage = weapon.damage(); // 5
}
var unionType = monster.EquippedType;
if (unionType == Equipment.Weapon) {
var weapon = monster.Equipped<Weapon>().Value;
var weaponName = weapon.Name; // "Axe"
var weaponDamage = weapon.Damage; // 5
}
1 // We need a `flatbuffers.Table` to capture the output of the
2 // `monster.Equipped()` function.
3 unionTable := new(flatbuffers.Table)
4
5 if monster.Equipped(unionTable) {
6 unionType := monster.EquippedType()
7
8 if unionType == sample.EquipmentWeapon {
9 // Create a `sample.Weapon` object that can be initialized with the contents
10 // of the `flatbuffers.Table` (`unionTable`), which was populated by
11 // `monster.Equipped()`.
12 unionWeapon = new(sample.Weapon)
13 unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
14
15 weaponName = unionWeapon.Name()
16 weaponDamage = unionWeapon.Damage()
17 }
18 }
1 union_type = monster.EquippedType()
2
3 if union_type == MyGame.Sample.Equipment.Equipment().Weapon:
4 # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used to
5 # initialize a `MyGame.Sample.Weapon.Weapon()`.
6 union_weapon = MyGame.Sample.Weapon.Weapon()
7 union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
8
9 weapon_name = union_weapon.Name() // 'Axe'
10 weapon_damage = union_weapon.Damage() // 5
var unionType = monster.equippedType();
if (unionType == MyGame.Sample.Equipment.Weapon) {
var weapon_name = monster.equipped(new MyGame.Sample.Weapon()).name(); // 'Axe'
var weapon_damage = monster.equipped(new MyGame.Sample.Weapon()).damage(); // 5
}
$union_type = $monster->getEquippedType();
if ($union_type == \MyGame\Sample\Equipment::Weapon) {
$weapon_name = $monster->getEquipped(new \MyGame\Sample\Weapon())->getName(); // "Axe"
$weapon_damage = $monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage(); // 5
}
// Access union type field.
if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) {
// Cast to appropriate type:
// C allows for silent void pointer assignment, so we need no explicit cast.
ns(Weapon_table_t) weapon = ns(Monster_equipped(monster));
const char *weapon_name = ns(Weapon_name(weapon)); // "Axe"
uint16_t weapon_damage = ns(Weapon_damage(weapon)); // 5
}

## Mutating FlatBuffers

As you saw above, typically once you have created a FlatBuffer, it is read-only from that moment on. There are, however, cases where you have just received a FlatBuffer, and you'd like to modify something about it before sending it on to another recipient. With the above functionality, you'd have to generate an entirely new FlatBuffer, while tracking what you modified in your own data structures. This is inconvenient.

For this reason FlatBuffers can also be mutated in-place. While this is great for making small fixes to an existing buffer, you generally want to create buffers from scratch whenever possible, since it is much more efficient and the API is much more general purpose.

To get non-const accessors, invoke `flatc` with `--gen-mutable`.

Similar to how we read fields using the accessors above, we can now use the mutators like so:

auto monster = GetMutableMonster(buffer_pointer); // non-const
monster->mutate_hp(10); // Set the table `hp` field.
monster->mutable_pos()->mutate_z(4); // Set struct field.
monster->mutable_inventory()->Mutate(0, 1); // Set vector element.
Monster monster = Monster.getRootAsMonster(buf);
monster.mutateHp(10); // Set table field.
monster.pos().mutateZ(4); // Set struct field.
monster.mutateInventory(0, 1); // Set vector element.
var monster = Monster.GetRootAsMonster(buf);
monster.MutateHp(10); // Set table field.
monster.Pos.MutateZ(4); // Set struct field.
monster.MutateInventory(0, 1); // Set vector element.
1 <API for mutating FlatBuffers is not yet available in Go.>
1 <API for mutating FlatBuffers is not yet available in Python.>
<API for mutating FlatBuffers is not yet support in JavaScript.>
<API for mutating FlatBuffers is not yet supported in PHP.>
<API for in-place mutating FlatBuffers will not be supported in C
(except in-place vector sorting is possible).>

We use the somewhat verbose term `mutate` instead of `set` to indicate that this is a special use case, not to be confused with the default way of constructing FlatBuffer data.

After the above mutations, you can send on the FlatBuffer to a new recipient without any further work!

Note that any `mutate` functions on a table will return a boolean, which is `false` if the field we're trying to set is not present in the buffer. Fields that are not present if they weren't set, or even if they happen to be equal to the default value. For example, in the creation code above, the `mana` field is equal to `150`, which is the default value, so it was never stored in the buffer. Trying to call the corresponding `mutate` method for `mana` on such data will return `false`, and the value won't actually be modified!

One way to solve this is to call `ForceDefaults` on a FlatBufferBuilder to force all fields you set to actually be written. This, of course, increases the size of the buffer somewhat, but this may be acceptable for a mutable buffer.

If this is not sufficient, other ways of mutating FlatBuffers may be supported in your language through an object based API (`--gen-object-api`) or reflection. See the individual language documents for support.

## JSON with FlatBuffers

#### Using `flatc` as a Conversion Tool

This is often the preferred method to use JSON with FlatBuffers, as it doesn't require you to add any new code to your program. It is also efficient, since you can ship with the binary data. The drawback is that it requires an extra step for your users/developers to perform (although it may be able to be automated as part of your compilation).

Lets say you have a JSON file that describes your monster. In this example, we will use the file `flatbuffers/samples/monsterdata.json`.

Here are the contents of the file:

1 {
2 pos: {
3 x: 1,
4 y: 2,
5 z: 3
6 },
7 hp: 300,
8 name: "Orc"
9 }

You can run this file through the `flatc` compile with the `-b` flag and our `monster.fbs` schema to produce a FlatBuffer binary file.

1 ./../flatc -b monster.fbs monsterdata.json

The output of this will be a file `monsterdata.bin`, which will contain the FlatBuffer binary representation of the contents from our `.json` file.

Note: If you're working in C++, you can also parse JSON at runtime. See the Use in C++ section of the Programmer's Guide for more information.
Note: If you're working in C, the `flatcc --json` (not `flatc`) compiler will generate schema specific high performance json parsers and printers that you can compile and use at runtime. The `flatc` compiler (not `flatcc`) on the other hand, is still useful for general offline json to flatbuffer conversion from a given schema. There are no current plans for `flatcc` to support this.

## Advanced Features for Each Language

Each language has a dedicated `Use in XXX` page in the Programmer's Guide to cover the nuances of FlatBuffers in that language.

For your chosen language, see:

Use in C++
Use in Java/C#
Use in Java/C#
Use in Go
Use in Python
Use in JavaScript
Use in PHP
Use in C