// automatically generated by the FlatBuffers compiler, do not modify

package MyGame.Example;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

/**
 * an example documentation comment: "monster object"
 */
@SuppressWarnings("unused")
public final class Monster extends Table {
  public static void ValidateVersion() { Constants.FLATBUFFERS_22_10_25(); }
  public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
  public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
  public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public MyGame.Example.Vec3 pos() { return pos(new MyGame.Example.Vec3()); }
  public MyGame.Example.Vec3 pos(MyGame.Example.Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
  public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
  public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
  public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
  public boolean mutateHp(short hp) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, hp); return true; } else { return false; } }
  public String name() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
  public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
  public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
  public int inventory(int j) { int o = __offset(14); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
  public int inventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector inventoryVector() { return inventoryVector(new ByteVector()); }
  public ByteVector inventoryVector(ByteVector obj) { int o = __offset(14); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer inventoryAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
  public ByteBuffer inventoryInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 1); }
  public boolean mutateInventory(int j, int inventory) { int o = __offset(14); if (o != 0) { bb.put(__vector(o) + j * 1, (byte) inventory); return true; } else { return false; } }
  public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; }
  public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte) color); return true; } else { return false; } }
  public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o + bb_pos) : null; }
  public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); }
  public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
  public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Test.Vector test4Vector() { return test4Vector(new MyGame.Example.Test.Vector()); }
  public MyGame.Example.Test.Vector test4Vector(MyGame.Example.Test.Vector obj) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
  public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
  public StringVector testarrayofstringVector() { return testarrayofstringVector(new StringVector()); }
  public StringVector testarrayofstringVector(StringVector obj) { int o = __offset(24); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  /**
   * an example documentation comment: this will end up in the generated code
   * multiline too
   */
  public MyGame.Example.Monster testarrayoftables(int j) { return testarrayoftables(new MyGame.Example.Monster(), j); }
  public MyGame.Example.Monster testarrayoftables(MyGame.Example.Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
  public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Monster testarrayoftablesByKey(String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb) : null; }
  public MyGame.Example.Monster testarrayoftablesByKey(MyGame.Example.Monster obj, String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb) : null; }
  public MyGame.Example.Monster.Vector testarrayoftablesVector() { return testarrayoftablesVector(new MyGame.Example.Monster.Vector()); }
  public MyGame.Example.Monster.Vector testarrayoftablesVector(MyGame.Example.Monster.Vector obj) { int o = __offset(26); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public MyGame.Example.Monster enemy() { return enemy(new MyGame.Example.Monster()); }
  public MyGame.Example.Monster enemy(MyGame.Example.Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
  public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
  public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector testnestedflatbufferVector() { return testnestedflatbufferVector(new ByteVector()); }
  public ByteVector testnestedflatbufferVector(ByteVector obj) { int o = __offset(30); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
  public ByteBuffer testnestedflatbufferInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 1); }
  public MyGame.Example.Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new MyGame.Example.Monster()); }
  public MyGame.Example.Monster testnestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
  public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte) testnestedflatbuffer); return true; } else { return false; } }
  public MyGame.Example.Stat testempty() { return testempty(new MyGame.Example.Stat()); }
  public MyGame.Example.Stat testempty(MyGame.Example.Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
  public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
  public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
  public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
  public boolean mutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
  public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
  public boolean mutateTesthashu32Fnv1(long testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.putInt(o + bb_pos, (int) testhashu32_fnv1); return true; } else { return false; } }
  public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
  public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateTesthashu64Fnv1(long testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
  public int testhashs32Fnv1a() { int o = __offset(44); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
  public boolean mutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
  public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
  public boolean mutateTesthashu32Fnv1a(long testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.putInt(o + bb_pos, (int) testhashu32_fnv1a); return true; } else { return false; } }
  public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
  public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
  public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
  public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
  public BooleanVector testarrayofboolsVector() { return testarrayofboolsVector(new BooleanVector()); }
  public BooleanVector testarrayofboolsVector(BooleanVector obj) { int o = __offset(52); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer testarrayofboolsAsByteBuffer() { return __vector_as_bytebuffer(52, 1); }
  public ByteBuffer testarrayofboolsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 1); }
  public boolean mutateTestarrayofbools(int j, boolean testarrayofbools) { int o = __offset(52); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
  public float testf() { int o = __offset(54); return o != 0 ? bb.getFloat(o + bb_pos) : 3.14159f; }
  public boolean mutateTestf(float testf) { int o = __offset(54); if (o != 0) { bb.putFloat(o + bb_pos, testf); return true; } else { return false; } }
  public float testf2() { int o = __offset(56); return o != 0 ? bb.getFloat(o + bb_pos) : 3.0f; }
  public boolean mutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.putFloat(o + bb_pos, testf2); return true; } else { return false; } }
  public float testf3() { int o = __offset(58); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
  public boolean mutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.putFloat(o + bb_pos, testf3); return true; } else { return false; } }
  public String testarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; }
  public int testarrayofstring2Length() { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; }
  public StringVector testarrayofstring2Vector() { return testarrayofstring2Vector(new StringVector()); }
  public StringVector testarrayofstring2Vector(StringVector obj) { int o = __offset(60); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public MyGame.Example.Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new MyGame.Example.Ability(), j); }
  public MyGame.Example.Ability testarrayofsortedstruct(MyGame.Example.Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
  public int testarrayofsortedstructLength() { int o = __offset(62); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Ability.Vector testarrayofsortedstructVector() { return testarrayofsortedstructVector(new MyGame.Example.Ability.Vector()); }
  public MyGame.Example.Ability.Vector testarrayofsortedstructVector(MyGame.Example.Ability.Vector obj) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o), 8, bb) : null; }
  public int flex(int j) { int o = __offset(64); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
  public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector flexVector() { return flexVector(new ByteVector()); }
  public ByteVector flexVector(ByteVector obj) { int o = __offset(64); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
  public ByteBuffer flexInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 64, 1); }
  public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte) flex); return true; } else { return false; } }
  public MyGame.Example.Test test5(int j) { return test5(new MyGame.Example.Test(), j); }
  public MyGame.Example.Test test5(MyGame.Example.Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
  public int test5Length() { int o = __offset(66); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Test.Vector test5Vector() { return test5Vector(new MyGame.Example.Test.Vector()); }
  public MyGame.Example.Test.Vector test5Vector(MyGame.Example.Test.Vector obj) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public long vectorOfLongs(int j) { int o = __offset(68); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
  public int vectorOfLongsLength() { int o = __offset(68); return o != 0 ? __vector_len(o) : 0; }
  public LongVector vectorOfLongsVector() { return vectorOfLongsVector(new LongVector()); }
  public LongVector vectorOfLongsVector(LongVector obj) { int o = __offset(68); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfLongsAsByteBuffer() { return __vector_as_bytebuffer(68, 8); }
  public ByteBuffer vectorOfLongsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 68, 8); }
  public boolean mutateVectorOfLongs(int j, long vector_of_longs) { int o = __offset(68); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
  public double vectorOfDoubles(int j) { int o = __offset(70); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
  public int vectorOfDoublesLength() { int o = __offset(70); return o != 0 ? __vector_len(o) : 0; }
  public DoubleVector vectorOfDoublesVector() { return vectorOfDoublesVector(new DoubleVector()); }
  public DoubleVector vectorOfDoublesVector(DoubleVector obj) { int o = __offset(70); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfDoublesAsByteBuffer() { return __vector_as_bytebuffer(70, 8); }
  public ByteBuffer vectorOfDoublesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 70, 8); }
  public boolean mutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __offset(70); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
  public MyGame.InParentNamespace parentNamespaceTest() { return parentNamespaceTest(new MyGame.InParentNamespace()); }
  public MyGame.InParentNamespace parentNamespaceTest(MyGame.InParentNamespace obj) { int o = __offset(72); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
  public MyGame.Example.Referrable vectorOfReferrables(int j) { return vectorOfReferrables(new MyGame.Example.Referrable(), j); }
  public MyGame.Example.Referrable vectorOfReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(74); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
  public int vectorOfReferrablesLength() { int o = __offset(74); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Referrable vectorOfReferrablesByKey(long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
  public MyGame.Example.Referrable vectorOfReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
  public MyGame.Example.Referrable.Vector vectorOfReferrablesVector() { return vectorOfReferrablesVector(new MyGame.Example.Referrable.Vector()); }
  public MyGame.Example.Referrable.Vector vectorOfReferrablesVector(MyGame.Example.Referrable.Vector obj) { int o = __offset(74); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public long singleWeakReference() { int o = __offset(76); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateSingleWeakReference(long single_weak_reference) { int o = __offset(76); if (o != 0) { bb.putLong(o + bb_pos, single_weak_reference); return true; } else { return false; } }
  public long vectorOfWeakReferences(int j) { int o = __offset(78); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
  public int vectorOfWeakReferencesLength() { int o = __offset(78); return o != 0 ? __vector_len(o) : 0; }
  public LongVector vectorOfWeakReferencesVector() { return vectorOfWeakReferencesVector(new LongVector()); }
  public LongVector vectorOfWeakReferencesVector(LongVector obj) { int o = __offset(78); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfWeakReferencesAsByteBuffer() { return __vector_as_bytebuffer(78, 8); }
  public ByteBuffer vectorOfWeakReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 78, 8); }
  public boolean mutateVectorOfWeakReferences(int j, long vector_of_weak_references) { int o = __offset(78); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
  public MyGame.Example.Referrable vectorOfStrongReferrables(int j) { return vectorOfStrongReferrables(new MyGame.Example.Referrable(), j); }
  public MyGame.Example.Referrable vectorOfStrongReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(80); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
  public int vectorOfStrongReferrablesLength() { int o = __offset(80); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
  public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
  public MyGame.Example.Referrable.Vector vectorOfStrongReferrablesVector() { return vectorOfStrongReferrablesVector(new MyGame.Example.Referrable.Vector()); }
  public MyGame.Example.Referrable.Vector vectorOfStrongReferrablesVector(MyGame.Example.Referrable.Vector obj) { int o = __offset(80); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public long coOwningReference() { int o = __offset(82); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateCoOwningReference(long co_owning_reference) { int o = __offset(82); if (o != 0) { bb.putLong(o + bb_pos, co_owning_reference); return true; } else { return false; } }
  public long vectorOfCoOwningReferences(int j) { int o = __offset(84); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
  public int vectorOfCoOwningReferencesLength() { int o = __offset(84); return o != 0 ? __vector_len(o) : 0; }
  public LongVector vectorOfCoOwningReferencesVector() { return vectorOfCoOwningReferencesVector(new LongVector()); }
  public LongVector vectorOfCoOwningReferencesVector(LongVector obj) { int o = __offset(84); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfCoOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(84, 8); }
  public ByteBuffer vectorOfCoOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 84, 8); }
  public boolean mutateVectorOfCoOwningReferences(int j, long vector_of_co_owning_references) { int o = __offset(84); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
  public long nonOwningReference() { int o = __offset(86); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateNonOwningReference(long non_owning_reference) { int o = __offset(86); if (o != 0) { bb.putLong(o + bb_pos, non_owning_reference); return true; } else { return false; } }
  public long vectorOfNonOwningReferences(int j) { int o = __offset(88); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
  public int vectorOfNonOwningReferencesLength() { int o = __offset(88); return o != 0 ? __vector_len(o) : 0; }
  public LongVector vectorOfNonOwningReferencesVector() { return vectorOfNonOwningReferencesVector(new LongVector()); }
  public LongVector vectorOfNonOwningReferencesVector(LongVector obj) { int o = __offset(88); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfNonOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(88, 8); }
  public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); }
  public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
  public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o + bb_pos) : null; }
  public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o + bb_pos) : null; }
  public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
  public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector vectorOfEnumsVector() { return vectorOfEnumsVector(new ByteVector()); }
  public ByteVector vectorOfEnumsVector(ByteVector obj) { int o = __offset(98); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vectorOfEnumsAsByteBuffer() { return __vector_as_bytebuffer(98, 1); }
  public ByteBuffer vectorOfEnumsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 98, 1); }
  public boolean mutateVectorOfEnums(int j, int vector_of_enums) { int o = __offset(98); if (o != 0) { bb.put(__vector(o) + j * 1, (byte) vector_of_enums); return true; } else { return false; } }
  public byte signedEnum() { int o = __offset(100); return o != 0 ? bb.get(o + bb_pos) : -1; }
  public boolean mutateSignedEnum(byte signed_enum) { int o = __offset(100); if (o != 0) { bb.put(o + bb_pos, signed_enum); return true; } else { return false; } }
  public int testrequirednestedflatbuffer(int j) { int o = __offset(102); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
  public int testrequirednestedflatbufferLength() { int o = __offset(102); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector testrequirednestedflatbufferVector() { return testrequirednestedflatbufferVector(new ByteVector()); }
  public ByteVector testrequirednestedflatbufferVector(ByteVector obj) { int o = __offset(102); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer testrequirednestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(102, 1); }
  public ByteBuffer testrequirednestedflatbufferInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 102, 1); }
  public MyGame.Example.Monster testrequirednestedflatbufferAsMonster() { return testrequirednestedflatbufferAsMonster(new MyGame.Example.Monster()); }
  public MyGame.Example.Monster testrequirednestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(102); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
  public boolean mutateTestrequirednestedflatbuffer(int j, int testrequirednestedflatbuffer) { int o = __offset(102); if (o != 0) { bb.put(__vector(o) + j * 1, (byte) testrequirednestedflatbuffer); return true; } else { return false; } }
  public MyGame.Example.Stat scalarKeySortedTables(int j) { return scalarKeySortedTables(new MyGame.Example.Stat(), j); }
  public MyGame.Example.Stat scalarKeySortedTables(MyGame.Example.Stat obj, int j) { int o = __offset(104); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
  public int scalarKeySortedTablesLength() { int o = __offset(104); return o != 0 ? __vector_len(o) : 0; }
  public MyGame.Example.Stat scalarKeySortedTablesByKey(int key) { int o = __offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(null, __vector(o), key, bb) : null; }
  public MyGame.Example.Stat scalarKeySortedTablesByKey(MyGame.Example.Stat obj, int key) { int o = __offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(obj, __vector(o), key, bb) : null; }
  public MyGame.Example.Stat.Vector scalarKeySortedTablesVector() { return scalarKeySortedTablesVector(new MyGame.Example.Stat.Vector()); }
  public MyGame.Example.Stat.Vector scalarKeySortedTablesVector(MyGame.Example.Stat.Vector obj) { int o = __offset(104); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
  public MyGame.Example.Test nativeInline() { return nativeInline(new MyGame.Example.Test()); }
  public MyGame.Example.Test nativeInline(MyGame.Example.Test obj) { int o = __offset(106); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
  public long longEnumNonEnumDefault() { int o = __offset(108); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateLongEnumNonEnumDefault(long long_enum_non_enum_default) { int o = __offset(108); if (o != 0) { bb.putLong(o + bb_pos, long_enum_non_enum_default); return true; } else { return false; } }
  public long longEnumNormalDefault() { int o = __offset(110); return o != 0 ? bb.getLong(o + bb_pos) : 2L; }
  public boolean mutateLongEnumNormalDefault(long long_enum_normal_default) { int o = __offset(110); if (o != 0) { bb.putLong(o + bb_pos, long_enum_normal_default); return true; } else { return false; } }

  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(54); }
  public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
  public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
  public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
  public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(nameOffset); builder.slot(3); }
  public static void addInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.addOffset(5, inventoryOffset, 0); }
  public static int createInventoryVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createInventoryVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startInventoryVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(6, (byte) color, (byte) 8); }
  public static void addTestType(FlatBufferBuilder builder, byte testType) { builder.addByte(7, testType, 0); }
  public static void addTest(FlatBufferBuilder builder, int testOffset) { builder.addOffset(8, testOffset, 0); }
  public static void addTest4(FlatBufferBuilder builder, int test4Offset) { builder.addOffset(9, test4Offset, 0); }
  public static void startTest4Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
  public static void addTestarrayofstring(FlatBufferBuilder builder, int testarrayofstringOffset) { builder.addOffset(10, testarrayofstringOffset, 0); }
  public static int createTestarrayofstringVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftablesOffset) { builder.addOffset(11, testarrayoftablesOffset, 0); }
  public static int createTestarrayoftablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.addOffset(12, enemyOffset, 0); }
  public static void addTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.addOffset(13, testnestedflatbufferOffset, 0); }
  public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
  public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
  public static void addTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.addInt(16, testhashs32Fnv1, 0); }
  public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int) testhashu32Fnv1, (int) 0L); }
  public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0L); }
  public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0L); }
  public static void addTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.addInt(20, testhashs32Fnv1a, 0); }
  public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int) testhashu32Fnv1a, (int) 0L); }
  public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0L); }
  public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0L); }
  public static void addTestarrayofbools(FlatBufferBuilder builder, int testarrayofboolsOffset) { builder.addOffset(24, testarrayofboolsOffset, 0); }
  public static int createTestarrayofboolsVector(FlatBufferBuilder builder, boolean[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addBoolean(data[i]); return builder.endVector(); }
  public static void startTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addTestf(FlatBufferBuilder builder, float testf) { builder.addFloat(25, testf, 3.14159f); }
  public static void addTestf2(FlatBufferBuilder builder, float testf2) { builder.addFloat(26, testf2, 3.0f); }
  public static void addTestf3(FlatBufferBuilder builder, float testf3) { builder.addFloat(27, testf3, 0.0f); }
  public static void addTestarrayofstring2(FlatBufferBuilder builder, int testarrayofstring2Offset) { builder.addOffset(28, testarrayofstring2Offset, 0); }
  public static int createTestarrayofstring2Vector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addTestarrayofsortedstruct(FlatBufferBuilder builder, int testarrayofsortedstructOffset) { builder.addOffset(29, testarrayofsortedstructOffset, 0); }
  public static void startTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 4); }
  public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
  public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createFlexVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addTest5(FlatBufferBuilder builder, int test5Offset) { builder.addOffset(31, test5Offset, 0); }
  public static void startTest5Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
  public static void addVectorOfLongs(FlatBufferBuilder builder, int vectorOfLongsOffset) { builder.addOffset(32, vectorOfLongsOffset, 0); }
  public static int createVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
  public static void startVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static void addVectorOfDoubles(FlatBufferBuilder builder, int vectorOfDoublesOffset) { builder.addOffset(33, vectorOfDoublesOffset, 0); }
  public static int createVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
  public static void startVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static void addParentNamespaceTest(FlatBufferBuilder builder, int parentNamespaceTestOffset) { builder.addOffset(34, parentNamespaceTestOffset, 0); }
  public static void addVectorOfReferrables(FlatBufferBuilder builder, int vectorOfReferrablesOffset) { builder.addOffset(35, vectorOfReferrablesOffset, 0); }
  public static int createVectorOfReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addSingleWeakReference(FlatBufferBuilder builder, long singleWeakReference) { builder.addLong(36, singleWeakReference, 0L); }
  public static void addVectorOfWeakReferences(FlatBufferBuilder builder, int vectorOfWeakReferencesOffset) { builder.addOffset(37, vectorOfWeakReferencesOffset, 0); }
  public static int createVectorOfWeakReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
  public static void startVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static void addVectorOfStrongReferrables(FlatBufferBuilder builder, int vectorOfStrongReferrablesOffset) { builder.addOffset(38, vectorOfStrongReferrablesOffset, 0); }
  public static int createVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addCoOwningReference(FlatBufferBuilder builder, long coOwningReference) { builder.addLong(39, coOwningReference, 0L); }
  public static void addVectorOfCoOwningReferences(FlatBufferBuilder builder, int vectorOfCoOwningReferencesOffset) { builder.addOffset(40, vectorOfCoOwningReferencesOffset, 0); }
  public static int createVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
  public static void startVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static void addNonOwningReference(FlatBufferBuilder builder, long nonOwningReference) { builder.addLong(41, nonOwningReference, 0L); }
  public static void addVectorOfNonOwningReferences(FlatBufferBuilder builder, int vectorOfNonOwningReferencesOffset) { builder.addOffset(42, vectorOfNonOwningReferencesOffset, 0); }
  public static int createVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
  public static void startVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static void addAnyUniqueType(FlatBufferBuilder builder, byte anyUniqueType) { builder.addByte(43, anyUniqueType, 0); }
  public static void addAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.addOffset(44, anyUniqueOffset, 0); }
  public static void addAnyAmbiguousType(FlatBufferBuilder builder, byte anyAmbiguousType) { builder.addByte(45, anyAmbiguousType, 0); }
  public static void addAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.addOffset(46, anyAmbiguousOffset, 0); }
  public static void addVectorOfEnums(FlatBufferBuilder builder, int vectorOfEnumsOffset) { builder.addOffset(47, vectorOfEnumsOffset, 0); }
  public static int createVectorOfEnumsVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createVectorOfEnumsVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addSignedEnum(FlatBufferBuilder builder, byte signedEnum) { builder.addByte(48, signedEnum, -1); }
  public static void addTestrequirednestedflatbuffer(FlatBufferBuilder builder, int testrequirednestedflatbufferOffset) { builder.addOffset(49, testrequirednestedflatbufferOffset, 0); }
  public static int createTestrequirednestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createTestrequirednestedflatbufferVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startTestrequirednestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addScalarKeySortedTables(FlatBufferBuilder builder, int scalarKeySortedTablesOffset) { builder.addOffset(50, scalarKeySortedTablesOffset, 0); }
  public static int createScalarKeySortedTablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
  public static void startScalarKeySortedTablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
  public static void addNativeInline(FlatBufferBuilder builder, int nativeInlineOffset) { builder.addStruct(51, nativeInlineOffset, 0); }
  public static void addLongEnumNonEnumDefault(FlatBufferBuilder builder, long longEnumNonEnumDefault) { builder.addLong(52, longEnumNonEnumDefault, 0L); }
  public static void addLongEnumNormalDefault(FlatBufferBuilder builder, long longEnumNormalDefault) { builder.addLong(53, longEnumNormalDefault, 2L); }
  public static int endMonster(FlatBufferBuilder builder) {
    int o = builder.endTable();
    builder.required(o, 10);  // name
    return o;
  }
  public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); }
  public static void finishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONS"); }

  @Override
  protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }

  public static Monster __lookup_by_key(Monster obj, int vectorLocation, String key, ByteBuffer bb) {
    byte[] byteKey = key.getBytes(java.nio.charset.StandardCharsets.UTF_8);
    int span = bb.getInt(vectorLocation - 4);
    int start = 0;
    while (span != 0) {
      int middle = span / 2;
      int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
      int comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb);
      if (comp > 0) {
        span = middle;
      } else if (comp < 0) {
        middle++;
        start += middle;
        span -= middle;
      } else {
        return (obj == null ? new Monster() : obj).__assign(tableOffset, bb);
      }
    }
    return null;
  }

  public static final class Vector extends BaseVector {
    public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }

    public Monster get(int j) { return get(new Monster(), j); }
    public Monster get(Monster obj, int j) {  return obj.__assign(__indirect(__element(j), bb), bb); }
    public Monster getByKey(String key) {  return __lookup_by_key(null, __vector(), key, bb); }
    public Monster getByKey(Monster obj, String key) {  return __lookup_by_key(obj, __vector(), key, bb); }
  }
  public MonsterT unpack() {
    MonsterT _o = new MonsterT();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(MonsterT _o) {
    if (pos() != null) pos().unpackTo(_o.getPos());
    else _o.setPos(null);
    short _oMana = mana();
    _o.setMana(_oMana);
    short _oHp = hp();
    _o.setHp(_oHp);
    String _oName = name();
    _o.setName(_oName);
    int[] _oInventory = new int[inventoryLength()];
    for (int _j = 0; _j < inventoryLength(); ++_j) {_oInventory[_j] = inventory(_j);}
    _o.setInventory(_oInventory);
    int _oColor = color();
    _o.setColor(_oColor);
    MyGame.Example.AnyUnion _oTest = new MyGame.Example.AnyUnion();
    byte _oTestType = testType();
    _oTest.setType(_oTestType);
    Table _oTestValue;
    switch (_oTestType) {
      case MyGame.Example.Any.Monster:
        _oTestValue = test(new MyGame.Example.Monster());
        _oTest.setValue(_oTestValue != null ? ((MyGame.Example.Monster) _oTestValue).unpack() : null);
        break;
      case MyGame.Example.Any.TestSimpleTableWithEnum:
        _oTestValue = test(new MyGame.Example.TestSimpleTableWithEnum());
        _oTest.setValue(_oTestValue != null ? ((MyGame.Example.TestSimpleTableWithEnum) _oTestValue).unpack() : null);
        break;
      case MyGame.Example.Any.MyGame_Example2_Monster:
        _oTestValue = test(new MyGame.Example2.Monster());
        _oTest.setValue(_oTestValue != null ? ((MyGame.Example2.Monster) _oTestValue).unpack() : null);
        break;
      default: break;
    }
    _o.setTest(_oTest);
    MyGame.Example.TestT[] _oTest4 = new MyGame.Example.TestT[test4Length()];
    for (int _j = 0; _j < test4Length(); ++_j) {_oTest4[_j] = (test4(_j) != null ? test4(_j).unpack() : null);}
    _o.setTest4(_oTest4);
    String[] _oTestarrayofstring = new String[testarrayofstringLength()];
    for (int _j = 0; _j < testarrayofstringLength(); ++_j) {_oTestarrayofstring[_j] = testarrayofstring(_j);}
    _o.setTestarrayofstring(_oTestarrayofstring);
    MyGame.Example.MonsterT[] _oTestarrayoftables = new MyGame.Example.MonsterT[testarrayoftablesLength()];
    for (int _j = 0; _j < testarrayoftablesLength(); ++_j) {_oTestarrayoftables[_j] = (testarrayoftables(_j) != null ? testarrayoftables(_j).unpack() : null);}
    _o.setTestarrayoftables(_oTestarrayoftables);
    if (enemy() != null) _o.setEnemy(enemy().unpack());
    else _o.setEnemy(null);
    int[] _oTestnestedflatbuffer = new int[testnestedflatbufferLength()];
    for (int _j = 0; _j < testnestedflatbufferLength(); ++_j) {_oTestnestedflatbuffer[_j] = testnestedflatbuffer(_j);}
    _o.setTestnestedflatbuffer(_oTestnestedflatbuffer);
    if (testempty() != null) _o.setTestempty(testempty().unpack());
    else _o.setTestempty(null);
    boolean _oTestbool = testbool();
    _o.setTestbool(_oTestbool);
    int _oTesthashs32Fnv1 = testhashs32Fnv1();
    _o.setTesthashs32Fnv1(_oTesthashs32Fnv1);
    long _oTesthashu32Fnv1 = testhashu32Fnv1();
    _o.setTesthashu32Fnv1(_oTesthashu32Fnv1);
    long _oTesthashs64Fnv1 = testhashs64Fnv1();
    _o.setTesthashs64Fnv1(_oTesthashs64Fnv1);
    long _oTesthashu64Fnv1 = testhashu64Fnv1();
    _o.setTesthashu64Fnv1(_oTesthashu64Fnv1);
    int _oTesthashs32Fnv1a = testhashs32Fnv1a();
    _o.setTesthashs32Fnv1a(_oTesthashs32Fnv1a);
    long _oTesthashu32Fnv1a = testhashu32Fnv1a();
    _o.setTesthashu32Fnv1a(_oTesthashu32Fnv1a);
    long _oTesthashs64Fnv1a = testhashs64Fnv1a();
    _o.setTesthashs64Fnv1a(_oTesthashs64Fnv1a);
    long _oTesthashu64Fnv1a = testhashu64Fnv1a();
    _o.setTesthashu64Fnv1a(_oTesthashu64Fnv1a);
    boolean[] _oTestarrayofbools = new boolean[testarrayofboolsLength()];
    for (int _j = 0; _j < testarrayofboolsLength(); ++_j) {_oTestarrayofbools[_j] = testarrayofbools(_j);}
    _o.setTestarrayofbools(_oTestarrayofbools);
    float _oTestf = testf();
    _o.setTestf(_oTestf);
    float _oTestf2 = testf2();
    _o.setTestf2(_oTestf2);
    float _oTestf3 = testf3();
    _o.setTestf3(_oTestf3);
    String[] _oTestarrayofstring2 = new String[testarrayofstring2Length()];
    for (int _j = 0; _j < testarrayofstring2Length(); ++_j) {_oTestarrayofstring2[_j] = testarrayofstring2(_j);}
    _o.setTestarrayofstring2(_oTestarrayofstring2);
    MyGame.Example.AbilityT[] _oTestarrayofsortedstruct = new MyGame.Example.AbilityT[testarrayofsortedstructLength()];
    for (int _j = 0; _j < testarrayofsortedstructLength(); ++_j) {_oTestarrayofsortedstruct[_j] = (testarrayofsortedstruct(_j) != null ? testarrayofsortedstruct(_j).unpack() : null);}
    _o.setTestarrayofsortedstruct(_oTestarrayofsortedstruct);
    int[] _oFlex = new int[flexLength()];
    for (int _j = 0; _j < flexLength(); ++_j) {_oFlex[_j] = flex(_j);}
    _o.setFlex(_oFlex);
    MyGame.Example.TestT[] _oTest5 = new MyGame.Example.TestT[test5Length()];
    for (int _j = 0; _j < test5Length(); ++_j) {_oTest5[_j] = (test5(_j) != null ? test5(_j).unpack() : null);}
    _o.setTest5(_oTest5);
    long[] _oVectorOfLongs = new long[vectorOfLongsLength()];
    for (int _j = 0; _j < vectorOfLongsLength(); ++_j) {_oVectorOfLongs[_j] = vectorOfLongs(_j);}
    _o.setVectorOfLongs(_oVectorOfLongs);
    double[] _oVectorOfDoubles = new double[vectorOfDoublesLength()];
    for (int _j = 0; _j < vectorOfDoublesLength(); ++_j) {_oVectorOfDoubles[_j] = vectorOfDoubles(_j);}
    _o.setVectorOfDoubles(_oVectorOfDoubles);
    if (parentNamespaceTest() != null) _o.setParentNamespaceTest(parentNamespaceTest().unpack());
    else _o.setParentNamespaceTest(null);
    MyGame.Example.ReferrableT[] _oVectorOfReferrables = new MyGame.Example.ReferrableT[vectorOfReferrablesLength()];
    for (int _j = 0; _j < vectorOfReferrablesLength(); ++_j) {_oVectorOfReferrables[_j] = (vectorOfReferrables(_j) != null ? vectorOfReferrables(_j).unpack() : null);}
    _o.setVectorOfReferrables(_oVectorOfReferrables);
    long _oSingleWeakReference = singleWeakReference();
    _o.setSingleWeakReference(_oSingleWeakReference);
    long[] _oVectorOfWeakReferences = new long[vectorOfWeakReferencesLength()];
    for (int _j = 0; _j < vectorOfWeakReferencesLength(); ++_j) {_oVectorOfWeakReferences[_j] = vectorOfWeakReferences(_j);}
    _o.setVectorOfWeakReferences(_oVectorOfWeakReferences);
    MyGame.Example.ReferrableT[] _oVectorOfStrongReferrables = new MyGame.Example.ReferrableT[vectorOfStrongReferrablesLength()];
    for (int _j = 0; _j < vectorOfStrongReferrablesLength(); ++_j) {_oVectorOfStrongReferrables[_j] = (vectorOfStrongReferrables(_j) != null ? vectorOfStrongReferrables(_j).unpack() : null);}
    _o.setVectorOfStrongReferrables(_oVectorOfStrongReferrables);
    long _oCoOwningReference = coOwningReference();
    _o.setCoOwningReference(_oCoOwningReference);
    long[] _oVectorOfCoOwningReferences = new long[vectorOfCoOwningReferencesLength()];
    for (int _j = 0; _j < vectorOfCoOwningReferencesLength(); ++_j) {_oVectorOfCoOwningReferences[_j] = vectorOfCoOwningReferences(_j);}
    _o.setVectorOfCoOwningReferences(_oVectorOfCoOwningReferences);
    long _oNonOwningReference = nonOwningReference();
    _o.setNonOwningReference(_oNonOwningReference);
    long[] _oVectorOfNonOwningReferences = new long[vectorOfNonOwningReferencesLength()];
    for (int _j = 0; _j < vectorOfNonOwningReferencesLength(); ++_j) {_oVectorOfNonOwningReferences[_j] = vectorOfNonOwningReferences(_j);}
    _o.setVectorOfNonOwningReferences(_oVectorOfNonOwningReferences);
    MyGame.Example.AnyUniqueAliasesUnion _oAnyUnique = new MyGame.Example.AnyUniqueAliasesUnion();
    byte _oAnyUniqueType = anyUniqueType();
    _oAnyUnique.setType(_oAnyUniqueType);
    Table _oAnyUniqueValue;
    switch (_oAnyUniqueType) {
      case MyGame.Example.AnyUniqueAliases.M:
        _oAnyUniqueValue = anyUnique(new MyGame.Example.Monster());
        _oAnyUnique.setValue(_oAnyUniqueValue != null ? ((MyGame.Example.Monster) _oAnyUniqueValue).unpack() : null);
        break;
      case MyGame.Example.AnyUniqueAliases.TS:
        _oAnyUniqueValue = anyUnique(new MyGame.Example.TestSimpleTableWithEnum());
        _oAnyUnique.setValue(_oAnyUniqueValue != null ? ((MyGame.Example.TestSimpleTableWithEnum) _oAnyUniqueValue).unpack() : null);
        break;
      case MyGame.Example.AnyUniqueAliases.M2:
        _oAnyUniqueValue = anyUnique(new MyGame.Example2.Monster());
        _oAnyUnique.setValue(_oAnyUniqueValue != null ? ((MyGame.Example2.Monster) _oAnyUniqueValue).unpack() : null);
        break;
      default: break;
    }
    _o.setAnyUnique(_oAnyUnique);
    MyGame.Example.AnyAmbiguousAliasesUnion _oAnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion();
    byte _oAnyAmbiguousType = anyAmbiguousType();
    _oAnyAmbiguous.setType(_oAnyAmbiguousType);
    Table _oAnyAmbiguousValue;
    switch (_oAnyAmbiguousType) {
      case MyGame.Example.AnyAmbiguousAliases.M1:
        _oAnyAmbiguousValue = anyAmbiguous(new MyGame.Example.Monster());
        _oAnyAmbiguous.setValue(_oAnyAmbiguousValue != null ? ((MyGame.Example.Monster) _oAnyAmbiguousValue).unpack() : null);
        break;
      case MyGame.Example.AnyAmbiguousAliases.M2:
        _oAnyAmbiguousValue = anyAmbiguous(new MyGame.Example.Monster());
        _oAnyAmbiguous.setValue(_oAnyAmbiguousValue != null ? ((MyGame.Example.Monster) _oAnyAmbiguousValue).unpack() : null);
        break;
      case MyGame.Example.AnyAmbiguousAliases.M3:
        _oAnyAmbiguousValue = anyAmbiguous(new MyGame.Example.Monster());
        _oAnyAmbiguous.setValue(_oAnyAmbiguousValue != null ? ((MyGame.Example.Monster) _oAnyAmbiguousValue).unpack() : null);
        break;
      default: break;
    }
    _o.setAnyAmbiguous(_oAnyAmbiguous);
    int[] _oVectorOfEnums = new int[vectorOfEnumsLength()];
    for (int _j = 0; _j < vectorOfEnumsLength(); ++_j) {_oVectorOfEnums[_j] = vectorOfEnums(_j);}
    _o.setVectorOfEnums(_oVectorOfEnums);
    byte _oSignedEnum = signedEnum();
    _o.setSignedEnum(_oSignedEnum);
    int[] _oTestrequirednestedflatbuffer = new int[testrequirednestedflatbufferLength()];
    for (int _j = 0; _j < testrequirednestedflatbufferLength(); ++_j) {_oTestrequirednestedflatbuffer[_j] = testrequirednestedflatbuffer(_j);}
    _o.setTestrequirednestedflatbuffer(_oTestrequirednestedflatbuffer);
    MyGame.Example.StatT[] _oScalarKeySortedTables = new MyGame.Example.StatT[scalarKeySortedTablesLength()];
    for (int _j = 0; _j < scalarKeySortedTablesLength(); ++_j) {_oScalarKeySortedTables[_j] = (scalarKeySortedTables(_j) != null ? scalarKeySortedTables(_j).unpack() : null);}
    _o.setScalarKeySortedTables(_oScalarKeySortedTables);
    if (nativeInline() != null) nativeInline().unpackTo(_o.getNativeInline());
    else _o.setNativeInline(null);
    long _oLongEnumNonEnumDefault = longEnumNonEnumDefault();
    _o.setLongEnumNonEnumDefault(_oLongEnumNonEnumDefault);
    long _oLongEnumNormalDefault = longEnumNormalDefault();
    _o.setLongEnumNormalDefault(_oLongEnumNormalDefault);
  }
  public static int pack(FlatBufferBuilder builder, MonsterT _o) {
    if (_o == null) return 0;
    int _name = _o.getName() == null ? 0 : builder.createString(_o.getName());
    int _inventory = 0;
    if (_o.getInventory() != null) {
      byte[] __inventory = new byte[_o.getInventory().length];
      int _j = 0;
      for (int _e : _o.getInventory()) { __inventory[_j] = (byte) _e; _j++;}
      _inventory = createInventoryVector(builder, __inventory);
    }
    byte _testType = _o.getTest() == null ? MyGame.Example.Any.NONE : _o.getTest().getType();
    int _test = _o.getTest() == null ? 0 : MyGame.Example.AnyUnion.pack(builder, _o.getTest());
    int _test4 = 0;
    MyGame.Example.TestT[] _oTest4 = _o.getTest4();
    if (_oTest4 != null) {
      int _unused_offset = 0;
      startTest4Vector(builder, _oTest4.length);
      for (int _j = _oTest4.length - 1; _j >=0; _j--) { _unused_offset = MyGame.Example.Test.pack(builder, _oTest4[_j]);}
      _test4 = builder.endVector();
    }
    int _testarrayofstring = 0;
    if (_o.getTestarrayofstring() != null) {
      int[] __testarrayofstring = new int[_o.getTestarrayofstring().length];
      int _j = 0;
      for (String _e : _o.getTestarrayofstring()) { __testarrayofstring[_j] = builder.createString(_e); _j++;}
      _testarrayofstring = createTestarrayofstringVector(builder, __testarrayofstring);
    }
    int _testarrayoftables = 0;
    if (_o.getTestarrayoftables() != null) {
      int[] __testarrayoftables = new int[_o.getTestarrayoftables().length];
      int _j = 0;
      for (MyGame.Example.MonsterT _e : _o.getTestarrayoftables()) { __testarrayoftables[_j] = MyGame.Example.Monster.pack(builder, _e); _j++;}
      _testarrayoftables = createTestarrayoftablesVector(builder, __testarrayoftables);
    }
    int _enemy = _o.getEnemy() == null ? 0 : MyGame.Example.Monster.pack(builder, _o.getEnemy());
    int _testnestedflatbuffer = 0;
    if (_o.getTestnestedflatbuffer() != null) {
      byte[] __testnestedflatbuffer = new byte[_o.getTestnestedflatbuffer().length];
      int _j = 0;
      for (int _e : _o.getTestnestedflatbuffer()) { __testnestedflatbuffer[_j] = (byte) _e; _j++;}
      _testnestedflatbuffer = createTestnestedflatbufferVector(builder, __testnestedflatbuffer);
    }
    int _testempty = _o.getTestempty() == null ? 0 : MyGame.Example.Stat.pack(builder, _o.getTestempty());
    int _testarrayofbools = 0;
    if (_o.getTestarrayofbools() != null) {
      _testarrayofbools = createTestarrayofboolsVector(builder, _o.getTestarrayofbools());
    }
    int _testarrayofstring2 = 0;
    if (_o.getTestarrayofstring2() != null) {
      int[] __testarrayofstring2 = new int[_o.getTestarrayofstring2().length];
      int _j = 0;
      for (String _e : _o.getTestarrayofstring2()) { __testarrayofstring2[_j] = builder.createString(_e); _j++;}
      _testarrayofstring2 = createTestarrayofstring2Vector(builder, __testarrayofstring2);
    }
    int _testarrayofsortedstruct = 0;
    MyGame.Example.AbilityT[] _oTestarrayofsortedstruct = _o.getTestarrayofsortedstruct();
    if (_oTestarrayofsortedstruct != null) {
      int _unused_offset = 0;
      startTestarrayofsortedstructVector(builder, _oTestarrayofsortedstruct.length);
      for (int _j = _oTestarrayofsortedstruct.length - 1; _j >=0; _j--) { _unused_offset = MyGame.Example.Ability.pack(builder, _oTestarrayofsortedstruct[_j]);}
      _testarrayofsortedstruct = builder.endVector();
    }
    int _flex = 0;
    if (_o.getFlex() != null) {
      byte[] __flex = new byte[_o.getFlex().length];
      int _j = 0;
      for (int _e : _o.getFlex()) { __flex[_j] = (byte) _e; _j++;}
      _flex = createFlexVector(builder, __flex);
    }
    int _test5 = 0;
    MyGame.Example.TestT[] _oTest5 = _o.getTest5();
    if (_oTest5 != null) {
      int _unused_offset = 0;
      startTest5Vector(builder, _oTest5.length);
      for (int _j = _oTest5.length - 1; _j >=0; _j--) { _unused_offset = MyGame.Example.Test.pack(builder, _oTest5[_j]);}
      _test5 = builder.endVector();
    }
    int _vectorOfLongs = 0;
    if (_o.getVectorOfLongs() != null) {
      _vectorOfLongs = createVectorOfLongsVector(builder, _o.getVectorOfLongs());
    }
    int _vectorOfDoubles = 0;
    if (_o.getVectorOfDoubles() != null) {
      _vectorOfDoubles = createVectorOfDoublesVector(builder, _o.getVectorOfDoubles());
    }
    int _parentNamespaceTest = _o.getParentNamespaceTest() == null ? 0 : MyGame.InParentNamespace.pack(builder, _o.getParentNamespaceTest());
    int _vectorOfReferrables = 0;
    if (_o.getVectorOfReferrables() != null) {
      int[] __vectorOfReferrables = new int[_o.getVectorOfReferrables().length];
      int _j = 0;
      for (MyGame.Example.ReferrableT _e : _o.getVectorOfReferrables()) { __vectorOfReferrables[_j] = MyGame.Example.Referrable.pack(builder, _e); _j++;}
      _vectorOfReferrables = createVectorOfReferrablesVector(builder, __vectorOfReferrables);
    }
    int _vectorOfWeakReferences = 0;
    if (_o.getVectorOfWeakReferences() != null) {
      _vectorOfWeakReferences = createVectorOfWeakReferencesVector(builder, _o.getVectorOfWeakReferences());
    }
    int _vectorOfStrongReferrables = 0;
    if (_o.getVectorOfStrongReferrables() != null) {
      int[] __vectorOfStrongReferrables = new int[_o.getVectorOfStrongReferrables().length];
      int _j = 0;
      for (MyGame.Example.ReferrableT _e : _o.getVectorOfStrongReferrables()) { __vectorOfStrongReferrables[_j] = MyGame.Example.Referrable.pack(builder, _e); _j++;}
      _vectorOfStrongReferrables = createVectorOfStrongReferrablesVector(builder, __vectorOfStrongReferrables);
    }
    int _vectorOfCoOwningReferences = 0;
    if (_o.getVectorOfCoOwningReferences() != null) {
      _vectorOfCoOwningReferences = createVectorOfCoOwningReferencesVector(builder, _o.getVectorOfCoOwningReferences());
    }
    int _vectorOfNonOwningReferences = 0;
    if (_o.getVectorOfNonOwningReferences() != null) {
      _vectorOfNonOwningReferences = createVectorOfNonOwningReferencesVector(builder, _o.getVectorOfNonOwningReferences());
    }
    byte _anyUniqueType = _o.getAnyUnique() == null ? MyGame.Example.AnyUniqueAliases.NONE : _o.getAnyUnique().getType();
    int _anyUnique = _o.getAnyUnique() == null ? 0 : MyGame.Example.AnyUniqueAliasesUnion.pack(builder, _o.getAnyUnique());
    byte _anyAmbiguousType = _o.getAnyAmbiguous() == null ? MyGame.Example.AnyAmbiguousAliases.NONE : _o.getAnyAmbiguous().getType();
    int _anyAmbiguous = _o.getAnyAmbiguous() == null ? 0 : MyGame.Example.AnyAmbiguousAliasesUnion.pack(builder, _o.getAnyAmbiguous());
    int _vectorOfEnums = 0;
    if (_o.getVectorOfEnums() != null) {
      byte[] __vectorOfEnums = new byte[_o.getVectorOfEnums().length];
      int _j = 0;
      for (int _e : _o.getVectorOfEnums()) { __vectorOfEnums[_j] = (byte) _e; _j++;}
      _vectorOfEnums = createVectorOfEnumsVector(builder, __vectorOfEnums);
    }
    int _testrequirednestedflatbuffer = 0;
    if (_o.getTestrequirednestedflatbuffer() != null) {
      byte[] __testrequirednestedflatbuffer = new byte[_o.getTestrequirednestedflatbuffer().length];
      int _j = 0;
      for (int _e : _o.getTestrequirednestedflatbuffer()) { __testrequirednestedflatbuffer[_j] = (byte) _e; _j++;}
      _testrequirednestedflatbuffer = createTestrequirednestedflatbufferVector(builder, __testrequirednestedflatbuffer);
    }
    int _scalarKeySortedTables = 0;
    if (_o.getScalarKeySortedTables() != null) {
      int[] __scalarKeySortedTables = new int[_o.getScalarKeySortedTables().length];
      int _j = 0;
      for (MyGame.Example.StatT _e : _o.getScalarKeySortedTables()) { __scalarKeySortedTables[_j] = MyGame.Example.Stat.pack(builder, _e); _j++;}
      _scalarKeySortedTables = createScalarKeySortedTablesVector(builder, __scalarKeySortedTables);
    }
    startMonster(builder);
    addPos(builder, MyGame.Example.Vec3.pack(builder, _o.getPos()));
    addMana(builder, _o.getMana());
    addHp(builder, _o.getHp());
    addName(builder, _name);
    addInventory(builder, _inventory);
    addColor(builder, _o.getColor());
    addTestType(builder, _testType);
    addTest(builder, _test);
    addTest4(builder, _test4);
    addTestarrayofstring(builder, _testarrayofstring);
    addTestarrayoftables(builder, _testarrayoftables);
    addEnemy(builder, _enemy);
    addTestnestedflatbuffer(builder, _testnestedflatbuffer);
    addTestempty(builder, _testempty);
    addTestbool(builder, _o.getTestbool());
    addTesthashs32Fnv1(builder, _o.getTesthashs32Fnv1());
    addTesthashu32Fnv1(builder, _o.getTesthashu32Fnv1());
    addTesthashs64Fnv1(builder, _o.getTesthashs64Fnv1());
    addTesthashu64Fnv1(builder, _o.getTesthashu64Fnv1());
    addTesthashs32Fnv1a(builder, _o.getTesthashs32Fnv1a());
    addTesthashu32Fnv1a(builder, _o.getTesthashu32Fnv1a());
    addTesthashs64Fnv1a(builder, _o.getTesthashs64Fnv1a());
    addTesthashu64Fnv1a(builder, _o.getTesthashu64Fnv1a());
    addTestarrayofbools(builder, _testarrayofbools);
    addTestf(builder, _o.getTestf());
    addTestf2(builder, _o.getTestf2());
    addTestf3(builder, _o.getTestf3());
    addTestarrayofstring2(builder, _testarrayofstring2);
    addTestarrayofsortedstruct(builder, _testarrayofsortedstruct);
    addFlex(builder, _flex);
    addTest5(builder, _test5);
    addVectorOfLongs(builder, _vectorOfLongs);
    addVectorOfDoubles(builder, _vectorOfDoubles);
    addParentNamespaceTest(builder, _parentNamespaceTest);
    addVectorOfReferrables(builder, _vectorOfReferrables);
    addSingleWeakReference(builder, _o.getSingleWeakReference());
    addVectorOfWeakReferences(builder, _vectorOfWeakReferences);
    addVectorOfStrongReferrables(builder, _vectorOfStrongReferrables);
    addCoOwningReference(builder, _o.getCoOwningReference());
    addVectorOfCoOwningReferences(builder, _vectorOfCoOwningReferences);
    addNonOwningReference(builder, _o.getNonOwningReference());
    addVectorOfNonOwningReferences(builder, _vectorOfNonOwningReferences);
    addAnyUniqueType(builder, _anyUniqueType);
    addAnyUnique(builder, _anyUnique);
    addAnyAmbiguousType(builder, _anyAmbiguousType);
    addAnyAmbiguous(builder, _anyAmbiguous);
    addVectorOfEnums(builder, _vectorOfEnums);
    addSignedEnum(builder, _o.getSignedEnum());
    addTestrequirednestedflatbuffer(builder, _testrequirednestedflatbuffer);
    addScalarKeySortedTables(builder, _scalarKeySortedTables);
    addNativeInline(builder, MyGame.Example.Test.pack(builder, _o.getNativeInline()));
    addLongEnumNonEnumDefault(builder, _o.getLongEnumNonEnumDefault());
    addLongEnumNormalDefault(builder, _o.getLongEnumNormalDefault());
    return endMonster(builder);
  }
}

