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

package MyGame.Example;

import com.google.flatbuffers.BaseVector;
import com.google.flatbuffers.BooleanVector;
import com.google.flatbuffers.ByteVector;
import com.google.flatbuffers.Constants;
import com.google.flatbuffers.DoubleVector;
import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.FloatVector;
import com.google.flatbuffers.LongVector;
import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.Struct;
import com.google.flatbuffers.Table;
import com.google.flatbuffers.UnionVector;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * an example documentation comment: "monster object"
 */
@SuppressWarnings("unused")
public final class Monster extends Table {
  public static void ValidateVersion() { Constants.FLATBUFFERS_22_12_06(); }
  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 float nanDefault() { int o = __offset(112); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
  public boolean mutateNanDefault(float nan_default) { int o = __offset(112); if (o != 0) { bb.putFloat(o + bb_pos, nan_default); return true; } else { return false; } }
  public float infDefault() { int o = __offset(114); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
  public boolean mutateInfDefault(float inf_default) { int o = __offset(114); if (o != 0) { bb.putFloat(o + bb_pos, inf_default); return true; } else { return false; } }
  public float positiveInfDefault() { int o = __offset(116); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
  public boolean mutatePositiveInfDefault(float positive_inf_default) { int o = __offset(116); if (o != 0) { bb.putFloat(o + bb_pos, positive_inf_default); return true; } else { return false; } }
  public float infinityDefault() { int o = __offset(118); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
  public boolean mutateInfinityDefault(float infinity_default) { int o = __offset(118); if (o != 0) { bb.putFloat(o + bb_pos, infinity_default); return true; } else { return false; } }
  public float positiveInfinityDefault() { int o = __offset(120); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
  public boolean mutatePositiveInfinityDefault(float positive_infinity_default) { int o = __offset(120); if (o != 0) { bb.putFloat(o + bb_pos, positive_infinity_default); return true; } else { return false; } }
  public float negativeInfDefault() { int o = __offset(122); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
  public boolean mutateNegativeInfDefault(float negative_inf_default) { int o = __offset(122); if (o != 0) { bb.putFloat(o + bb_pos, negative_inf_default); return true; } else { return false; } }
  public float negativeInfinityDefault() { int o = __offset(124); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
  public boolean mutateNegativeInfinityDefault(float negative_infinity_default) { int o = __offset(124); if (o != 0) { bb.putFloat(o + bb_pos, negative_infinity_default); return true; } else { return false; } }
  public double doubleInfDefault() { int o = __offset(126); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
  public boolean mutateDoubleInfDefault(double double_inf_default) { int o = __offset(126); if (o != 0) { bb.putDouble(o + bb_pos, double_inf_default); return true; } else { return false; } }

  public static void startMonster(FlatBufferBuilder builder) { builder.startTable(62); }
  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 void addNanDefault(FlatBufferBuilder builder, float nanDefault) { builder.addFloat(54, nanDefault, Float.NaN); }
  public static void addInfDefault(FlatBufferBuilder builder, float infDefault) { builder.addFloat(55, infDefault, Float.POSITIVE_INFINITY); }
  public static void addPositiveInfDefault(FlatBufferBuilder builder, float positiveInfDefault) { builder.addFloat(56, positiveInfDefault, Float.POSITIVE_INFINITY); }
  public static void addInfinityDefault(FlatBufferBuilder builder, float infinityDefault) { builder.addFloat(57, infinityDefault, Float.POSITIVE_INFINITY); }
  public static void addPositiveInfinityDefault(FlatBufferBuilder builder, float positiveInfinityDefault) { builder.addFloat(58, positiveInfinityDefault, Float.POSITIVE_INFINITY); }
  public static void addNegativeInfDefault(FlatBufferBuilder builder, float negativeInfDefault) { builder.addFloat(59, negativeInfDefault, Float.NEGATIVE_INFINITY); }
  public static void addNegativeInfinityDefault(FlatBufferBuilder builder, float negativeInfinityDefault) { builder.addFloat(60, negativeInfinityDefault, Float.NEGATIVE_INFINITY); }
  public static void addDoubleInfDefault(FlatBufferBuilder builder, double doubleInfDefault) { builder.addDouble(61, doubleInfDefault, Double.POSITIVE_INFINITY); }
  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);
    float _oNanDefault = nanDefault();
    _o.setNanDefault(_oNanDefault);
    float _oInfDefault = infDefault();
    _o.setInfDefault(_oInfDefault);
    float _oPositiveInfDefault = positiveInfDefault();
    _o.setPositiveInfDefault(_oPositiveInfDefault);
    float _oInfinityDefault = infinityDefault();
    _o.setInfinityDefault(_oInfinityDefault);
    float _oPositiveInfinityDefault = positiveInfinityDefault();
    _o.setPositiveInfinityDefault(_oPositiveInfinityDefault);
    float _oNegativeInfDefault = negativeInfDefault();
    _o.setNegativeInfDefault(_oNegativeInfDefault);
    float _oNegativeInfinityDefault = negativeInfinityDefault();
    _o.setNegativeInfinityDefault(_oNegativeInfinityDefault);
    double _oDoubleInfDefault = doubleInfDefault();
    _o.setDoubleInfDefault(_oDoubleInfDefault);
  }
  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());
    addNanDefault(builder, _o.getNanDefault());
    addInfDefault(builder, _o.getInfDefault());
    addPositiveInfDefault(builder, _o.getPositiveInfDefault());
    addInfinityDefault(builder, _o.getInfinityDefault());
    addPositiveInfinityDefault(builder, _o.getPositiveInfinityDefault());
    addNegativeInfDefault(builder, _o.getNegativeInfDefault());
    addNegativeInfinityDefault(builder, _o.getNegativeInfinityDefault());
    addDoubleInfDefault(builder, _o.getDoubleInfDefault());
    return endMonster(builder);
  }
}

