# automatically generated by the FlatBuffers compiler, do not modify

# namespace: Example

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

# an example documentation comment: "monster object"
class Monster(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Monster()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsMonster(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Monster
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Monster
    def Pos(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            x = o + self._tab.Pos
            from MyGame.Example.Vec3 import Vec3
            obj = Vec3()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Mana(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 150

    # Monster
    def Hp(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 100

    # Monster
    def Name(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.String(o + self._tab.Pos)
        return None

    # Monster
    def Inventory(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def InventoryAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def InventoryLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def InventoryIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        return o == 0

    # Monster
    def Color(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 8

    # Monster
    def TestType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Test(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def Test4(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test4Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test4IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        return o == 0

    # Monster
    def Testarrayofstring(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def TestarrayofstringLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofstringIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        return o == 0

    # an example documentation comment: this will end up in the generated code
    # multiline too
    # Monster
    def Testarrayoftables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Monster import Monster
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayoftablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayoftablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        return o == 0

    # Monster
    def Enemy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.Example.Monster import Monster
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testnestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestnestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestnestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestnestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestnestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        return o == 0

    # Monster
    def Testempty(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.Example.Stat import Stat
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testbool(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
        if o != 0:
            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
        return False

    # Monster
    def Testhashs32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(40))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(44))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(48))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(50))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testarrayofbools(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.BoolFlags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestarrayofboolsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.BoolFlags, o)
        return 0

    # Monster
    def TestarrayofboolsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofboolsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        return o == 0

    # Monster
    def Testf(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.14159

    # Monster
    def Testf2(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(56))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.0

    # Monster
    def Testf3(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(58))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 0.0

    # Monster
    def Testarrayofstring2(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def Testarrayofstring2Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Testarrayofstring2IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        return o == 0

    # Monster
    def Testarrayofsortedstruct(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
            from MyGame.Example.Ability import Ability
            obj = Ability()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayofsortedstructLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofsortedstructIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        return o == 0

    # Monster
    def Flex(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def FlexAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def FlexLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def FlexIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        return o == 0

    # Monster
    def Test5(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test5Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test5IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        return o == 0

    # Monster
    def VectorOfLongs(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfLongsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int64Flags, o)
        return 0

    # Monster
    def VectorOfLongsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfLongsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        return o == 0

    # Monster
    def VectorOfDoubles(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfDoublesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
        return 0

    # Monster
    def VectorOfDoublesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfDoublesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        return o == 0

    # Monster
    def ParentNamespaceTest(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.InParentNamespace import InParentNamespace
            obj = InParentNamespace()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Referrable import Referrable
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        return o == 0

    # Monster
    def SingleWeakReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfWeakReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfWeakReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfWeakReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfWeakReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        return o == 0

    # Monster
    def VectorOfStrongReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Referrable import Referrable
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfStrongReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfStrongReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        return o == 0

    # Monster
    def CoOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfCoOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfCoOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        return o == 0

    # Monster
    def NonOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfNonOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfNonOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        return o == 0

    # Monster
    def AnyUniqueType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyUnique(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(92))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def AnyAmbiguousType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(94))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyAmbiguous(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(96))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def VectorOfEnums(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def VectorOfEnumsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def VectorOfEnumsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfEnumsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        return o == 0

    # Monster
    def SignedEnum(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(100))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
        return -1

    # Monster
    def Testrequirednestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestrequirednestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestrequirednestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestrequirednestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestrequirednestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        return o == 0

    # Monster
    def ScalarKeySortedTables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Stat import Stat
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def ScalarKeySortedTablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def ScalarKeySortedTablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        return o == 0

    # Monster
    def NativeInline(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(106))
        if o != 0:
            x = o + self._tab.Pos
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def LongEnumNonEnumDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(108))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def LongEnumNormalDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(110))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 2

    # Monster
    def NanDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(112))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('nan')

    # Monster
    def InfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(114))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(116))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def InfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(118))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(120))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def NegativeInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(122))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def NegativeInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(124))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def DoubleInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(126))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('inf')

def MonsterStart(builder):
    builder.StartObject(62)

def Start(builder):
    MonsterStart(builder)

def MonsterAddPos(builder, pos):
    builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)

def AddPos(builder, pos):
    MonsterAddPos(builder, pos)

def MonsterAddMana(builder, mana):
    builder.PrependInt16Slot(1, mana, 150)

def AddMana(builder, mana):
    MonsterAddMana(builder, mana)

def MonsterAddHp(builder, hp):
    builder.PrependInt16Slot(2, hp, 100)

def AddHp(builder, hp):
    MonsterAddHp(builder, hp)

def MonsterAddName(builder, name):
    builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)

def AddName(builder, name):
    MonsterAddName(builder, name)

def MonsterAddInventory(builder, inventory):
    builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)

def AddInventory(builder, inventory):
    MonsterAddInventory(builder, inventory)

def MonsterStartInventoryVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartInventoryVector(builder, numElems):
    return MonsterStartInventoryVector(builder, numElems)

def MonsterCreateInventoryVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def CreateInventoryVector(builder, data):
    MonsterCreateInventoryVector(builder, data)

def MonsterAddColor(builder, color):
    builder.PrependUint8Slot(6, color, 8)

def AddColor(builder, color):
    MonsterAddColor(builder, color)

def MonsterAddTestType(builder, testType):
    builder.PrependUint8Slot(7, testType, 0)

def AddTestType(builder, testType):
    MonsterAddTestType(builder, testType)

def MonsterAddTest(builder, test):
    builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)

def AddTest(builder, test):
    MonsterAddTest(builder, test)

def MonsterAddTest4(builder, test4):
    builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)

def AddTest4(builder, test4):
    MonsterAddTest4(builder, test4)

def MonsterStartTest4Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def StartTest4Vector(builder, numElems):
    return MonsterStartTest4Vector(builder, numElems)

def MonsterCreateTest4Vector(builder, data):
    data = list(data)
    builder.StartVector(4, len(data), 2)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def CreateTest4Vector(builder, data):
    MonsterCreateTest4Vector(builder, data)

def MonsterAddTestarrayofstring(builder, testarrayofstring):
    builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring), 0)

def AddTestarrayofstring(builder, testarrayofstring):
    MonsterAddTestarrayofstring(builder, testarrayofstring)

def MonsterStartTestarrayofstringVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayofstringVector(builder, numElems):
    return MonsterStartTestarrayofstringVector(builder, numElems)

def MonsterCreateTestarrayofstringVector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateTestarrayofstringVector(builder, data):
    MonsterCreateTestarrayofstringVector(builder, data)

def MonsterAddTestarrayoftables(builder, testarrayoftables):
    builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayoftables), 0)

def AddTestarrayoftables(builder, testarrayoftables):
    MonsterAddTestarrayoftables(builder, testarrayoftables)

def MonsterStartTestarrayoftablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayoftablesVector(builder, numElems):
    return MonsterStartTestarrayoftablesVector(builder, numElems)

def MonsterCreateTestarrayoftablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateTestarrayoftablesVector(builder, data):
    MonsterCreateTestarrayoftablesVector(builder, data)

def MonsterAddEnemy(builder, enemy):
    builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)

def AddEnemy(builder, enemy):
    MonsterAddEnemy(builder, enemy)

def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)

def AddTestnestedflatbuffer(builder, testnestedflatbuffer):
    MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)

def MonsterStartTestnestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestnestedflatbufferVector(builder, numElems):
    return MonsterStartTestnestedflatbufferVector(builder, numElems)

def MonsterCreateTestnestedflatbufferVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def CreateTestnestedflatbufferVector(builder, data):
    MonsterCreateTestnestedflatbufferVector(builder, data)

def MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MakeTestnestedflatbufferVectorFromBytes(builder, bytes):
    return MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes)
def MonsterAddTestempty(builder, testempty):
    builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)

def AddTestempty(builder, testempty):
    MonsterAddTestempty(builder, testempty)

def MonsterAddTestbool(builder, testbool):
    builder.PrependBoolSlot(15, testbool, 0)

def AddTestbool(builder, testbool):
    MonsterAddTestbool(builder, testbool)

def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1):
    builder.PrependInt32Slot(16, testhashs32Fnv1, 0)

def AddTesthashs32Fnv1(builder, testhashs32Fnv1):
    MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1)

def MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1):
    builder.PrependUint32Slot(17, testhashu32Fnv1, 0)

def AddTesthashu32Fnv1(builder, testhashu32Fnv1):
    MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1)

def MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1):
    builder.PrependInt64Slot(18, testhashs64Fnv1, 0)

def AddTesthashs64Fnv1(builder, testhashs64Fnv1):
    MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1)

def MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1):
    builder.PrependUint64Slot(19, testhashu64Fnv1, 0)

def AddTesthashu64Fnv1(builder, testhashu64Fnv1):
    MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1)

def MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a):
    builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)

def AddTesthashs32Fnv1a(builder, testhashs32Fnv1a):
    MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a)

def MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a):
    builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)

def AddTesthashu32Fnv1a(builder, testhashu32Fnv1a):
    MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a)

def MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a):
    builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)

def AddTesthashs64Fnv1a(builder, testhashs64Fnv1a):
    MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a)

def MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a):
    builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)

def AddTesthashu64Fnv1a(builder, testhashu64Fnv1a):
    MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a)

def MonsterAddTestarrayofbools(builder, testarrayofbools):
    builder.PrependUOffsetTRelativeSlot(24, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofbools), 0)

def AddTestarrayofbools(builder, testarrayofbools):
    MonsterAddTestarrayofbools(builder, testarrayofbools)

def MonsterStartTestarrayofboolsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestarrayofboolsVector(builder, numElems):
    return MonsterStartTestarrayofboolsVector(builder, numElems)

def MonsterCreateTestarrayofboolsVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependBool(item)
    return builder.EndVector()

def CreateTestarrayofboolsVector(builder, data):
    MonsterCreateTestarrayofboolsVector(builder, data)

def MonsterAddTestf(builder, testf):
    builder.PrependFloat32Slot(25, testf, 3.14159)

def AddTestf(builder, testf):
    MonsterAddTestf(builder, testf)

def MonsterAddTestf2(builder, testf2):
    builder.PrependFloat32Slot(26, testf2, 3.0)

def AddTestf2(builder, testf2):
    MonsterAddTestf2(builder, testf2)

def MonsterAddTestf3(builder, testf3):
    builder.PrependFloat32Slot(27, testf3, 0.0)

def AddTestf3(builder, testf3):
    MonsterAddTestf3(builder, testf3)

def MonsterAddTestarrayofstring2(builder, testarrayofstring2):
    builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0)

def AddTestarrayofstring2(builder, testarrayofstring2):
    MonsterAddTestarrayofstring2(builder, testarrayofstring2)

def MonsterStartTestarrayofstring2Vector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayofstring2Vector(builder, numElems):
    return MonsterStartTestarrayofstring2Vector(builder, numElems)

def MonsterCreateTestarrayofstring2Vector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateTestarrayofstring2Vector(builder, data):
    MonsterCreateTestarrayofstring2Vector(builder, data)

def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct):
    builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)

def AddTestarrayofsortedstruct(builder, testarrayofsortedstruct):
    MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)

def MonsterStartTestarrayofsortedstructVector(builder, numElems):
    return builder.StartVector(8, numElems, 4)

def StartTestarrayofsortedstructVector(builder, numElems):
    return MonsterStartTestarrayofsortedstructVector(builder, numElems)

def MonsterCreateTestarrayofsortedstructVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 4)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def CreateTestarrayofsortedstructVector(builder, data):
    MonsterCreateTestarrayofsortedstructVector(builder, data)

def MonsterAddFlex(builder, flex):
    builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)

def AddFlex(builder, flex):
    MonsterAddFlex(builder, flex)

def MonsterStartFlexVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartFlexVector(builder, numElems):
    return MonsterStartFlexVector(builder, numElems)

def MonsterCreateFlexVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def CreateFlexVector(builder, data):
    MonsterCreateFlexVector(builder, data)

def MonsterAddTest5(builder, test5):
    builder.PrependUOffsetTRelativeSlot(31, flatbuffers.number_types.UOffsetTFlags.py_type(test5), 0)

def AddTest5(builder, test5):
    MonsterAddTest5(builder, test5)

def MonsterStartTest5Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def StartTest5Vector(builder, numElems):
    return MonsterStartTest5Vector(builder, numElems)

def MonsterCreateTest5Vector(builder, data):
    data = list(data)
    builder.StartVector(4, len(data), 2)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def CreateTest5Vector(builder, data):
    MonsterCreateTest5Vector(builder, data)

def MonsterAddVectorOfLongs(builder, vectorOfLongs):
    builder.PrependUOffsetTRelativeSlot(32, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfLongs), 0)

def AddVectorOfLongs(builder, vectorOfLongs):
    MonsterAddVectorOfLongs(builder, vectorOfLongs)

def MonsterStartVectorOfLongsVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfLongsVector(builder, numElems):
    return MonsterStartVectorOfLongsVector(builder, numElems)

def MonsterCreateVectorOfLongsVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependInt64(item)
    return builder.EndVector()

def CreateVectorOfLongsVector(builder, data):
    MonsterCreateVectorOfLongsVector(builder, data)

def MonsterAddVectorOfDoubles(builder, vectorOfDoubles):
    builder.PrependUOffsetTRelativeSlot(33, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfDoubles), 0)

def AddVectorOfDoubles(builder, vectorOfDoubles):
    MonsterAddVectorOfDoubles(builder, vectorOfDoubles)

def MonsterStartVectorOfDoublesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfDoublesVector(builder, numElems):
    return MonsterStartVectorOfDoublesVector(builder, numElems)

def MonsterCreateVectorOfDoublesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependFloat64(item)
    return builder.EndVector()

def CreateVectorOfDoublesVector(builder, data):
    MonsterCreateVectorOfDoublesVector(builder, data)

def MonsterAddParentNamespaceTest(builder, parentNamespaceTest):
    builder.PrependUOffsetTRelativeSlot(34, flatbuffers.number_types.UOffsetTFlags.py_type(parentNamespaceTest), 0)

def AddParentNamespaceTest(builder, parentNamespaceTest):
    MonsterAddParentNamespaceTest(builder, parentNamespaceTest)

def MonsterAddVectorOfReferrables(builder, vectorOfReferrables):
    builder.PrependUOffsetTRelativeSlot(35, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfReferrables), 0)

def AddVectorOfReferrables(builder, vectorOfReferrables):
    MonsterAddVectorOfReferrables(builder, vectorOfReferrables)

def MonsterStartVectorOfReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartVectorOfReferrablesVector(builder, numElems):
    return MonsterStartVectorOfReferrablesVector(builder, numElems)

def MonsterCreateVectorOfReferrablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateVectorOfReferrablesVector(builder, data):
    MonsterCreateVectorOfReferrablesVector(builder, data)

def MonsterAddSingleWeakReference(builder, singleWeakReference):
    builder.PrependUint64Slot(36, singleWeakReference, 0)

def AddSingleWeakReference(builder, singleWeakReference):
    MonsterAddSingleWeakReference(builder, singleWeakReference)

def MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences):
    builder.PrependUOffsetTRelativeSlot(37, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfWeakReferences), 0)

def AddVectorOfWeakReferences(builder, vectorOfWeakReferences):
    MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)

def MonsterStartVectorOfWeakReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfWeakReferencesVector(builder, numElems):
    return MonsterStartVectorOfWeakReferencesVector(builder, numElems)

def MonsterCreateVectorOfWeakReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def CreateVectorOfWeakReferencesVector(builder, data):
    MonsterCreateVectorOfWeakReferencesVector(builder, data)

def MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables):
    builder.PrependUOffsetTRelativeSlot(38, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfStrongReferrables), 0)

def AddVectorOfStrongReferrables(builder, vectorOfStrongReferrables):
    MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)

def MonsterStartVectorOfStrongReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartVectorOfStrongReferrablesVector(builder, numElems):
    return MonsterStartVectorOfStrongReferrablesVector(builder, numElems)

def MonsterCreateVectorOfStrongReferrablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateVectorOfStrongReferrablesVector(builder, data):
    MonsterCreateVectorOfStrongReferrablesVector(builder, data)

def MonsterAddCoOwningReference(builder, coOwningReference):
    builder.PrependUint64Slot(39, coOwningReference, 0)

def AddCoOwningReference(builder, coOwningReference):
    MonsterAddCoOwningReference(builder, coOwningReference)

def MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences):
    builder.PrependUOffsetTRelativeSlot(40, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfCoOwningReferences), 0)

def AddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences):
    MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)

def MonsterStartVectorOfCoOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfCoOwningReferencesVector(builder, numElems):
    return MonsterStartVectorOfCoOwningReferencesVector(builder, numElems)

def MonsterCreateVectorOfCoOwningReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def CreateVectorOfCoOwningReferencesVector(builder, data):
    MonsterCreateVectorOfCoOwningReferencesVector(builder, data)

def MonsterAddNonOwningReference(builder, nonOwningReference):
    builder.PrependUint64Slot(41, nonOwningReference, 0)

def AddNonOwningReference(builder, nonOwningReference):
    MonsterAddNonOwningReference(builder, nonOwningReference)

def MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences):
    builder.PrependUOffsetTRelativeSlot(42, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfNonOwningReferences), 0)

def AddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences):
    MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)

def MonsterStartVectorOfNonOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfNonOwningReferencesVector(builder, numElems):
    return MonsterStartVectorOfNonOwningReferencesVector(builder, numElems)

def MonsterCreateVectorOfNonOwningReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def CreateVectorOfNonOwningReferencesVector(builder, data):
    MonsterCreateVectorOfNonOwningReferencesVector(builder, data)

def MonsterAddAnyUniqueType(builder, anyUniqueType):
    builder.PrependUint8Slot(43, anyUniqueType, 0)

def AddAnyUniqueType(builder, anyUniqueType):
    MonsterAddAnyUniqueType(builder, anyUniqueType)

def MonsterAddAnyUnique(builder, anyUnique):
    builder.PrependUOffsetTRelativeSlot(44, flatbuffers.number_types.UOffsetTFlags.py_type(anyUnique), 0)

def AddAnyUnique(builder, anyUnique):
    MonsterAddAnyUnique(builder, anyUnique)

def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType):
    builder.PrependUint8Slot(45, anyAmbiguousType, 0)

def AddAnyAmbiguousType(builder, anyAmbiguousType):
    MonsterAddAnyAmbiguousType(builder, anyAmbiguousType)

def MonsterAddAnyAmbiguous(builder, anyAmbiguous):
    builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)

def AddAnyAmbiguous(builder, anyAmbiguous):
    MonsterAddAnyAmbiguous(builder, anyAmbiguous)

def MonsterAddVectorOfEnums(builder, vectorOfEnums):
    builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)

def AddVectorOfEnums(builder, vectorOfEnums):
    MonsterAddVectorOfEnums(builder, vectorOfEnums)

def MonsterStartVectorOfEnumsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartVectorOfEnumsVector(builder, numElems):
    return MonsterStartVectorOfEnumsVector(builder, numElems)

def MonsterCreateVectorOfEnumsVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def CreateVectorOfEnumsVector(builder, data):
    MonsterCreateVectorOfEnumsVector(builder, data)

def MonsterAddSignedEnum(builder, signedEnum):
    builder.PrependInt8Slot(48, signedEnum, -1)

def AddSignedEnum(builder, signedEnum):
    MonsterAddSignedEnum(builder, signedEnum)

def MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(49, flatbuffers.number_types.UOffsetTFlags.py_type(testrequirednestedflatbuffer), 0)

def AddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer):
    MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer)

def MonsterStartTestrequirednestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestrequirednestedflatbufferVector(builder, numElems):
    return MonsterStartTestrequirednestedflatbufferVector(builder, numElems)

def MonsterCreateTestrequirednestedflatbufferVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def CreateTestrequirednestedflatbufferVector(builder, data):
    MonsterCreateTestrequirednestedflatbufferVector(builder, data)

def MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
    return MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes)
def MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables):
    builder.PrependUOffsetTRelativeSlot(50, flatbuffers.number_types.UOffsetTFlags.py_type(scalarKeySortedTables), 0)

def AddScalarKeySortedTables(builder, scalarKeySortedTables):
    MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables)

def MonsterStartScalarKeySortedTablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartScalarKeySortedTablesVector(builder, numElems):
    return MonsterStartScalarKeySortedTablesVector(builder, numElems)

def MonsterCreateScalarKeySortedTablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def CreateScalarKeySortedTablesVector(builder, data):
    MonsterCreateScalarKeySortedTablesVector(builder, data)

def MonsterAddNativeInline(builder, nativeInline):
    builder.PrependStructSlot(51, flatbuffers.number_types.UOffsetTFlags.py_type(nativeInline), 0)

def AddNativeInline(builder, nativeInline):
    MonsterAddNativeInline(builder, nativeInline)

def MonsterAddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault):
    builder.PrependUint64Slot(52, longEnumNonEnumDefault, 0)

def AddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault):
    MonsterAddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault)

def MonsterAddLongEnumNormalDefault(builder, longEnumNormalDefault):
    builder.PrependUint64Slot(53, longEnumNormalDefault, 2)

def AddLongEnumNormalDefault(builder, longEnumNormalDefault):
    MonsterAddLongEnumNormalDefault(builder, longEnumNormalDefault)

def MonsterAddNanDefault(builder, nanDefault):
    builder.PrependFloat32Slot(54, nanDefault, float('nan'))

def AddNanDefault(builder, nanDefault):
    MonsterAddNanDefault(builder, nanDefault)

def MonsterAddInfDefault(builder, infDefault):
    builder.PrependFloat32Slot(55, infDefault, float('inf'))

def AddInfDefault(builder, infDefault):
    MonsterAddInfDefault(builder, infDefault)

def MonsterAddPositiveInfDefault(builder, positiveInfDefault):
    builder.PrependFloat32Slot(56, positiveInfDefault, float('inf'))

def AddPositiveInfDefault(builder, positiveInfDefault):
    MonsterAddPositiveInfDefault(builder, positiveInfDefault)

def MonsterAddInfinityDefault(builder, infinityDefault):
    builder.PrependFloat32Slot(57, infinityDefault, float('inf'))

def AddInfinityDefault(builder, infinityDefault):
    MonsterAddInfinityDefault(builder, infinityDefault)

def MonsterAddPositiveInfinityDefault(builder, positiveInfinityDefault):
    builder.PrependFloat32Slot(58, positiveInfinityDefault, float('inf'))

def AddPositiveInfinityDefault(builder, positiveInfinityDefault):
    MonsterAddPositiveInfinityDefault(builder, positiveInfinityDefault)

def MonsterAddNegativeInfDefault(builder, negativeInfDefault):
    builder.PrependFloat32Slot(59, negativeInfDefault, float('-inf'))

def AddNegativeInfDefault(builder, negativeInfDefault):
    MonsterAddNegativeInfDefault(builder, negativeInfDefault)

def MonsterAddNegativeInfinityDefault(builder, negativeInfinityDefault):
    builder.PrependFloat32Slot(60, negativeInfinityDefault, float('-inf'))

def AddNegativeInfinityDefault(builder, negativeInfinityDefault):
    MonsterAddNegativeInfinityDefault(builder, negativeInfinityDefault)

def MonsterAddDoubleInfDefault(builder, doubleInfDefault):
    builder.PrependFloat64Slot(61, doubleInfDefault, float('inf'))

def AddDoubleInfDefault(builder, doubleInfDefault):
    MonsterAddDoubleInfDefault(builder, doubleInfDefault)

def MonsterEnd(builder):
    return builder.EndObject()

def End(builder):
    return MonsterEnd(builder)

import MyGame.Example.Ability
import MyGame.Example.Any
import MyGame.Example.AnyAmbiguousAliases
import MyGame.Example.AnyUniqueAliases
import MyGame.Example.Referrable
import MyGame.Example.Stat
import MyGame.Example.Test
import MyGame.Example.TestSimpleTableWithEnum
import MyGame.Example.Vec3
import MyGame.Example2.Monster
import MyGame.InParentNamespace
try:
    from typing import List, Optional, Union
except:
    pass

class MonsterT(object):

    # MonsterT
    def __init__(
        self,
        pos = None,
        mana = 150,
        hp = 100,
        name = None,
        inventory = None,
        color = 8,
        testType = 0,
        test = None,
        test4 = None,
        testarrayofstring = None,
        testarrayoftables = None,
        enemy = None,
        testnestedflatbuffer = None,
        testempty = None,
        testbool = False,
        testhashs32Fnv1 = 0,
        testhashu32Fnv1 = 0,
        testhashs64Fnv1 = 0,
        testhashu64Fnv1 = 0,
        testhashs32Fnv1a = 0,
        testhashu32Fnv1a = 0,
        testhashs64Fnv1a = 0,
        testhashu64Fnv1a = 0,
        testarrayofbools = None,
        testf = 3.14159,
        testf2 = 3.0,
        testf3 = 0.0,
        testarrayofstring2 = None,
        testarrayofsortedstruct = None,
        flex = None,
        test5 = None,
        vectorOfLongs = None,
        vectorOfDoubles = None,
        parentNamespaceTest = None,
        vectorOfReferrables = None,
        singleWeakReference = 0,
        vectorOfWeakReferences = None,
        vectorOfStrongReferrables = None,
        coOwningReference = 0,
        vectorOfCoOwningReferences = None,
        nonOwningReference = 0,
        vectorOfNonOwningReferences = None,
        anyUniqueType = 0,
        anyUnique = None,
        anyAmbiguousType = 0,
        anyAmbiguous = None,
        vectorOfEnums = None,
        signedEnum = -1,
        testrequirednestedflatbuffer = None,
        scalarKeySortedTables = None,
        nativeInline = None,
        longEnumNonEnumDefault = 0,
        longEnumNormalDefault = 2,
        nanDefault = float('nan'),
        infDefault = float('inf'),
        positiveInfDefault = float('inf'),
        infinityDefault = float('inf'),
        positiveInfinityDefault = float('inf'),
        negativeInfDefault = float('-inf'),
        negativeInfinityDefault = float('-inf'),
        doubleInfDefault = float('inf'),
    ):
        self.pos = pos  # type: Optional[MyGame.Example.Vec3.Vec3T]
        self.mana = mana  # type: int
        self.hp = hp  # type: int
        self.name = name  # type: Optional[str]
        self.inventory = inventory  # type: Optional[List[int]]
        self.color = color  # type: int
        self.testType = testType  # type: int
        self.test = test  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT', 'MyGame.Example2.Monster.MonsterT']
        self.test4 = test4  # type: Optional[List[MyGame.Example.Test.TestT]]
        self.testarrayofstring = testarrayofstring  # type: Optional[List[Optional[str]]]
        self.testarrayoftables = testarrayoftables  # type: Optional[List[MyGame.Example.Monster.MonsterT]]
        self.enemy = enemy  # type: Optional[MyGame.Example.Monster.MonsterT]
        self.testnestedflatbuffer = testnestedflatbuffer  # type: Optional[List[int]]
        self.testempty = testempty  # type: Optional[MyGame.Example.Stat.StatT]
        self.testbool = testbool  # type: bool
        self.testhashs32Fnv1 = testhashs32Fnv1  # type: int
        self.testhashu32Fnv1 = testhashu32Fnv1  # type: int
        self.testhashs64Fnv1 = testhashs64Fnv1  # type: int
        self.testhashu64Fnv1 = testhashu64Fnv1  # type: int
        self.testhashs32Fnv1a = testhashs32Fnv1a  # type: int
        self.testhashu32Fnv1a = testhashu32Fnv1a  # type: int
        self.testhashs64Fnv1a = testhashs64Fnv1a  # type: int
        self.testhashu64Fnv1a = testhashu64Fnv1a  # type: int
        self.testarrayofbools = testarrayofbools  # type: Optional[List[bool]]
        self.testf = testf  # type: float
        self.testf2 = testf2  # type: float
        self.testf3 = testf3  # type: float
        self.testarrayofstring2 = testarrayofstring2  # type: Optional[List[Optional[str]]]
        self.testarrayofsortedstruct = testarrayofsortedstruct  # type: Optional[List[MyGame.Example.Ability.AbilityT]]
        self.flex = flex  # type: Optional[List[int]]
        self.test5 = test5  # type: Optional[List[MyGame.Example.Test.TestT]]
        self.vectorOfLongs = vectorOfLongs  # type: Optional[List[int]]
        self.vectorOfDoubles = vectorOfDoubles  # type: Optional[List[float]]
        self.parentNamespaceTest = parentNamespaceTest  # type: Optional[MyGame.InParentNamespace.InParentNamespaceT]
        self.vectorOfReferrables = vectorOfReferrables  # type: Optional[List[MyGame.Example.Referrable.ReferrableT]]
        self.singleWeakReference = singleWeakReference  # type: int
        self.vectorOfWeakReferences = vectorOfWeakReferences  # type: Optional[List[int]]
        self.vectorOfStrongReferrables = vectorOfStrongReferrables  # type: Optional[List[MyGame.Example.Referrable.ReferrableT]]
        self.coOwningReference = coOwningReference  # type: int
        self.vectorOfCoOwningReferences = vectorOfCoOwningReferences  # type: Optional[List[int]]
        self.nonOwningReference = nonOwningReference  # type: int
        self.vectorOfNonOwningReferences = vectorOfNonOwningReferences  # type: Optional[List[int]]
        self.anyUniqueType = anyUniqueType  # type: int
        self.anyUnique = anyUnique  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT', 'MyGame.Example2.Monster.MonsterT']
        self.anyAmbiguousType = anyAmbiguousType  # type: int
        self.anyAmbiguous = anyAmbiguous  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.Monster.MonsterT']
        self.vectorOfEnums = vectorOfEnums  # type: Optional[List[int]]
        self.signedEnum = signedEnum  # type: int
        self.testrequirednestedflatbuffer = testrequirednestedflatbuffer  # type: Optional[List[int]]
        self.scalarKeySortedTables = scalarKeySortedTables  # type: Optional[List[MyGame.Example.Stat.StatT]]
        self.nativeInline = nativeInline  # type: Optional[MyGame.Example.Test.TestT]
        self.longEnumNonEnumDefault = longEnumNonEnumDefault  # type: int
        self.longEnumNormalDefault = longEnumNormalDefault  # type: int
        self.nanDefault = nanDefault  # type: float
        self.infDefault = infDefault  # type: float
        self.positiveInfDefault = positiveInfDefault  # type: float
        self.infinityDefault = infinityDefault  # type: float
        self.positiveInfinityDefault = positiveInfinityDefault  # type: float
        self.negativeInfDefault = negativeInfDefault  # type: float
        self.negativeInfinityDefault = negativeInfinityDefault  # type: float
        self.doubleInfDefault = doubleInfDefault  # type: float

    @classmethod
    def InitFromBuf(cls, buf, pos):
        monster = Monster()
        monster.Init(buf, pos)
        return cls.InitFromObj(monster)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, monster):
        x = MonsterT()
        x._UnPack(monster)
        return x

    # MonsterT
    def _UnPack(self, monster):
        if monster is None:
            return
        if monster.Pos() is not None:
            self.pos = MyGame.Example.Vec3.Vec3T.InitFromObj(monster.Pos())
        self.mana = monster.Mana()
        self.hp = monster.Hp()
        self.name = monster.Name()
        if not monster.InventoryIsNone():
            if np is None:
                self.inventory = []
                for i in range(monster.InventoryLength()):
                    self.inventory.append(monster.Inventory(i))
            else:
                self.inventory = monster.InventoryAsNumpy()
        self.color = monster.Color()
        self.testType = monster.TestType()
        self.test = MyGame.Example.Any.AnyCreator(self.testType, monster.Test())
        if not monster.Test4IsNone():
            self.test4 = []
            for i in range(monster.Test4Length()):
                if monster.Test4(i) is None:
                    self.test4.append(None)
                else:
                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test4(i))
                    self.test4.append(test_)
        if not monster.TestarrayofstringIsNone():
            self.testarrayofstring = []
            for i in range(monster.TestarrayofstringLength()):
                self.testarrayofstring.append(monster.Testarrayofstring(i))
        if not monster.TestarrayoftablesIsNone():
            self.testarrayoftables = []
            for i in range(monster.TestarrayoftablesLength()):
                if monster.Testarrayoftables(i) is None:
                    self.testarrayoftables.append(None)
                else:
                    monster_ = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Testarrayoftables(i))
                    self.testarrayoftables.append(monster_)
        if monster.Enemy() is not None:
            self.enemy = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Enemy())
        if not monster.TestnestedflatbufferIsNone():
            if np is None:
                self.testnestedflatbuffer = []
                for i in range(monster.TestnestedflatbufferLength()):
                    self.testnestedflatbuffer.append(monster.Testnestedflatbuffer(i))
            else:
                self.testnestedflatbuffer = monster.TestnestedflatbufferAsNumpy()
        if monster.Testempty() is not None:
            self.testempty = MyGame.Example.Stat.StatT.InitFromObj(monster.Testempty())
        self.testbool = monster.Testbool()
        self.testhashs32Fnv1 = monster.Testhashs32Fnv1()
        self.testhashu32Fnv1 = monster.Testhashu32Fnv1()
        self.testhashs64Fnv1 = monster.Testhashs64Fnv1()
        self.testhashu64Fnv1 = monster.Testhashu64Fnv1()
        self.testhashs32Fnv1a = monster.Testhashs32Fnv1a()
        self.testhashu32Fnv1a = monster.Testhashu32Fnv1a()
        self.testhashs64Fnv1a = monster.Testhashs64Fnv1a()
        self.testhashu64Fnv1a = monster.Testhashu64Fnv1a()
        if not monster.TestarrayofboolsIsNone():
            if np is None:
                self.testarrayofbools = []
                for i in range(monster.TestarrayofboolsLength()):
                    self.testarrayofbools.append(monster.Testarrayofbools(i))
            else:
                self.testarrayofbools = monster.TestarrayofboolsAsNumpy()
        self.testf = monster.Testf()
        self.testf2 = monster.Testf2()
        self.testf3 = monster.Testf3()
        if not monster.Testarrayofstring2IsNone():
            self.testarrayofstring2 = []
            for i in range(monster.Testarrayofstring2Length()):
                self.testarrayofstring2.append(monster.Testarrayofstring2(i))
        if not monster.TestarrayofsortedstructIsNone():
            self.testarrayofsortedstruct = []
            for i in range(monster.TestarrayofsortedstructLength()):
                if monster.Testarrayofsortedstruct(i) is None:
                    self.testarrayofsortedstruct.append(None)
                else:
                    ability_ = MyGame.Example.Ability.AbilityT.InitFromObj(monster.Testarrayofsortedstruct(i))
                    self.testarrayofsortedstruct.append(ability_)
        if not monster.FlexIsNone():
            if np is None:
                self.flex = []
                for i in range(monster.FlexLength()):
                    self.flex.append(monster.Flex(i))
            else:
                self.flex = monster.FlexAsNumpy()
        if not monster.Test5IsNone():
            self.test5 = []
            for i in range(monster.Test5Length()):
                if monster.Test5(i) is None:
                    self.test5.append(None)
                else:
                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test5(i))
                    self.test5.append(test_)
        if not monster.VectorOfLongsIsNone():
            if np is None:
                self.vectorOfLongs = []
                for i in range(monster.VectorOfLongsLength()):
                    self.vectorOfLongs.append(monster.VectorOfLongs(i))
            else:
                self.vectorOfLongs = monster.VectorOfLongsAsNumpy()
        if not monster.VectorOfDoublesIsNone():
            if np is None:
                self.vectorOfDoubles = []
                for i in range(monster.VectorOfDoublesLength()):
                    self.vectorOfDoubles.append(monster.VectorOfDoubles(i))
            else:
                self.vectorOfDoubles = monster.VectorOfDoublesAsNumpy()
        if monster.ParentNamespaceTest() is not None:
            self.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT.InitFromObj(monster.ParentNamespaceTest())
        if not monster.VectorOfReferrablesIsNone():
            self.vectorOfReferrables = []
            for i in range(monster.VectorOfReferrablesLength()):
                if monster.VectorOfReferrables(i) is None:
                    self.vectorOfReferrables.append(None)
                else:
                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfReferrables(i))
                    self.vectorOfReferrables.append(referrable_)
        self.singleWeakReference = monster.SingleWeakReference()
        if not monster.VectorOfWeakReferencesIsNone():
            if np is None:
                self.vectorOfWeakReferences = []
                for i in range(monster.VectorOfWeakReferencesLength()):
                    self.vectorOfWeakReferences.append(monster.VectorOfWeakReferences(i))
            else:
                self.vectorOfWeakReferences = monster.VectorOfWeakReferencesAsNumpy()
        if not monster.VectorOfStrongReferrablesIsNone():
            self.vectorOfStrongReferrables = []
            for i in range(monster.VectorOfStrongReferrablesLength()):
                if monster.VectorOfStrongReferrables(i) is None:
                    self.vectorOfStrongReferrables.append(None)
                else:
                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfStrongReferrables(i))
                    self.vectorOfStrongReferrables.append(referrable_)
        self.coOwningReference = monster.CoOwningReference()
        if not monster.VectorOfCoOwningReferencesIsNone():
            if np is None:
                self.vectorOfCoOwningReferences = []
                for i in range(monster.VectorOfCoOwningReferencesLength()):
                    self.vectorOfCoOwningReferences.append(monster.VectorOfCoOwningReferences(i))
            else:
                self.vectorOfCoOwningReferences = monster.VectorOfCoOwningReferencesAsNumpy()
        self.nonOwningReference = monster.NonOwningReference()
        if not monster.VectorOfNonOwningReferencesIsNone():
            if np is None:
                self.vectorOfNonOwningReferences = []
                for i in range(monster.VectorOfNonOwningReferencesLength()):
                    self.vectorOfNonOwningReferences.append(monster.VectorOfNonOwningReferences(i))
            else:
                self.vectorOfNonOwningReferences = monster.VectorOfNonOwningReferencesAsNumpy()
        self.anyUniqueType = monster.AnyUniqueType()
        self.anyUnique = MyGame.Example.AnyUniqueAliases.AnyUniqueAliasesCreator(self.anyUniqueType, monster.AnyUnique())
        self.anyAmbiguousType = monster.AnyAmbiguousType()
        self.anyAmbiguous = MyGame.Example.AnyAmbiguousAliases.AnyAmbiguousAliasesCreator(self.anyAmbiguousType, monster.AnyAmbiguous())
        if not monster.VectorOfEnumsIsNone():
            if np is None:
                self.vectorOfEnums = []
                for i in range(monster.VectorOfEnumsLength()):
                    self.vectorOfEnums.append(monster.VectorOfEnums(i))
            else:
                self.vectorOfEnums = monster.VectorOfEnumsAsNumpy()
        self.signedEnum = monster.SignedEnum()
        if not monster.TestrequirednestedflatbufferIsNone():
            if np is None:
                self.testrequirednestedflatbuffer = []
                for i in range(monster.TestrequirednestedflatbufferLength()):
                    self.testrequirednestedflatbuffer.append(monster.Testrequirednestedflatbuffer(i))
            else:
                self.testrequirednestedflatbuffer = monster.TestrequirednestedflatbufferAsNumpy()
        if not monster.ScalarKeySortedTablesIsNone():
            self.scalarKeySortedTables = []
            for i in range(monster.ScalarKeySortedTablesLength()):
                if monster.ScalarKeySortedTables(i) is None:
                    self.scalarKeySortedTables.append(None)
                else:
                    stat_ = MyGame.Example.Stat.StatT.InitFromObj(monster.ScalarKeySortedTables(i))
                    self.scalarKeySortedTables.append(stat_)
        if monster.NativeInline() is not None:
            self.nativeInline = MyGame.Example.Test.TestT.InitFromObj(monster.NativeInline())
        self.longEnumNonEnumDefault = monster.LongEnumNonEnumDefault()
        self.longEnumNormalDefault = monster.LongEnumNormalDefault()
        self.nanDefault = monster.NanDefault()
        self.infDefault = monster.InfDefault()
        self.positiveInfDefault = monster.PositiveInfDefault()
        self.infinityDefault = monster.InfinityDefault()
        self.positiveInfinityDefault = monster.PositiveInfinityDefault()
        self.negativeInfDefault = monster.NegativeInfDefault()
        self.negativeInfinityDefault = monster.NegativeInfinityDefault()
        self.doubleInfDefault = monster.DoubleInfDefault()

    # MonsterT
    def Pack(self, builder):
        if self.name is not None:
            name = builder.CreateString(self.name)
        if self.inventory is not None:
            if np is not None and type(self.inventory) is np.ndarray:
                inventory = builder.CreateNumpyVector(self.inventory)
            else:
                MonsterStartInventoryVector(builder, len(self.inventory))
                for i in reversed(range(len(self.inventory))):
                    builder.PrependUint8(self.inventory[i])
                inventory = builder.EndVector()
        if self.test is not None:
            test = self.test.Pack(builder)
        if self.test4 is not None:
            MonsterStartTest4Vector(builder, len(self.test4))
            for i in reversed(range(len(self.test4))):
                self.test4[i].Pack(builder)
            test4 = builder.EndVector()
        if self.testarrayofstring is not None:
            testarrayofstringlist = []
            for i in range(len(self.testarrayofstring)):
                testarrayofstringlist.append(builder.CreateString(self.testarrayofstring[i]))
            MonsterStartTestarrayofstringVector(builder, len(self.testarrayofstring))
            for i in reversed(range(len(self.testarrayofstring))):
                builder.PrependUOffsetTRelative(testarrayofstringlist[i])
            testarrayofstring = builder.EndVector()
        if self.testarrayoftables is not None:
            testarrayoftableslist = []
            for i in range(len(self.testarrayoftables)):
                testarrayoftableslist.append(self.testarrayoftables[i].Pack(builder))
            MonsterStartTestarrayoftablesVector(builder, len(self.testarrayoftables))
            for i in reversed(range(len(self.testarrayoftables))):
                builder.PrependUOffsetTRelative(testarrayoftableslist[i])
            testarrayoftables = builder.EndVector()
        if self.enemy is not None:
            enemy = self.enemy.Pack(builder)
        if self.testnestedflatbuffer is not None:
            if np is not None and type(self.testnestedflatbuffer) is np.ndarray:
                testnestedflatbuffer = builder.CreateNumpyVector(self.testnestedflatbuffer)
            else:
                MonsterStartTestnestedflatbufferVector(builder, len(self.testnestedflatbuffer))
                for i in reversed(range(len(self.testnestedflatbuffer))):
                    builder.PrependUint8(self.testnestedflatbuffer[i])
                testnestedflatbuffer = builder.EndVector()
        if self.testempty is not None:
            testempty = self.testempty.Pack(builder)
        if self.testarrayofbools is not None:
            if np is not None and type(self.testarrayofbools) is np.ndarray:
                testarrayofbools = builder.CreateNumpyVector(self.testarrayofbools)
            else:
                MonsterStartTestarrayofboolsVector(builder, len(self.testarrayofbools))
                for i in reversed(range(len(self.testarrayofbools))):
                    builder.PrependBool(self.testarrayofbools[i])
                testarrayofbools = builder.EndVector()
        if self.testarrayofstring2 is not None:
            testarrayofstring2list = []
            for i in range(len(self.testarrayofstring2)):
                testarrayofstring2list.append(builder.CreateString(self.testarrayofstring2[i]))
            MonsterStartTestarrayofstring2Vector(builder, len(self.testarrayofstring2))
            for i in reversed(range(len(self.testarrayofstring2))):
                builder.PrependUOffsetTRelative(testarrayofstring2list[i])
            testarrayofstring2 = builder.EndVector()
        if self.testarrayofsortedstruct is not None:
            MonsterStartTestarrayofsortedstructVector(builder, len(self.testarrayofsortedstruct))
            for i in reversed(range(len(self.testarrayofsortedstruct))):
                self.testarrayofsortedstruct[i].Pack(builder)
            testarrayofsortedstruct = builder.EndVector()
        if self.flex is not None:
            if np is not None and type(self.flex) is np.ndarray:
                flex = builder.CreateNumpyVector(self.flex)
            else:
                MonsterStartFlexVector(builder, len(self.flex))
                for i in reversed(range(len(self.flex))):
                    builder.PrependUint8(self.flex[i])
                flex = builder.EndVector()
        if self.test5 is not None:
            MonsterStartTest5Vector(builder, len(self.test5))
            for i in reversed(range(len(self.test5))):
                self.test5[i].Pack(builder)
            test5 = builder.EndVector()
        if self.vectorOfLongs is not None:
            if np is not None and type(self.vectorOfLongs) is np.ndarray:
                vectorOfLongs = builder.CreateNumpyVector(self.vectorOfLongs)
            else:
                MonsterStartVectorOfLongsVector(builder, len(self.vectorOfLongs))
                for i in reversed(range(len(self.vectorOfLongs))):
                    builder.PrependInt64(self.vectorOfLongs[i])
                vectorOfLongs = builder.EndVector()
        if self.vectorOfDoubles is not None:
            if np is not None and type(self.vectorOfDoubles) is np.ndarray:
                vectorOfDoubles = builder.CreateNumpyVector(self.vectorOfDoubles)
            else:
                MonsterStartVectorOfDoublesVector(builder, len(self.vectorOfDoubles))
                for i in reversed(range(len(self.vectorOfDoubles))):
                    builder.PrependFloat64(self.vectorOfDoubles[i])
                vectorOfDoubles = builder.EndVector()
        if self.parentNamespaceTest is not None:
            parentNamespaceTest = self.parentNamespaceTest.Pack(builder)
        if self.vectorOfReferrables is not None:
            vectorOfReferrableslist = []
            for i in range(len(self.vectorOfReferrables)):
                vectorOfReferrableslist.append(self.vectorOfReferrables[i].Pack(builder))
            MonsterStartVectorOfReferrablesVector(builder, len(self.vectorOfReferrables))
            for i in reversed(range(len(self.vectorOfReferrables))):
                builder.PrependUOffsetTRelative(vectorOfReferrableslist[i])
            vectorOfReferrables = builder.EndVector()
        if self.vectorOfWeakReferences is not None:
            if np is not None and type(self.vectorOfWeakReferences) is np.ndarray:
                vectorOfWeakReferences = builder.CreateNumpyVector(self.vectorOfWeakReferences)
            else:
                MonsterStartVectorOfWeakReferencesVector(builder, len(self.vectorOfWeakReferences))
                for i in reversed(range(len(self.vectorOfWeakReferences))):
                    builder.PrependUint64(self.vectorOfWeakReferences[i])
                vectorOfWeakReferences = builder.EndVector()
        if self.vectorOfStrongReferrables is not None:
            vectorOfStrongReferrableslist = []
            for i in range(len(self.vectorOfStrongReferrables)):
                vectorOfStrongReferrableslist.append(self.vectorOfStrongReferrables[i].Pack(builder))
            MonsterStartVectorOfStrongReferrablesVector(builder, len(self.vectorOfStrongReferrables))
            for i in reversed(range(len(self.vectorOfStrongReferrables))):
                builder.PrependUOffsetTRelative(vectorOfStrongReferrableslist[i])
            vectorOfStrongReferrables = builder.EndVector()
        if self.vectorOfCoOwningReferences is not None:
            if np is not None and type(self.vectorOfCoOwningReferences) is np.ndarray:
                vectorOfCoOwningReferences = builder.CreateNumpyVector(self.vectorOfCoOwningReferences)
            else:
                MonsterStartVectorOfCoOwningReferencesVector(builder, len(self.vectorOfCoOwningReferences))
                for i in reversed(range(len(self.vectorOfCoOwningReferences))):
                    builder.PrependUint64(self.vectorOfCoOwningReferences[i])
                vectorOfCoOwningReferences = builder.EndVector()
        if self.vectorOfNonOwningReferences is not None:
            if np is not None and type(self.vectorOfNonOwningReferences) is np.ndarray:
                vectorOfNonOwningReferences = builder.CreateNumpyVector(self.vectorOfNonOwningReferences)
            else:
                MonsterStartVectorOfNonOwningReferencesVector(builder, len(self.vectorOfNonOwningReferences))
                for i in reversed(range(len(self.vectorOfNonOwningReferences))):
                    builder.PrependUint64(self.vectorOfNonOwningReferences[i])
                vectorOfNonOwningReferences = builder.EndVector()
        if self.anyUnique is not None:
            anyUnique = self.anyUnique.Pack(builder)
        if self.anyAmbiguous is not None:
            anyAmbiguous = self.anyAmbiguous.Pack(builder)
        if self.vectorOfEnums is not None:
            if np is not None and type(self.vectorOfEnums) is np.ndarray:
                vectorOfEnums = builder.CreateNumpyVector(self.vectorOfEnums)
            else:
                MonsterStartVectorOfEnumsVector(builder, len(self.vectorOfEnums))
                for i in reversed(range(len(self.vectorOfEnums))):
                    builder.PrependUint8(self.vectorOfEnums[i])
                vectorOfEnums = builder.EndVector()
        if self.testrequirednestedflatbuffer is not None:
            if np is not None and type(self.testrequirednestedflatbuffer) is np.ndarray:
                testrequirednestedflatbuffer = builder.CreateNumpyVector(self.testrequirednestedflatbuffer)
            else:
                MonsterStartTestrequirednestedflatbufferVector(builder, len(self.testrequirednestedflatbuffer))
                for i in reversed(range(len(self.testrequirednestedflatbuffer))):
                    builder.PrependUint8(self.testrequirednestedflatbuffer[i])
                testrequirednestedflatbuffer = builder.EndVector()
        if self.scalarKeySortedTables is not None:
            scalarKeySortedTableslist = []
            for i in range(len(self.scalarKeySortedTables)):
                scalarKeySortedTableslist.append(self.scalarKeySortedTables[i].Pack(builder))
            MonsterStartScalarKeySortedTablesVector(builder, len(self.scalarKeySortedTables))
            for i in reversed(range(len(self.scalarKeySortedTables))):
                builder.PrependUOffsetTRelative(scalarKeySortedTableslist[i])
            scalarKeySortedTables = builder.EndVector()
        MonsterStart(builder)
        if self.pos is not None:
            pos = self.pos.Pack(builder)
            MonsterAddPos(builder, pos)
        MonsterAddMana(builder, self.mana)
        MonsterAddHp(builder, self.hp)
        if self.name is not None:
            MonsterAddName(builder, name)
        if self.inventory is not None:
            MonsterAddInventory(builder, inventory)
        MonsterAddColor(builder, self.color)
        MonsterAddTestType(builder, self.testType)
        if self.test is not None:
            MonsterAddTest(builder, test)
        if self.test4 is not None:
            MonsterAddTest4(builder, test4)
        if self.testarrayofstring is not None:
            MonsterAddTestarrayofstring(builder, testarrayofstring)
        if self.testarrayoftables is not None:
            MonsterAddTestarrayoftables(builder, testarrayoftables)
        if self.enemy is not None:
            MonsterAddEnemy(builder, enemy)
        if self.testnestedflatbuffer is not None:
            MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)
        if self.testempty is not None:
            MonsterAddTestempty(builder, testempty)
        MonsterAddTestbool(builder, self.testbool)
        MonsterAddTesthashs32Fnv1(builder, self.testhashs32Fnv1)
        MonsterAddTesthashu32Fnv1(builder, self.testhashu32Fnv1)
        MonsterAddTesthashs64Fnv1(builder, self.testhashs64Fnv1)
        MonsterAddTesthashu64Fnv1(builder, self.testhashu64Fnv1)
        MonsterAddTesthashs32Fnv1a(builder, self.testhashs32Fnv1a)
        MonsterAddTesthashu32Fnv1a(builder, self.testhashu32Fnv1a)
        MonsterAddTesthashs64Fnv1a(builder, self.testhashs64Fnv1a)
        MonsterAddTesthashu64Fnv1a(builder, self.testhashu64Fnv1a)
        if self.testarrayofbools is not None:
            MonsterAddTestarrayofbools(builder, testarrayofbools)
        MonsterAddTestf(builder, self.testf)
        MonsterAddTestf2(builder, self.testf2)
        MonsterAddTestf3(builder, self.testf3)
        if self.testarrayofstring2 is not None:
            MonsterAddTestarrayofstring2(builder, testarrayofstring2)
        if self.testarrayofsortedstruct is not None:
            MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)
        if self.flex is not None:
            MonsterAddFlex(builder, flex)
        if self.test5 is not None:
            MonsterAddTest5(builder, test5)
        if self.vectorOfLongs is not None:
            MonsterAddVectorOfLongs(builder, vectorOfLongs)
        if self.vectorOfDoubles is not None:
            MonsterAddVectorOfDoubles(builder, vectorOfDoubles)
        if self.parentNamespaceTest is not None:
            MonsterAddParentNamespaceTest(builder, parentNamespaceTest)
        if self.vectorOfReferrables is not None:
            MonsterAddVectorOfReferrables(builder, vectorOfReferrables)
        MonsterAddSingleWeakReference(builder, self.singleWeakReference)
        if self.vectorOfWeakReferences is not None:
            MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)
        if self.vectorOfStrongReferrables is not None:
            MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)
        MonsterAddCoOwningReference(builder, self.coOwningReference)
        if self.vectorOfCoOwningReferences is not None:
            MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)
        MonsterAddNonOwningReference(builder, self.nonOwningReference)
        if self.vectorOfNonOwningReferences is not None:
            MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)
        MonsterAddAnyUniqueType(builder, self.anyUniqueType)
        if self.anyUnique is not None:
            MonsterAddAnyUnique(builder, anyUnique)
        MonsterAddAnyAmbiguousType(builder, self.anyAmbiguousType)
        if self.anyAmbiguous is not None:
            MonsterAddAnyAmbiguous(builder, anyAmbiguous)
        if self.vectorOfEnums is not None:
            MonsterAddVectorOfEnums(builder, vectorOfEnums)
        MonsterAddSignedEnum(builder, self.signedEnum)
        if self.testrequirednestedflatbuffer is not None:
            MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer)
        if self.scalarKeySortedTables is not None:
            MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables)
        if self.nativeInline is not None:
            nativeInline = self.nativeInline.Pack(builder)
            MonsterAddNativeInline(builder, nativeInline)
        MonsterAddLongEnumNonEnumDefault(builder, self.longEnumNonEnumDefault)
        MonsterAddLongEnumNormalDefault(builder, self.longEnumNormalDefault)
        MonsterAddNanDefault(builder, self.nanDefault)
        MonsterAddInfDefault(builder, self.infDefault)
        MonsterAddPositiveInfDefault(builder, self.positiveInfDefault)
        MonsterAddInfinityDefault(builder, self.infinityDefault)
        MonsterAddPositiveInfinityDefault(builder, self.positiveInfinityDefault)
        MonsterAddNegativeInfDefault(builder, self.negativeInfDefault)
        MonsterAddNegativeInfinityDefault(builder, self.negativeInfinityDefault)
        MonsterAddDoubleInfDefault(builder, self.doubleInfDefault)
        monster = MonsterEnd(builder)
        return monster
