// 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.IntVector;
import com.google.flatbuffers.LongVector;
import com.google.flatbuffers.ShortVector;
import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.Struct;
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 com.google.flatbuffers.Table {
  public static void ValidateVersion() { Constants.FLATBUFFERS_25_9_23(); }
  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 com.google.flatbuffers.Table test(com.google.flatbuffers.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 com.google.flatbuffers.Table anyUnique(com.google.flatbuffers.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 com.google.flatbuffers.Table anyAmbiguous(com.google.flatbuffers.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);
    com.google.flatbuffers.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);
    com.google.flatbuffers.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);
    com.google.flatbuffers.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);
  }
}

