<?php
// automatically generated by the FlatBuffers compiler, do not modify

namespace MyGame\Example;

use \Google\FlatBuffers\Struct;
use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;

/// an example documentation comment: "monster object"
class Monster extends Table
{
    /**
     * @param ByteBuffer $bb
     * @return Monster
     */
    public static function getRootAsMonster(ByteBuffer $bb)
    {
        $obj = new Monster();
        return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
    }

    public static function MonsterIdentifier()
    {
        return "MONS";
    }

    public static function MonsterBufferHasIdentifier(ByteBuffer $buf)
    {
        return self::__has_identifier($buf, self::MonsterIdentifier());
    }

    public static function MonsterExtension()
    {
        return "mon";
    }

    /**
     * @param int $_i offset
     * @param ByteBuffer $_bb
     * @return Monster
     **/
    public function init($_i, ByteBuffer $_bb)
    {
        $this->bb_pos = $_i;
        $this->bb = $_bb;
        return $this;
    }

    public function getPos()
    {
        $obj = new Vec3();
        $o = $this->__offset(4);
        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
    }

    /**
     * @return short
     */
    public function getMana()
    {
        $o = $this->__offset(6);
        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 150;
    }

    /**
     * @return short
     */
    public function getHp()
    {
        $o = $this->__offset(8);
        return $o != 0 ? $this->bb->getShort($o + $this->bb_pos) : 100;
    }

    public function getName()
    {
        $o = $this->__offset(10);
        return $o != 0 ? $this->__string($o + $this->bb_pos) : null;
    }

    /**
     * @param int offset
     * @return byte
     */
    public function getInventory($j)
    {
        $o = $this->__offset(14);
        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getInventoryLength()
    {
        $o = $this->__offset(14);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return string
     */
    public function getInventoryBytes()
    {
        return $this->__vector_as_bytes(14);
    }

    /**
     * @return byte
     */
    public function getColor()
    {
        $o = $this->__offset(16);
        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Blue;
    }

    /**
     * @return byte
     */
    public function getTestType()
    {
        $o = $this->__offset(18);
        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Any::NONE;
    }

    /**
     * @returnint
     */
    public function getTest($obj)
    {
        $o = $this->__offset(20);
        return $o != 0 ? $this->__union($obj, $o) : null;
    }

    /**
     * @returnVectorOffset
     */
    public function getTest4($j)
    {
        $o = $this->__offset(22);
        $obj = new Test();
        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getTest4Length()
    {
        $o = $this->__offset(22);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @param int offset
     * @return string
     */
    public function getTestarrayofstring($j)
    {
        $o = $this->__offset(24);
        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
    }

    /**
     * @return int
     */
    public function getTestarrayofstringLength()
    {
        $o = $this->__offset(24);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /// an example documentation comment: this will end up in the generated code
    /// multiline too
    /**
     * @returnVectorOffset
     */
    public function getTestarrayoftables($j)
    {
        $o = $this->__offset(26);
        $obj = new Monster();
        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getTestarrayoftablesLength()
    {
        $o = $this->__offset(26);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    public function getEnemy()
    {
        $obj = new Monster();
        $o = $this->__offset(28);
        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
    }

    /**
     * @param int offset
     * @return byte
     */
    public function getTestnestedflatbuffer($j)
    {
        $o = $this->__offset(30);
        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getTestnestedflatbufferLength()
    {
        $o = $this->__offset(30);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return string
     */
    public function getTestnestedflatbufferBytes()
    {
        return $this->__vector_as_bytes(30);
    }

    public function getTestempty()
    {
        $obj = new Stat();
        $o = $this->__offset(32);
        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
    }

    /**
     * @return bool
     */
    public function getTestbool()
    {
        $o = $this->__offset(34);
        return $o != 0 ? $this->bb->getBool($o + $this->bb_pos) : false;
    }

    /**
     * @return int
     */
    public function getTesthashs32Fnv1()
    {
        $o = $this->__offset(36);
        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
    }

    /**
     * @return uint
     */
    public function getTesthashu32Fnv1()
    {
        $o = $this->__offset(38);
        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
    }

    /**
     * @return long
     */
    public function getTesthashs64Fnv1()
    {
        $o = $this->__offset(40);
        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
    }

    /**
     * @return ulong
     */
    public function getTesthashu64Fnv1()
    {
        $o = $this->__offset(42);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @return int
     */
    public function getTesthashs32Fnv1a()
    {
        $o = $this->__offset(44);
        return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
    }

    /**
     * @return uint
     */
    public function getTesthashu32Fnv1a()
    {
        $o = $this->__offset(46);
        return $o != 0 ? $this->bb->getUint($o + $this->bb_pos) : 0;
    }

    /**
     * @return long
     */
    public function getTesthashs64Fnv1a()
    {
        $o = $this->__offset(48);
        return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
    }

    /**
     * @return ulong
     */
    public function getTesthashu64Fnv1a()
    {
        $o = $this->__offset(50);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @param int offset
     * @return bool
     */
    public function getTestarrayofbools($j)
    {
        $o = $this->__offset(52);
        return $o != 0 ? $this->bb->getBool($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getTestarrayofboolsLength()
    {
        $o = $this->__offset(52);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return float
     */
    public function getTestf()
    {
        $o = $this->__offset(54);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.14159;
    }

    /**
     * @return float
     */
    public function getTestf2()
    {
        $o = $this->__offset(56);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 3.0;
    }

    /**
     * @return float
     */
    public function getTestf3()
    {
        $o = $this->__offset(58);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : 0.0;
    }

    /**
     * @param int offset
     * @return string
     */
    public function getTestarrayofstring2($j)
    {
        $o = $this->__offset(60);
        return $o != 0 ? $this->__string($this->__vector($o) + $j * 4) : 0;
    }

    /**
     * @return int
     */
    public function getTestarrayofstring2Length()
    {
        $o = $this->__offset(60);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @returnVectorOffset
     */
    public function getTestarrayofsortedstruct($j)
    {
        $o = $this->__offset(62);
        $obj = new Ability();
        return $o != 0 ? $obj->init($this->__vector($o) + $j *8, $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getTestarrayofsortedstructLength()
    {
        $o = $this->__offset(62);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @param int offset
     * @return byte
     */
    public function getFlex($j)
    {
        $o = $this->__offset(64);
        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getFlexLength()
    {
        $o = $this->__offset(64);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return string
     */
    public function getFlexBytes()
    {
        return $this->__vector_as_bytes(64);
    }

    /**
     * @returnVectorOffset
     */
    public function getTest5($j)
    {
        $o = $this->__offset(66);
        $obj = new Test();
        return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getTest5Length()
    {
        $o = $this->__offset(66);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @param int offset
     * @return long
     */
    public function getVectorOfLongs($j)
    {
        $o = $this->__offset(68);
        return $o != 0 ? $this->bb->getLong($this->__vector($o) + $j * 8) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfLongsLength()
    {
        $o = $this->__offset(68);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @param int offset
     * @return double
     */
    public function getVectorOfDoubles($j)
    {
        $o = $this->__offset(70);
        return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfDoublesLength()
    {
        $o = $this->__offset(70);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    public function getParentNamespaceTest()
    {
        $obj = new InParentNamespace();
        $o = $this->__offset(72);
        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
    }

    /**
     * @returnVectorOffset
     */
    public function getVectorOfReferrables($j)
    {
        $o = $this->__offset(74);
        $obj = new Referrable();
        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getVectorOfReferrablesLength()
    {
        $o = $this->__offset(74);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return ulong
     */
    public function getSingleWeakReference()
    {
        $o = $this->__offset(76);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @param int offset
     * @return ulong
     */
    public function getVectorOfWeakReferences($j)
    {
        $o = $this->__offset(78);
        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfWeakReferencesLength()
    {
        $o = $this->__offset(78);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @returnVectorOffset
     */
    public function getVectorOfStrongReferrables($j)
    {
        $o = $this->__offset(80);
        $obj = new Referrable();
        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getVectorOfStrongReferrablesLength()
    {
        $o = $this->__offset(80);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return ulong
     */
    public function getCoOwningReference()
    {
        $o = $this->__offset(82);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @param int offset
     * @return ulong
     */
    public function getVectorOfCoOwningReferences($j)
    {
        $o = $this->__offset(84);
        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfCoOwningReferencesLength()
    {
        $o = $this->__offset(84);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return ulong
     */
    public function getNonOwningReference()
    {
        $o = $this->__offset(86);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @param int offset
     * @return ulong
     */
    public function getVectorOfNonOwningReferences($j)
    {
        $o = $this->__offset(88);
        return $o != 0 ? $this->bb->getUlong($this->__vector($o) + $j * 8) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfNonOwningReferencesLength()
    {
        $o = $this->__offset(88);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return byte
     */
    public function getAnyUniqueType()
    {
        $o = $this->__offset(90);
        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyUniqueAliases::NONE;
    }

    /**
     * @returnint
     */
    public function getAnyUnique($obj)
    {
        $o = $this->__offset(92);
        return $o != 0 ? $this->__union($obj, $o) : null;
    }

    /**
     * @return byte
     */
    public function getAnyAmbiguousType()
    {
        $o = $this->__offset(94);
        return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\AnyAmbiguousAliases::NONE;
    }

    /**
     * @returnint
     */
    public function getAnyAmbiguous($obj)
    {
        $o = $this->__offset(96);
        return $o != 0 ? $this->__union($obj, $o) : null;
    }

    /**
     * @param int offset
     * @return byte
     */
    public function getVectorOfEnums($j)
    {
        $o = $this->__offset(98);
        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getVectorOfEnumsLength()
    {
        $o = $this->__offset(98);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return string
     */
    public function getVectorOfEnumsBytes()
    {
        return $this->__vector_as_bytes(98);
    }

    /**
     * @return sbyte
     */
    public function getSignedEnum()
    {
        $o = $this->__offset(100);
        return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \MyGame\Example\Race::None;
    }

    /**
     * @param int offset
     * @return byte
     */
    public function getTestrequirednestedflatbuffer($j)
    {
        $o = $this->__offset(102);
        return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
    }

    /**
     * @return int
     */
    public function getTestrequirednestedflatbufferLength()
    {
        $o = $this->__offset(102);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    /**
     * @return string
     */
    public function getTestrequirednestedflatbufferBytes()
    {
        return $this->__vector_as_bytes(102);
    }

    /**
     * @returnVectorOffset
     */
    public function getScalarKeySortedTables($j)
    {
        $o = $this->__offset(104);
        $obj = new Stat();
        return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
    }

    /**
     * @return int
     */
    public function getScalarKeySortedTablesLength()
    {
        $o = $this->__offset(104);
        return $o != 0 ? $this->__vector_len($o) : 0;
    }

    public function getNativeInline()
    {
        $obj = new Test();
        $o = $this->__offset(106);
        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
    }

    /**
     * @return ulong
     */
    public function getLongEnumNonEnumDefault()
    {
        $o = $this->__offset(108);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : 0;
    }

    /**
     * @return ulong
     */
    public function getLongEnumNormalDefault()
    {
        $o = $this->__offset(110);
        return $o != 0 ? $this->bb->getUlong($o + $this->bb_pos) : \MyGame\Example\LongEnum::LongOne;
    }

    /**
     * @return float
     */
    public function getNanDefault()
    {
        $o = $this->__offset(112);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : nan;
    }

    /**
     * @return float
     */
    public function getInfDefault()
    {
        $o = $this->__offset(114);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : inf;
    }

    /**
     * @return float
     */
    public function getPositiveInfDefault()
    {
        $o = $this->__offset(116);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : +inf;
    }

    /**
     * @return float
     */
    public function getInfinityDefault()
    {
        $o = $this->__offset(118);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : infinity;
    }

    /**
     * @return float
     */
    public function getPositiveInfinityDefault()
    {
        $o = $this->__offset(120);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : +infinity;
    }

    /**
     * @return float
     */
    public function getNegativeInfDefault()
    {
        $o = $this->__offset(122);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : -inf;
    }

    /**
     * @return float
     */
    public function getNegativeInfinityDefault()
    {
        $o = $this->__offset(124);
        return $o != 0 ? $this->bb->getFloat($o + $this->bb_pos) : -infinity;
    }

    /**
     * @return double
     */
    public function getDoubleInfDefault()
    {
        $o = $this->__offset(126);
        return $o != 0 ? $this->bb->getDouble($o + $this->bb_pos) : inf;
    }

    /**
     * @param FlatBufferBuilder $builder
     * @return void
     */
    public static function startMonster(FlatBufferBuilder $builder)
    {
        $builder->StartObject(62);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @return Monster
     */
    public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums, $signed_enum, $testrequirednestedflatbuffer, $scalar_key_sorted_tables, $native_inline, $long_enum_non_enum_default, $long_enum_normal_default, $nan_default, $inf_default, $positive_inf_default, $infinity_default, $positive_infinity_default, $negative_inf_default, $negative_infinity_default, $double_inf_default)
    {
        $builder->startObject(62);
        self::addPos($builder, $pos);
        self::addMana($builder, $mana);
        self::addHp($builder, $hp);
        self::addName($builder, $name);
        self::addInventory($builder, $inventory);
        self::addColor($builder, $color);
        self::addTestType($builder, $test_type);
        self::addTest($builder, $test);
        self::addTest4($builder, $test4);
        self::addTestarrayofstring($builder, $testarrayofstring);
        self::addTestarrayoftables($builder, $testarrayoftables);
        self::addEnemy($builder, $enemy);
        self::addTestnestedflatbuffer($builder, $testnestedflatbuffer);
        self::addTestempty($builder, $testempty);
        self::addTestbool($builder, $testbool);
        self::addTesthashs32Fnv1($builder, $testhashs32_fnv1);
        self::addTesthashu32Fnv1($builder, $testhashu32_fnv1);
        self::addTesthashs64Fnv1($builder, $testhashs64_fnv1);
        self::addTesthashu64Fnv1($builder, $testhashu64_fnv1);
        self::addTesthashs32Fnv1a($builder, $testhashs32_fnv1a);
        self::addTesthashu32Fnv1a($builder, $testhashu32_fnv1a);
        self::addTesthashs64Fnv1a($builder, $testhashs64_fnv1a);
        self::addTesthashu64Fnv1a($builder, $testhashu64_fnv1a);
        self::addTestarrayofbools($builder, $testarrayofbools);
        self::addTestf($builder, $testf);
        self::addTestf2($builder, $testf2);
        self::addTestf3($builder, $testf3);
        self::addTestarrayofstring2($builder, $testarrayofstring2);
        self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
        self::addFlex($builder, $flex);
        self::addTest5($builder, $test5);
        self::addVectorOfLongs($builder, $vector_of_longs);
        self::addVectorOfDoubles($builder, $vector_of_doubles);
        self::addParentNamespaceTest($builder, $parent_namespace_test);
        self::addVectorOfReferrables($builder, $vector_of_referrables);
        self::addSingleWeakReference($builder, $single_weak_reference);
        self::addVectorOfWeakReferences($builder, $vector_of_weak_references);
        self::addVectorOfStrongReferrables($builder, $vector_of_strong_referrables);
        self::addCoOwningReference($builder, $co_owning_reference);
        self::addVectorOfCoOwningReferences($builder, $vector_of_co_owning_references);
        self::addNonOwningReference($builder, $non_owning_reference);
        self::addVectorOfNonOwningReferences($builder, $vector_of_non_owning_references);
        self::addAnyUniqueType($builder, $any_unique_type);
        self::addAnyUnique($builder, $any_unique);
        self::addAnyAmbiguousType($builder, $any_ambiguous_type);
        self::addAnyAmbiguous($builder, $any_ambiguous);
        self::addVectorOfEnums($builder, $vector_of_enums);
        self::addSignedEnum($builder, $signed_enum);
        self::addTestrequirednestedflatbuffer($builder, $testrequirednestedflatbuffer);
        self::addScalarKeySortedTables($builder, $scalar_key_sorted_tables);
        self::addNativeInline($builder, $native_inline);
        self::addLongEnumNonEnumDefault($builder, $long_enum_non_enum_default);
        self::addLongEnumNormalDefault($builder, $long_enum_normal_default);
        self::addNanDefault($builder, $nan_default);
        self::addInfDefault($builder, $inf_default);
        self::addPositiveInfDefault($builder, $positive_inf_default);
        self::addInfinityDefault($builder, $infinity_default);
        self::addPositiveInfinityDefault($builder, $positive_infinity_default);
        self::addNegativeInfDefault($builder, $negative_inf_default);
        self::addNegativeInfinityDefault($builder, $negative_infinity_default);
        self::addDoubleInfDefault($builder, $double_inf_default);
        $o = $builder->endObject();
        $builder->required($o, 10);  // name
        return $o;
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addPos(FlatBufferBuilder $builder, $pos)
    {
        $builder->addStructX(0, $pos, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param short
     * @return void
     */
    public static function addMana(FlatBufferBuilder $builder, $mana)
    {
        $builder->addShortX(1, $mana, 150);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param short
     * @return void
     */
    public static function addHp(FlatBufferBuilder $builder, $hp)
    {
        $builder->addShortX(2, $hp, 100);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param StringOffset
     * @return void
     */
    public static function addName(FlatBufferBuilder $builder, $name)
    {
        $builder->addOffsetX(3, $name, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addInventory(FlatBufferBuilder $builder, $inventory)
    {
        $builder->addOffsetX(5, $inventory, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createInventoryVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putByte($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startInventoryVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param byte
     * @return void
     */
    public static function addColor(FlatBufferBuilder $builder, $color)
    {
        $builder->addByteX(6, $color, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param byte
     * @return void
     */
    public static function addTestType(FlatBufferBuilder $builder, $testType)
    {
        $builder->addByteX(7, $testType, 0);
    }

    public static function addTest(FlatBufferBuilder $builder, $offset)
    {
        $builder->addOffsetX(8, $offset, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTest4(FlatBufferBuilder $builder, $test4)
    {
        $builder->addOffsetX(9, $test4, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTest4Vector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 2);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTest4Vector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 2);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestarrayofstring(FlatBufferBuilder $builder, $testarrayofstring)
    {
        $builder->addOffsetX(10, $testarrayofstring, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestarrayofstringVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestarrayofstringVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestarrayoftables(FlatBufferBuilder $builder, $testarrayoftables)
    {
        $builder->addOffsetX(11, $testarrayoftables, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestarrayoftablesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestarrayoftablesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addEnemy(FlatBufferBuilder $builder, $enemy)
    {
        $builder->addOffsetX(12, $enemy, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestnestedflatbuffer(FlatBufferBuilder $builder, $testnestedflatbuffer)
    {
        $builder->addOffsetX(13, $testnestedflatbuffer, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestnestedflatbufferVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putByte($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestnestedflatbufferVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestempty(FlatBufferBuilder $builder, $testempty)
    {
        $builder->addOffsetX(14, $testempty, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param bool
     * @return void
     */
    public static function addTestbool(FlatBufferBuilder $builder, $testbool)
    {
        $builder->addBoolX(15, $testbool, false);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int
     * @return void
     */
    public static function addTesthashs32Fnv1(FlatBufferBuilder $builder, $testhashs32Fnv1)
    {
        $builder->addIntX(16, $testhashs32Fnv1, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param uint
     * @return void
     */
    public static function addTesthashu32Fnv1(FlatBufferBuilder $builder, $testhashu32Fnv1)
    {
        $builder->addUintX(17, $testhashu32Fnv1, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param long
     * @return void
     */
    public static function addTesthashs64Fnv1(FlatBufferBuilder $builder, $testhashs64Fnv1)
    {
        $builder->addLongX(18, $testhashs64Fnv1, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addTesthashu64Fnv1(FlatBufferBuilder $builder, $testhashu64Fnv1)
    {
        $builder->addUlongX(19, $testhashu64Fnv1, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int
     * @return void
     */
    public static function addTesthashs32Fnv1a(FlatBufferBuilder $builder, $testhashs32Fnv1a)
    {
        $builder->addIntX(20, $testhashs32Fnv1a, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param uint
     * @return void
     */
    public static function addTesthashu32Fnv1a(FlatBufferBuilder $builder, $testhashu32Fnv1a)
    {
        $builder->addUintX(21, $testhashu32Fnv1a, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param long
     * @return void
     */
    public static function addTesthashs64Fnv1a(FlatBufferBuilder $builder, $testhashs64Fnv1a)
    {
        $builder->addLongX(22, $testhashs64Fnv1a, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addTesthashu64Fnv1a(FlatBufferBuilder $builder, $testhashu64Fnv1a)
    {
        $builder->addUlongX(23, $testhashu64Fnv1a, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestarrayofbools(FlatBufferBuilder $builder, $testarrayofbools)
    {
        $builder->addOffsetX(24, $testarrayofbools, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestarrayofboolsVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putBool($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestarrayofboolsVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addTestf(FlatBufferBuilder $builder, $testf)
    {
        $builder->addFloatX(25, $testf, 3.14159);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addTestf2(FlatBufferBuilder $builder, $testf2)
    {
        $builder->addFloatX(26, $testf2, 3.0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addTestf3(FlatBufferBuilder $builder, $testf3)
    {
        $builder->addFloatX(27, $testf3, 0.0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestarrayofstring2(FlatBufferBuilder $builder, $testarrayofstring2)
    {
        $builder->addOffsetX(28, $testarrayofstring2, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestarrayofstring2Vector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestarrayofstring2Vector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestarrayofsortedstruct(FlatBufferBuilder $builder, $testarrayofsortedstruct)
    {
        $builder->addOffsetX(29, $testarrayofsortedstruct, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestarrayofsortedstructVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestarrayofsortedstructVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addFlex(FlatBufferBuilder $builder, $flex)
    {
        $builder->addOffsetX(30, $flex, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createFlexVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putByte($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startFlexVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTest5(FlatBufferBuilder $builder, $test5)
    {
        $builder->addOffsetX(31, $test5, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTest5Vector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 2);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTest5Vector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 2);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfLongs(FlatBufferBuilder $builder, $vectorOfLongs)
    {
        $builder->addOffsetX(32, $vectorOfLongs, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfLongsVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 8);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putLong($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfLongsVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfDoubles(FlatBufferBuilder $builder, $vectorOfDoubles)
    {
        $builder->addOffsetX(33, $vectorOfDoubles, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfDoublesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 8);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putDouble($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfDoublesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addParentNamespaceTest(FlatBufferBuilder $builder, $parentNamespaceTest)
    {
        $builder->addOffsetX(34, $parentNamespaceTest, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfReferrables(FlatBufferBuilder $builder, $vectorOfReferrables)
    {
        $builder->addOffsetX(35, $vectorOfReferrables, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfReferrablesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfReferrablesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addSingleWeakReference(FlatBufferBuilder $builder, $singleWeakReference)
    {
        $builder->addUlongX(36, $singleWeakReference, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfWeakReferences(FlatBufferBuilder $builder, $vectorOfWeakReferences)
    {
        $builder->addOffsetX(37, $vectorOfWeakReferences, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfWeakReferencesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 8);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putUlong($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfWeakReferencesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfStrongReferrables(FlatBufferBuilder $builder, $vectorOfStrongReferrables)
    {
        $builder->addOffsetX(38, $vectorOfStrongReferrables, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfStrongReferrablesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addCoOwningReference(FlatBufferBuilder $builder, $coOwningReference)
    {
        $builder->addUlongX(39, $coOwningReference, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfCoOwningReferences(FlatBufferBuilder $builder, $vectorOfCoOwningReferences)
    {
        $builder->addOffsetX(40, $vectorOfCoOwningReferences, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 8);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putUlong($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfCoOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addNonOwningReference(FlatBufferBuilder $builder, $nonOwningReference)
    {
        $builder->addUlongX(41, $nonOwningReference, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfNonOwningReferences(FlatBufferBuilder $builder, $vectorOfNonOwningReferences)
    {
        $builder->addOffsetX(42, $vectorOfNonOwningReferences, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(8, count($data), 8);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putUlong($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfNonOwningReferencesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(8, $numElems, 8);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param byte
     * @return void
     */
    public static function addAnyUniqueType(FlatBufferBuilder $builder, $anyUniqueType)
    {
        $builder->addByteX(43, $anyUniqueType, 0);
    }

    public static function addAnyUnique(FlatBufferBuilder $builder, $offset)
    {
        $builder->addOffsetX(44, $offset, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param byte
     * @return void
     */
    public static function addAnyAmbiguousType(FlatBufferBuilder $builder, $anyAmbiguousType)
    {
        $builder->addByteX(45, $anyAmbiguousType, 0);
    }

    public static function addAnyAmbiguous(FlatBufferBuilder $builder, $offset)
    {
        $builder->addOffsetX(46, $offset, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addVectorOfEnums(FlatBufferBuilder $builder, $vectorOfEnums)
    {
        $builder->addOffsetX(47, $vectorOfEnums, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createVectorOfEnumsVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putByte($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startVectorOfEnumsVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param sbyte
     * @return void
     */
    public static function addSignedEnum(FlatBufferBuilder $builder, $signedEnum)
    {
        $builder->addSbyteX(48, $signedEnum, -1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addTestrequirednestedflatbuffer(FlatBufferBuilder $builder, $testrequirednestedflatbuffer)
    {
        $builder->addOffsetX(49, $testrequirednestedflatbuffer, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createTestrequirednestedflatbufferVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(1, count($data), 1);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putByte($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startTestrequirednestedflatbufferVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(1, $numElems, 1);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addScalarKeySortedTables(FlatBufferBuilder $builder, $scalarKeySortedTables)
    {
        $builder->addOffsetX(50, $scalarKeySortedTables, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param array offset array
     * @return int vector offset
     */
    public static function createScalarKeySortedTablesVector(FlatBufferBuilder $builder, array $data)
    {
        $builder->startVector(4, count($data), 4);
        for ($i = count($data) - 1; $i >= 0; $i--) {
            $builder->putOffset($data[$i]);
        }
        return $builder->endVector();
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param int $numElems
     * @return void
     */
    public static function startScalarKeySortedTablesVector(FlatBufferBuilder $builder, $numElems)
    {
        $builder->startVector(4, $numElems, 4);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param VectorOffset
     * @return void
     */
    public static function addNativeInline(FlatBufferBuilder $builder, $nativeInline)
    {
        $builder->addStructX(51, $nativeInline, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addLongEnumNonEnumDefault(FlatBufferBuilder $builder, $longEnumNonEnumDefault)
    {
        $builder->addUlongX(52, $longEnumNonEnumDefault, 0);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param ulong
     * @return void
     */
    public static function addLongEnumNormalDefault(FlatBufferBuilder $builder, $longEnumNormalDefault)
    {
        $builder->addUlongX(53, $longEnumNormalDefault, 2);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addNanDefault(FlatBufferBuilder $builder, $nanDefault)
    {
        $builder->addFloatX(54, $nanDefault, nan);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addInfDefault(FlatBufferBuilder $builder, $infDefault)
    {
        $builder->addFloatX(55, $infDefault, inf);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addPositiveInfDefault(FlatBufferBuilder $builder, $positiveInfDefault)
    {
        $builder->addFloatX(56, $positiveInfDefault, +inf);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addInfinityDefault(FlatBufferBuilder $builder, $infinityDefault)
    {
        $builder->addFloatX(57, $infinityDefault, infinity);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addPositiveInfinityDefault(FlatBufferBuilder $builder, $positiveInfinityDefault)
    {
        $builder->addFloatX(58, $positiveInfinityDefault, +infinity);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addNegativeInfDefault(FlatBufferBuilder $builder, $negativeInfDefault)
    {
        $builder->addFloatX(59, $negativeInfDefault, -inf);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param float
     * @return void
     */
    public static function addNegativeInfinityDefault(FlatBufferBuilder $builder, $negativeInfinityDefault)
    {
        $builder->addFloatX(60, $negativeInfinityDefault, -infinity);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @param double
     * @return void
     */
    public static function addDoubleInfDefault(FlatBufferBuilder $builder, $doubleInfDefault)
    {
        $builder->addDoubleX(61, $doubleInfDefault, inf);
    }

    /**
     * @param FlatBufferBuilder $builder
     * @return int table offset
     */
    public static function endMonster(FlatBufferBuilder $builder)
    {
        $o = $builder->endObject();
        $builder->required($o, 10);  // name
        return $o;
    }

    public static function finishMonsterBuffer(FlatBufferBuilder $builder, $offset)
    {
        $builder->finish($offset, "MONS");
    }
}
