// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace MyGame.Example
{

using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;

/// an example documentation comment: "monster object"
public struct Monster : IFlatbufferObject
{
  private Table __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_24_3_7(); }
  public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
  public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
  public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
  public static bool VerifyMonster(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("MONS", false, MonsterVerify.Verify); }
  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
  public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public MyGame.Example.Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Vec3?)(new MyGame.Example.Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
  public short Mana { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)150; } }
  public bool MutateMana(short mana) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, mana); return true; } else { return false; } }
  public short Hp { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)100; } }
  public bool MutateHp(short hp) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, hp); return true; } else { return false; } }
  public string Name { get { int o = __p.__offset(10); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
  public Span<byte> GetNameBytes() { return __p.__vector_as_span<byte>(10, 1); }
#else
  public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
#endif
  public byte[] GetNameArray() { return __p.__vector_as_array<byte>(10); }
  public byte Inventory(int j) { int o = __p.__offset(14); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
  public int InventoryLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<byte> GetInventoryBytes() { return __p.__vector_as_span<byte>(14, 1); }
#else
  public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
#endif
  public byte[] GetInventoryArray() { return __p.__vector_as_array<byte>(14); }
  public bool MutateInventory(int j, byte inventory) { int o = __p.__offset(14); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, inventory); return true; } else { return false; } }
  public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } }
  public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
  public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } }
  public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
  public MyGame.Example.Monster TestAsMonster() { return Test<MyGame.Example.Monster>().Value; }
  internal MyGame.Example.TestSimpleTableWithEnum TestAsTestSimpleTableWithEnum() { return Test<MyGame.Example.TestSimpleTableWithEnum>().Value; }
  public MyGame.Example2.Monster TestAsMyGame_Example2_Monster() { return Test<MyGame.Example2.Monster>().Value; }
  public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
  public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
  public string Testarrayofstring(int j) { int o = __p.__offset(24); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
  public int TestarrayofstringLength { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
  /// an example documentation comment: this will end up in the generated code
  /// multiline too
  public MyGame.Example.Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
  public int TestarrayoftablesLength { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
  public MyGame.Example.Monster? TestarrayoftablesByKey(string key) { int o = __p.__offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
  public MyGame.Example.Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
  public byte Testnestedflatbuffer(int j) { int o = __p.__offset(30); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
  public int TestnestedflatbufferLength { get { int o = __p.__offset(30); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<byte> GetTestnestedflatbufferBytes() { return __p.__vector_as_span<byte>(30, 1); }
#else
  public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
#endif
  public byte[] GetTestnestedflatbufferArray() { return __p.__vector_as_array<byte>(30); }
  public MyGame.Example.Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
  public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __p.__offset(30); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
  public MyGame.Example.Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
  public bool Testbool { get { int o = __p.__offset(34); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
  public bool MutateTestbool(bool testbool) { int o = __p.__offset(34); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
  public int Testhashs32Fnv1 { get { int o = __p.__offset(36); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
  public bool MutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __p.__offset(36); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1); return true; } else { return false; } }
  public uint Testhashu32Fnv1 { get { int o = __p.__offset(38); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
  public bool MutateTesthashu32Fnv1(uint testhashu32_fnv1) { int o = __p.__offset(38); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1); return true; } else { return false; } }
  public long Testhashs64Fnv1 { get { int o = __p.__offset(40); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
  public bool MutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __p.__offset(40); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1); return true; } else { return false; } }
  public ulong Testhashu64Fnv1 { get { int o = __p.__offset(42); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
  public bool MutateTesthashu64Fnv1(ulong testhashu64_fnv1) { int o = __p.__offset(42); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1); return true; } else { return false; } }
  public int Testhashs32Fnv1a { get { int o = __p.__offset(44); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
  public bool MutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __p.__offset(44); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
  public uint Testhashu32Fnv1a { get { int o = __p.__offset(46); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
  public bool MutateTesthashu32Fnv1a(uint testhashu32_fnv1a) { int o = __p.__offset(46); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1a); return true; } else { return false; } }
  public long Testhashs64Fnv1a { get { int o = __p.__offset(48); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
  public bool MutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __p.__offset(48); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
  public ulong Testhashu64Fnv1a { get { int o = __p.__offset(50); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
  public bool MutateTesthashu64Fnv1a(ulong testhashu64_fnv1a) { int o = __p.__offset(50); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
  public bool Testarrayofbools(int j) { int o = __p.__offset(52); return o != 0 ? 0!=__p.bb.Get(__p.__vector(o) + j * 1) : false; }
  public int TestarrayofboolsLength { get { int o = __p.__offset(52); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<bool> GetTestarrayofboolsBytes() { return __p.__vector_as_span<bool>(52, 1); }
#else
  public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
#endif
  public bool[] GetTestarrayofboolsArray() { return __p.__vector_as_array<bool>(52); }
  public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __p.__offset(52); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
  public float Testf { get { int o = __p.__offset(54); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.14159f; } }
  public bool MutateTestf(float testf) { int o = __p.__offset(54); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf); return true; } else { return false; } }
  public float Testf2 { get { int o = __p.__offset(56); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.0f; } }
  public bool MutateTestf2(float testf2) { int o = __p.__offset(56); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf2); return true; } else { return false; } }
  public float Testf3 { get { int o = __p.__offset(58); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
  public bool MutateTestf3(float testf3) { int o = __p.__offset(58); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf3); return true; } else { return false; } }
  public string Testarrayofstring2(int j) { int o = __p.__offset(60); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
  public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
  public MyGame.Example.Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (MyGame.Example.Ability?)(new MyGame.Example.Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
  public int TestarrayofsortedstructLength { get { int o = __p.__offset(62); return o != 0 ? __p.__vector_len(o) : 0; } }
  public byte Flex(int j) { int o = __p.__offset(64); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
  public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<byte> GetFlexBytes() { return __p.__vector_as_span<byte>(64, 1); }
#else
  public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
#endif
  public byte[] GetFlexArray() { return __p.__vector_as_array<byte>(64); }
  public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
  public MyGame.Example.Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
  public int Test5Length { get { int o = __p.__offset(66); return o != 0 ? __p.__vector_len(o) : 0; } }
  public long VectorOfLongs(int j) { int o = __p.__offset(68); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
  public int VectorOfLongsLength { get { int o = __p.__offset(68); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<long> GetVectorOfLongsBytes() { return __p.__vector_as_span<long>(68, 8); }
#else
  public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
#endif
  public long[] GetVectorOfLongsArray() { return __p.__vector_as_array<long>(68); }
  public bool MutateVectorOfLongs(int j, long vector_of_longs) { int o = __p.__offset(68); if (o != 0) { __p.bb.PutLong(__p.__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
  public double VectorOfDoubles(int j) { int o = __p.__offset(70); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
  public int VectorOfDoublesLength { get { int o = __p.__offset(70); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<double> GetVectorOfDoublesBytes() { return __p.__vector_as_span<double>(70, 8); }
#else
  public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
#endif
  public double[] GetVectorOfDoublesArray() { return __p.__vector_as_array<double>(70); }
  public bool MutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __p.__offset(70); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
  public MyGame.InParentNamespace? ParentNamespaceTest { get { int o = __p.__offset(72); return o != 0 ? (MyGame.InParentNamespace?)(new MyGame.InParentNamespace()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
  public MyGame.Example.Referrable? VectorOfReferrables(int j) { int o = __p.__offset(74); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
  public int VectorOfReferrablesLength { get { int o = __p.__offset(74); return o != 0 ? __p.__vector_len(o) : 0; } }
  public MyGame.Example.Referrable? VectorOfReferrablesByKey(ulong key) { int o = __p.__offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
  public ulong SingleWeakReference { get { int o = __p.__offset(76); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
  public bool MutateSingleWeakReference(ulong single_weak_reference) { int o = __p.__offset(76); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, single_weak_reference); return true; } else { return false; } }
  public ulong VectorOfWeakReferences(int j) { int o = __p.__offset(78); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
  public int VectorOfWeakReferencesLength { get { int o = __p.__offset(78); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<ulong> GetVectorOfWeakReferencesBytes() { return __p.__vector_as_span<ulong>(78, 8); }
#else
  public ArraySegment<byte>? GetVectorOfWeakReferencesBytes() { return __p.__vector_as_arraysegment(78); }
#endif
  public ulong[] GetVectorOfWeakReferencesArray() { return __p.__vector_as_array<ulong>(78); }
  public bool MutateVectorOfWeakReferences(int j, ulong vector_of_weak_references) { int o = __p.__offset(78); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
  public MyGame.Example.Referrable? VectorOfStrongReferrables(int j) { int o = __p.__offset(80); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
  public int VectorOfStrongReferrablesLength { get { int o = __p.__offset(80); return o != 0 ? __p.__vector_len(o) : 0; } }
  public MyGame.Example.Referrable? VectorOfStrongReferrablesByKey(ulong key) { int o = __p.__offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
  public ulong CoOwningReference { get { int o = __p.__offset(82); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
  public bool MutateCoOwningReference(ulong co_owning_reference) { int o = __p.__offset(82); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, co_owning_reference); return true; } else { return false; } }
  public ulong VectorOfCoOwningReferences(int j) { int o = __p.__offset(84); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
  public int VectorOfCoOwningReferencesLength { get { int o = __p.__offset(84); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<ulong> GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_span<ulong>(84, 8); }
#else
  public ArraySegment<byte>? GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_arraysegment(84); }
#endif
  public ulong[] GetVectorOfCoOwningReferencesArray() { return __p.__vector_as_array<ulong>(84); }
  public bool MutateVectorOfCoOwningReferences(int j, ulong vector_of_co_owning_references) { int o = __p.__offset(84); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
  public ulong NonOwningReference { get { int o = __p.__offset(86); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
  public bool MutateNonOwningReference(ulong non_owning_reference) { int o = __p.__offset(86); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, non_owning_reference); return true; } else { return false; } }
  public ulong VectorOfNonOwningReferences(int j) { int o = __p.__offset(88); return o != 0 ? __p.bb.GetUlong(__p.__vector(o) + j * 8) : (ulong)0; }
  public int VectorOfNonOwningReferencesLength { get { int o = __p.__offset(88); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<ulong> GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_span<ulong>(88, 8); }
#else
  public ArraySegment<byte>? GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_arraysegment(88); }
#endif
  public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); }
  public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
  public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } }
  public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
  public MyGame.Example.Monster AnyUniqueAsM() { return AnyUnique<MyGame.Example.Monster>().Value; }
  internal MyGame.Example.TestSimpleTableWithEnum AnyUniqueAsTS() { return AnyUnique<MyGame.Example.TestSimpleTableWithEnum>().Value; }
  public MyGame.Example2.Monster AnyUniqueAsM2() { return AnyUnique<MyGame.Example2.Monster>().Value; }
  public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } }
  public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
  public MyGame.Example.Monster AnyAmbiguousAsM1() { return AnyAmbiguous<MyGame.Example.Monster>().Value; }
  public MyGame.Example.Monster AnyAmbiguousAsM2() { return AnyAmbiguous<MyGame.Example.Monster>().Value; }
  public MyGame.Example.Monster AnyAmbiguousAsM3() { return AnyAmbiguous<MyGame.Example.Monster>().Value; }
  public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; }
  public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<MyGame.Example.Color> GetVectorOfEnumsBytes() { return __p.__vector_as_span<MyGame.Example.Color>(98, 1); }
#else
  public ArraySegment<byte>? GetVectorOfEnumsBytes() { return __p.__vector_as_arraysegment(98); }
#endif
  public MyGame.Example.Color[] GetVectorOfEnumsArray() { int o = __p.__offset(98); if (o == 0) return null; int p = __p.__vector(o); int l = __p.__vector_len(o); MyGame.Example.Color[] a = new MyGame.Example.Color[l]; for (int i = 0; i < l; i++) { a[i] = (MyGame.Example.Color)__p.bb.Get(p + i * 1); } return a; }
  public bool MutateVectorOfEnums(int j, MyGame.Example.Color vector_of_enums) { int o = __p.__offset(98); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
  public MyGame.Example.Race SignedEnum { get { int o = __p.__offset(100); return o != 0 ? (MyGame.Example.Race)__p.bb.GetSbyte(o + __p.bb_pos) : MyGame.Example.Race.None; } }
  public bool MutateSignedEnum(MyGame.Example.Race signed_enum) { int o = __p.__offset(100); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)signed_enum); return true; } else { return false; } }
  public byte Testrequirednestedflatbuffer(int j) { int o = __p.__offset(102); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
  public int TestrequirednestedflatbufferLength { get { int o = __p.__offset(102); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<byte> GetTestrequirednestedflatbufferBytes() { return __p.__vector_as_span<byte>(102, 1); }
#else
  public ArraySegment<byte>? GetTestrequirednestedflatbufferBytes() { return __p.__vector_as_arraysegment(102); }
#endif
  public byte[] GetTestrequirednestedflatbufferArray() { return __p.__vector_as_array<byte>(102); }
  public MyGame.Example.Monster? GetTestrequirednestedflatbufferAsMonster() { int o = __p.__offset(102); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
  public bool MutateTestrequirednestedflatbuffer(int j, byte testrequirednestedflatbuffer) { int o = __p.__offset(102); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testrequirednestedflatbuffer); return true; } else { return false; } }
  public MyGame.Example.Stat? ScalarKeySortedTables(int j) { int o = __p.__offset(104); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
  public int ScalarKeySortedTablesLength { get { int o = __p.__offset(104); return o != 0 ? __p.__vector_len(o) : 0; } }
  public MyGame.Example.Stat? ScalarKeySortedTablesByKey(ushort key) { int o = __p.__offset(104); return o != 0 ? MyGame.Example.Stat.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
  public MyGame.Example.Test? NativeInline { get { int o = __p.__offset(106); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(o + __p.bb_pos, __p.bb) : null; } }
  public MyGame.Example.LongEnum LongEnumNonEnumDefault { get { int o = __p.__offset(108); return o != 0 ? (MyGame.Example.LongEnum)__p.bb.GetUlong(o + __p.bb_pos) : 0; } }
  public bool MutateLongEnumNonEnumDefault(MyGame.Example.LongEnum long_enum_non_enum_default) { int o = __p.__offset(108); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, (ulong)long_enum_non_enum_default); return true; } else { return false; } }
  public MyGame.Example.LongEnum LongEnumNormalDefault { get { int o = __p.__offset(110); return o != 0 ? (MyGame.Example.LongEnum)__p.bb.GetUlong(o + __p.bb_pos) : MyGame.Example.LongEnum.LongOne; } }
  public bool MutateLongEnumNormalDefault(MyGame.Example.LongEnum long_enum_normal_default) { int o = __p.__offset(110); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, (ulong)long_enum_normal_default); return true; } else { return false; } }
  public float NanDefault { get { int o = __p.__offset(112); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
  public bool MutateNanDefault(float nan_default) { int o = __p.__offset(112); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, nan_default); return true; } else { return false; } }
  public float InfDefault { get { int o = __p.__offset(114); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
  public bool MutateInfDefault(float inf_default) { int o = __p.__offset(114); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, inf_default); return true; } else { return false; } }
  public float PositiveInfDefault { get { int o = __p.__offset(116); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
  public bool MutatePositiveInfDefault(float positive_inf_default) { int o = __p.__offset(116); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, positive_inf_default); return true; } else { return false; } }
  public float InfinityDefault { get { int o = __p.__offset(118); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
  public bool MutateInfinityDefault(float infinity_default) { int o = __p.__offset(118); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, infinity_default); return true; } else { return false; } }
  public float PositiveInfinityDefault { get { int o = __p.__offset(120); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
  public bool MutatePositiveInfinityDefault(float positive_infinity_default) { int o = __p.__offset(120); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, positive_infinity_default); return true; } else { return false; } }
  public float NegativeInfDefault { get { int o = __p.__offset(122); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
  public bool MutateNegativeInfDefault(float negative_inf_default) { int o = __p.__offset(122); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, negative_inf_default); return true; } else { return false; } }
  public float NegativeInfinityDefault { get { int o = __p.__offset(124); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
  public bool MutateNegativeInfinityDefault(float negative_infinity_default) { int o = __p.__offset(124); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, negative_infinity_default); return true; } else { return false; } }
  public double DoubleInfDefault { get { int o = __p.__offset(126); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
  public bool MutateDoubleInfDefault(double double_inf_default) { int o = __p.__offset(126); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, double_inf_default); return true; } else { return false; } }

  public static Offset<MyGame.Example.Monster> CreateMonster(FlatBufferBuilder builder,
      MyGame.Example.Vec3T pos = null,
      short mana = 150,
      short hp = 100,
      StringOffset nameOffset = default(StringOffset),
      VectorOffset inventoryOffset = default(VectorOffset),
      MyGame.Example.Color color = MyGame.Example.Color.Blue,
      MyGame.Example.Any test_type = MyGame.Example.Any.NONE,
      int testOffset = 0,
      VectorOffset test4Offset = default(VectorOffset),
      VectorOffset testarrayofstringOffset = default(VectorOffset),
      VectorOffset testarrayoftablesOffset = default(VectorOffset),
      Offset<MyGame.Example.Monster> enemyOffset = default(Offset<MyGame.Example.Monster>),
      VectorOffset testnestedflatbufferOffset = default(VectorOffset),
      Offset<MyGame.Example.Stat> testemptyOffset = default(Offset<MyGame.Example.Stat>),
      bool testbool = false,
      int testhashs32_fnv1 = 0,
      uint testhashu32_fnv1 = 0,
      long testhashs64_fnv1 = 0,
      ulong testhashu64_fnv1 = 0,
      int testhashs32_fnv1a = 0,
      uint testhashu32_fnv1a = 0,
      long testhashs64_fnv1a = 0,
      ulong testhashu64_fnv1a = 0,
      VectorOffset testarrayofboolsOffset = default(VectorOffset),
      float testf = 3.14159f,
      float testf2 = 3.0f,
      float testf3 = 0.0f,
      VectorOffset testarrayofstring2Offset = default(VectorOffset),
      VectorOffset testarrayofsortedstructOffset = default(VectorOffset),
      VectorOffset flexOffset = default(VectorOffset),
      VectorOffset test5Offset = default(VectorOffset),
      VectorOffset vector_of_longsOffset = default(VectorOffset),
      VectorOffset vector_of_doublesOffset = default(VectorOffset),
      Offset<MyGame.InParentNamespace> parent_namespace_testOffset = default(Offset<MyGame.InParentNamespace>),
      VectorOffset vector_of_referrablesOffset = default(VectorOffset),
      ulong single_weak_reference = 0,
      VectorOffset vector_of_weak_referencesOffset = default(VectorOffset),
      VectorOffset vector_of_strong_referrablesOffset = default(VectorOffset),
      ulong co_owning_reference = 0,
      VectorOffset vector_of_co_owning_referencesOffset = default(VectorOffset),
      ulong non_owning_reference = 0,
      VectorOffset vector_of_non_owning_referencesOffset = default(VectorOffset),
      MyGame.Example.AnyUniqueAliases any_unique_type = MyGame.Example.AnyUniqueAliases.NONE,
      int any_uniqueOffset = 0,
      MyGame.Example.AnyAmbiguousAliases any_ambiguous_type = MyGame.Example.AnyAmbiguousAliases.NONE,
      int any_ambiguousOffset = 0,
      VectorOffset vector_of_enumsOffset = default(VectorOffset),
      MyGame.Example.Race signed_enum = MyGame.Example.Race.None,
      VectorOffset testrequirednestedflatbufferOffset = default(VectorOffset),
      VectorOffset scalar_key_sorted_tablesOffset = default(VectorOffset),
      MyGame.Example.TestT native_inline = null,
      MyGame.Example.LongEnum long_enum_non_enum_default = 0,
      MyGame.Example.LongEnum long_enum_normal_default = MyGame.Example.LongEnum.LongOne,
      float nan_default = Single.NaN,
      float inf_default = Single.PositiveInfinity,
      float positive_inf_default = Single.PositiveInfinity,
      float infinity_default = Single.PositiveInfinity,
      float positive_infinity_default = Single.PositiveInfinity,
      float negative_inf_default = Single.NegativeInfinity,
      float negative_infinity_default = Single.NegativeInfinity,
      double double_inf_default = Double.PositiveInfinity) {
    builder.StartTable(62);
    Monster.AddDoubleInfDefault(builder, double_inf_default);
    Monster.AddLongEnumNormalDefault(builder, long_enum_normal_default);
    Monster.AddLongEnumNonEnumDefault(builder, long_enum_non_enum_default);
    Monster.AddNonOwningReference(builder, non_owning_reference);
    Monster.AddCoOwningReference(builder, co_owning_reference);
    Monster.AddSingleWeakReference(builder, single_weak_reference);
    Monster.AddTesthashu64Fnv1a(builder, testhashu64_fnv1a);
    Monster.AddTesthashs64Fnv1a(builder, testhashs64_fnv1a);
    Monster.AddTesthashu64Fnv1(builder, testhashu64_fnv1);
    Monster.AddTesthashs64Fnv1(builder, testhashs64_fnv1);
    Monster.AddNegativeInfinityDefault(builder, negative_infinity_default);
    Monster.AddNegativeInfDefault(builder, negative_inf_default);
    Monster.AddPositiveInfinityDefault(builder, positive_infinity_default);
    Monster.AddInfinityDefault(builder, infinity_default);
    Monster.AddPositiveInfDefault(builder, positive_inf_default);
    Monster.AddInfDefault(builder, inf_default);
    Monster.AddNanDefault(builder, nan_default);
    Monster.AddNativeInline(builder, MyGame.Example.Test.Pack(builder, native_inline));
    Monster.AddScalarKeySortedTables(builder, scalar_key_sorted_tablesOffset);
    Monster.AddTestrequirednestedflatbuffer(builder, testrequirednestedflatbufferOffset);
    Monster.AddVectorOfEnums(builder, vector_of_enumsOffset);
    Monster.AddAnyAmbiguous(builder, any_ambiguousOffset);
    Monster.AddAnyUnique(builder, any_uniqueOffset);
    Monster.AddVectorOfNonOwningReferences(builder, vector_of_non_owning_referencesOffset);
    Monster.AddVectorOfCoOwningReferences(builder, vector_of_co_owning_referencesOffset);
    Monster.AddVectorOfStrongReferrables(builder, vector_of_strong_referrablesOffset);
    Monster.AddVectorOfWeakReferences(builder, vector_of_weak_referencesOffset);
    Monster.AddVectorOfReferrables(builder, vector_of_referrablesOffset);
    Monster.AddParentNamespaceTest(builder, parent_namespace_testOffset);
    Monster.AddVectorOfDoubles(builder, vector_of_doublesOffset);
    Monster.AddVectorOfLongs(builder, vector_of_longsOffset);
    Monster.AddTest5(builder, test5Offset);
    Monster.AddFlex(builder, flexOffset);
    Monster.AddTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
    Monster.AddTestarrayofstring2(builder, testarrayofstring2Offset);
    Monster.AddTestf3(builder, testf3);
    Monster.AddTestf2(builder, testf2);
    Monster.AddTestf(builder, testf);
    Monster.AddTestarrayofbools(builder, testarrayofboolsOffset);
    Monster.AddTesthashu32Fnv1a(builder, testhashu32_fnv1a);
    Monster.AddTesthashs32Fnv1a(builder, testhashs32_fnv1a);
    Monster.AddTesthashu32Fnv1(builder, testhashu32_fnv1);
    Monster.AddTesthashs32Fnv1(builder, testhashs32_fnv1);
    Monster.AddTestempty(builder, testemptyOffset);
    Monster.AddTestnestedflatbuffer(builder, testnestedflatbufferOffset);
    Monster.AddEnemy(builder, enemyOffset);
    Monster.AddTestarrayoftables(builder, testarrayoftablesOffset);
    Monster.AddTestarrayofstring(builder, testarrayofstringOffset);
    Monster.AddTest4(builder, test4Offset);
    Monster.AddTest(builder, testOffset);
    Monster.AddInventory(builder, inventoryOffset);
    Monster.AddName(builder, nameOffset);
    Monster.AddPos(builder, MyGame.Example.Vec3.Pack(builder, pos));
    Monster.AddHp(builder, hp);
    Monster.AddMana(builder, mana);
    Monster.AddSignedEnum(builder, signed_enum);
    Monster.AddAnyAmbiguousType(builder, any_ambiguous_type);
    Monster.AddAnyUniqueType(builder, any_unique_type);
    Monster.AddTestbool(builder, testbool);
    Monster.AddTestType(builder, test_type);
    Monster.AddColor(builder, color);
    return Monster.EndMonster(builder);
  }

  public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(62); }
  public static void AddPos(FlatBufferBuilder builder, Offset<MyGame.Example.Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 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, StringOffset nameOffset) { builder.AddOffset(3, nameOffset.Value, 0); }
  public static void AddInventory(FlatBufferBuilder builder, VectorOffset inventoryOffset) { builder.AddOffset(5, inventoryOffset.Value, 0); }
  public static VectorOffset CreateInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, ArraySegment<byte> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateInventoryVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<byte>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartInventoryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(6, (byte)color, 8); }
  public static void AddTestType(FlatBufferBuilder builder, MyGame.Example.Any testType) { builder.AddByte(7, (byte)testType, 0); }
  public static void AddTest(FlatBufferBuilder builder, int testOffset) { builder.AddOffset(8, testOffset, 0); }
  public static void AddTest4(FlatBufferBuilder builder, VectorOffset test4Offset) { builder.AddOffset(9, test4Offset.Value, 0); }
  public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
  public static void AddTestarrayofstring(FlatBufferBuilder builder, VectorOffset testarrayofstringOffset) { builder.AddOffset(10, testarrayofstringOffset.Value, 0); }
  public static VectorOffset CreateTestarrayofstringVector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, ArraySegment<StringOffset> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstringVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<StringOffset>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddTestarrayoftables(FlatBufferBuilder builder, VectorOffset testarrayoftablesOffset) { builder.AddOffset(11, testarrayoftablesOffset.Value, 0); }
  public static VectorOffset CreateTestarrayoftablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Monster>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<MyGame.Example.Monster>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayoftablesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<MyGame.Example.Monster>>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddEnemy(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> enemyOffset) { builder.AddOffset(12, enemyOffset.Value, 0); }
  public static void AddTestnestedflatbuffer(FlatBufferBuilder builder, VectorOffset testnestedflatbufferOffset) { builder.AddOffset(13, testnestedflatbufferOffset.Value, 0); }
  public static VectorOffset CreateTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, ArraySegment<byte> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestnestedflatbufferVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<byte>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddTestempty(FlatBufferBuilder builder, Offset<MyGame.Example.Stat> testemptyOffset) { builder.AddOffset(14, testemptyOffset.Value, 0); }
  public static void AddTestbool(FlatBufferBuilder builder, bool testbool) { builder.AddBool(15, testbool, false); }
  public static void AddTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.AddInt(16, testhashs32Fnv1, 0); }
  public static void AddTesthashu32Fnv1(FlatBufferBuilder builder, uint testhashu32Fnv1) { builder.AddUint(17, testhashu32Fnv1, 0); }
  public static void AddTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.AddLong(18, testhashs64Fnv1, 0); }
  public static void AddTesthashu64Fnv1(FlatBufferBuilder builder, ulong testhashu64Fnv1) { builder.AddUlong(19, testhashu64Fnv1, 0); }
  public static void AddTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.AddInt(20, testhashs32Fnv1a, 0); }
  public static void AddTesthashu32Fnv1a(FlatBufferBuilder builder, uint testhashu32Fnv1a) { builder.AddUint(21, testhashu32Fnv1a, 0); }
  public static void AddTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.AddLong(22, testhashs64Fnv1a, 0); }
  public static void AddTesthashu64Fnv1a(FlatBufferBuilder builder, ulong testhashu64Fnv1a) { builder.AddUlong(23, testhashu64Fnv1a, 0); }
  public static void AddTestarrayofbools(FlatBufferBuilder builder, VectorOffset testarrayofboolsOffset) { builder.AddOffset(24, testarrayofboolsOffset.Value, 0); }
  public static VectorOffset CreateTestarrayofboolsVector(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddBool(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, bool[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, ArraySegment<bool> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofboolsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<bool>(dataPtr, sizeInBytes); 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, VectorOffset testarrayofstring2Offset) { builder.AddOffset(28, testarrayofstring2Offset.Value, 0); }
  public static VectorOffset CreateTestarrayofstring2Vector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, ArraySegment<StringOffset> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestarrayofstring2VectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<StringOffset>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartTestarrayofstring2Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddTestarrayofsortedstruct(FlatBufferBuilder builder, VectorOffset testarrayofsortedstructOffset) { builder.AddOffset(29, testarrayofsortedstructOffset.Value, 0); }
  public static void StartTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
  public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
  public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, ArraySegment<byte> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateFlexVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<byte>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddTest5(FlatBufferBuilder builder, VectorOffset test5Offset) { builder.AddOffset(31, test5Offset.Value, 0); }
  public static void StartTest5Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
  public static void AddVectorOfLongs(FlatBufferBuilder builder, VectorOffset vectorOfLongsOffset) { builder.AddOffset(32, vectorOfLongsOffset.Value, 0); }
  public static VectorOffset 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 VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, ArraySegment<long> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfLongsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<long>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddVectorOfDoubles(FlatBufferBuilder builder, VectorOffset vectorOfDoublesOffset) { builder.AddOffset(33, vectorOfDoublesOffset.Value, 0); }
  public static VectorOffset 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 VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, ArraySegment<double> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfDoublesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<double>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddParentNamespaceTest(FlatBufferBuilder builder, Offset<MyGame.InParentNamespace> parentNamespaceTestOffset) { builder.AddOffset(34, parentNamespaceTestOffset.Value, 0); }
  public static void AddVectorOfReferrables(FlatBufferBuilder builder, VectorOffset vectorOfReferrablesOffset) { builder.AddOffset(35, vectorOfReferrablesOffset.Value, 0); }
  public static VectorOffset CreateVectorOfReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<MyGame.Example.Referrable>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfReferrablesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<MyGame.Example.Referrable>>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddSingleWeakReference(FlatBufferBuilder builder, ulong singleWeakReference) { builder.AddUlong(36, singleWeakReference, 0); }
  public static void AddVectorOfWeakReferences(FlatBufferBuilder builder, VectorOffset vectorOfWeakReferencesOffset) { builder.AddOffset(37, vectorOfWeakReferencesOffset.Value, 0); }
  public static VectorOffset CreateVectorOfWeakReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, ArraySegment<ulong> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfWeakReferencesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<ulong>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfWeakReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddVectorOfStrongReferrables(FlatBufferBuilder builder, VectorOffset vectorOfStrongReferrablesOffset) { builder.AddOffset(38, vectorOfStrongReferrablesOffset.Value, 0); }
  public static VectorOffset CreateVectorOfStrongReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Referrable>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<MyGame.Example.Referrable>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfStrongReferrablesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<MyGame.Example.Referrable>>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfStrongReferrablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddCoOwningReference(FlatBufferBuilder builder, ulong coOwningReference) { builder.AddUlong(39, coOwningReference, 0); }
  public static void AddVectorOfCoOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfCoOwningReferencesOffset) { builder.AddOffset(40, vectorOfCoOwningReferencesOffset.Value, 0); }
  public static VectorOffset CreateVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, ArraySegment<ulong> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfCoOwningReferencesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<ulong>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfCoOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddNonOwningReference(FlatBufferBuilder builder, ulong nonOwningReference) { builder.AddUlong(41, nonOwningReference, 0); }
  public static void AddVectorOfNonOwningReferences(FlatBufferBuilder builder, VectorOffset vectorOfNonOwningReferencesOffset) { builder.AddOffset(42, vectorOfNonOwningReferencesOffset.Value, 0); }
  public static VectorOffset CreateVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddUlong(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, ulong[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, ArraySegment<ulong> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfNonOwningReferencesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<ulong>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfNonOwningReferencesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddAnyUniqueType(FlatBufferBuilder builder, MyGame.Example.AnyUniqueAliases anyUniqueType) { builder.AddByte(43, (byte)anyUniqueType, 0); }
  public static void AddAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.AddOffset(44, anyUniqueOffset, 0); }
  public static void AddAnyAmbiguousType(FlatBufferBuilder builder, MyGame.Example.AnyAmbiguousAliases anyAmbiguousType) { builder.AddByte(45, (byte)anyAmbiguousType, 0); }
  public static void AddAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.AddOffset(46, anyAmbiguousOffset, 0); }
  public static void AddVectorOfEnums(FlatBufferBuilder builder, VectorOffset vectorOfEnumsOffset) { builder.AddOffset(47, vectorOfEnumsOffset.Value, 0); }
  public static VectorOffset CreateVectorOfEnumsVector(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte((byte)data[i]); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, MyGame.Example.Color[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, ArraySegment<MyGame.Example.Color> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<MyGame.Example.Color>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddSignedEnum(FlatBufferBuilder builder, MyGame.Example.Race signedEnum) { builder.AddSbyte(48, (sbyte)signedEnum, -1); }
  public static void AddTestrequirednestedflatbuffer(FlatBufferBuilder builder, VectorOffset testrequirednestedflatbufferOffset) { builder.AddOffset(49, testrequirednestedflatbufferOffset.Value, 0); }
  public static VectorOffset CreateTestrequirednestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateTestrequirednestedflatbufferVectorBlock(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestrequirednestedflatbufferVectorBlock(FlatBufferBuilder builder, ArraySegment<byte> data) { builder.StartVector(1, data.Count, 1); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateTestrequirednestedflatbufferVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<byte>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartTestrequirednestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
  public static void AddScalarKeySortedTables(FlatBufferBuilder builder, VectorOffset scalarKeySortedTablesOffset) { builder.AddOffset(50, scalarKeySortedTablesOffset.Value, 0); }
  public static VectorOffset CreateScalarKeySortedTablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.Stat>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
  public static VectorOffset CreateScalarKeySortedTablesVectorBlock(FlatBufferBuilder builder, Offset<MyGame.Example.Stat>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateScalarKeySortedTablesVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<MyGame.Example.Stat>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateScalarKeySortedTablesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<MyGame.Example.Stat>>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartScalarKeySortedTablesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static void AddNativeInline(FlatBufferBuilder builder, Offset<MyGame.Example.Test> nativeInlineOffset) { builder.AddStruct(51, nativeInlineOffset.Value, 0); }
  public static void AddLongEnumNonEnumDefault(FlatBufferBuilder builder, MyGame.Example.LongEnum longEnumNonEnumDefault) { builder.AddUlong(52, (ulong)longEnumNonEnumDefault, 0); }
  public static void AddLongEnumNormalDefault(FlatBufferBuilder builder, MyGame.Example.LongEnum longEnumNormalDefault) { builder.AddUlong(53, (ulong)longEnumNormalDefault, 2); }
  public static void AddNanDefault(FlatBufferBuilder builder, float nanDefault) { builder.AddFloat(54, nanDefault, Single.NaN); }
  public static void AddInfDefault(FlatBufferBuilder builder, float infDefault) { builder.AddFloat(55, infDefault, Single.PositiveInfinity); }
  public static void AddPositiveInfDefault(FlatBufferBuilder builder, float positiveInfDefault) { builder.AddFloat(56, positiveInfDefault, Single.PositiveInfinity); }
  public static void AddInfinityDefault(FlatBufferBuilder builder, float infinityDefault) { builder.AddFloat(57, infinityDefault, Single.PositiveInfinity); }
  public static void AddPositiveInfinityDefault(FlatBufferBuilder builder, float positiveInfinityDefault) { builder.AddFloat(58, positiveInfinityDefault, Single.PositiveInfinity); }
  public static void AddNegativeInfDefault(FlatBufferBuilder builder, float negativeInfDefault) { builder.AddFloat(59, negativeInfDefault, Single.NegativeInfinity); }
  public static void AddNegativeInfinityDefault(FlatBufferBuilder builder, float negativeInfinityDefault) { builder.AddFloat(60, negativeInfinityDefault, Single.NegativeInfinity); }
  public static void AddDoubleInfDefault(FlatBufferBuilder builder, double doubleInfDefault) { builder.AddDouble(61, doubleInfDefault, Double.PositiveInfinity); }
  public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) {
    int o = builder.EndTable();
    builder.Required(o, 10);  // name
    return new Offset<MyGame.Example.Monster>(o);
  }
  public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.Finish(offset.Value, "MONS"); }
  public static void FinishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.FinishSizePrefixed(offset.Value, "MONS"); }

  public static VectorOffset CreateSortedVectorOfMonster(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
    Array.Sort(offsets,
      (Offset<Monster> o1, Offset<Monster> o2) =>
        new Monster().__assign(builder.DataBuffer.Length - o1.Value, builder.DataBuffer).Name.CompareTo(new Monster().__assign(builder.DataBuffer.Length - o2.Value, builder.DataBuffer).Name));
    return builder.CreateVectorOfTables(offsets);
  }

  public static Monster? __lookup_by_key(int vectorLocation, string key, ByteBuffer bb) {
    Monster obj_ = new Monster();
    int span = bb.GetInt(vectorLocation - 4);
    int start = 0;
    while (span != 0) {
      int middle = span / 2;
      int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
      obj_.__assign(tableOffset, bb);
      int comp = obj_.Name.CompareTo(key);
      if (comp > 0) {
        span = middle;
      } else if (comp < 0) {
        middle++;
        start += middle;
        span -= middle;
      } else {
        return obj_;
      }
    }
    return null;
  }
  public MonsterT UnPack() {
    var _o = new MonsterT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(MonsterT _o) {
    _o.Pos = this.Pos.HasValue ? this.Pos.Value.UnPack() : null;
    _o.Mana = this.Mana;
    _o.Hp = this.Hp;
    _o.Name = this.Name;
    _o.Inventory = new List<byte>();
    for (var _j = 0; _j < this.InventoryLength; ++_j) {_o.Inventory.Add(this.Inventory(_j));}
    _o.Color = this.Color;
    _o.Test = new MyGame.Example.AnyUnion();
    _o.Test.Type = this.TestType;
    switch (this.TestType) {
      default: break;
      case MyGame.Example.Any.Monster:
        _o.Test.Value = this.Test<MyGame.Example.Monster>().HasValue ? this.Test<MyGame.Example.Monster>().Value.UnPack() : null;
        break;
      case MyGame.Example.Any.TestSimpleTableWithEnum:
        _o.Test.Value = this.Test<MyGame.Example.TestSimpleTableWithEnum>().HasValue ? this.Test<MyGame.Example.TestSimpleTableWithEnum>().Value.UnPack() : null;
        break;
      case MyGame.Example.Any.MyGame_Example2_Monster:
        _o.Test.Value = this.Test<MyGame.Example2.Monster>().HasValue ? this.Test<MyGame.Example2.Monster>().Value.UnPack() : null;
        break;
    }
    _o.Test4 = new List<MyGame.Example.TestT>();
    for (var _j = 0; _j < this.Test4Length; ++_j) {_o.Test4.Add(this.Test4(_j).HasValue ? this.Test4(_j).Value.UnPack() : null);}
    _o.Testarrayofstring = new List<string>();
    for (var _j = 0; _j < this.TestarrayofstringLength; ++_j) {_o.Testarrayofstring.Add(this.Testarrayofstring(_j));}
    _o.Testarrayoftables = new List<MyGame.Example.MonsterT>();
    for (var _j = 0; _j < this.TestarrayoftablesLength; ++_j) {_o.Testarrayoftables.Add(this.Testarrayoftables(_j).HasValue ? this.Testarrayoftables(_j).Value.UnPack() : null);}
    _o.Enemy = this.Enemy.HasValue ? this.Enemy.Value.UnPack() : null;
    _o.Testnestedflatbuffer = new List<byte>();
    for (var _j = 0; _j < this.TestnestedflatbufferLength; ++_j) {_o.Testnestedflatbuffer.Add(this.Testnestedflatbuffer(_j));}
    _o.Testempty = this.Testempty.HasValue ? this.Testempty.Value.UnPack() : null;
    _o.Testbool = this.Testbool;
    _o.Testhashs32Fnv1 = this.Testhashs32Fnv1;
    _o.Testhashu32Fnv1 = this.Testhashu32Fnv1;
    _o.Testhashs64Fnv1 = this.Testhashs64Fnv1;
    _o.Testhashu64Fnv1 = this.Testhashu64Fnv1;
    _o.Testhashs32Fnv1a = this.Testhashs32Fnv1a;
    _o.Testhashu32Fnv1a = this.Testhashu32Fnv1a;
    _o.Testhashs64Fnv1a = this.Testhashs64Fnv1a;
    _o.Testhashu64Fnv1a = this.Testhashu64Fnv1a;
    _o.Testarrayofbools = new List<bool>();
    for (var _j = 0; _j < this.TestarrayofboolsLength; ++_j) {_o.Testarrayofbools.Add(this.Testarrayofbools(_j));}
    _o.Testf = this.Testf;
    _o.Testf2 = this.Testf2;
    _o.Testf3 = this.Testf3;
    _o.Testarrayofstring2 = new List<string>();
    for (var _j = 0; _j < this.Testarrayofstring2Length; ++_j) {_o.Testarrayofstring2.Add(this.Testarrayofstring2(_j));}
    _o.Testarrayofsortedstruct = new List<MyGame.Example.AbilityT>();
    for (var _j = 0; _j < this.TestarrayofsortedstructLength; ++_j) {_o.Testarrayofsortedstruct.Add(this.Testarrayofsortedstruct(_j).HasValue ? this.Testarrayofsortedstruct(_j).Value.UnPack() : null);}
    _o.Flex = new List<byte>();
    for (var _j = 0; _j < this.FlexLength; ++_j) {_o.Flex.Add(this.Flex(_j));}
    _o.Test5 = new List<MyGame.Example.TestT>();
    for (var _j = 0; _j < this.Test5Length; ++_j) {_o.Test5.Add(this.Test5(_j).HasValue ? this.Test5(_j).Value.UnPack() : null);}
    _o.VectorOfLongs = new List<long>();
    for (var _j = 0; _j < this.VectorOfLongsLength; ++_j) {_o.VectorOfLongs.Add(this.VectorOfLongs(_j));}
    _o.VectorOfDoubles = new List<double>();
    for (var _j = 0; _j < this.VectorOfDoublesLength; ++_j) {_o.VectorOfDoubles.Add(this.VectorOfDoubles(_j));}
    _o.ParentNamespaceTest = this.ParentNamespaceTest.HasValue ? this.ParentNamespaceTest.Value.UnPack() : null;
    _o.VectorOfReferrables = new List<MyGame.Example.ReferrableT>();
    for (var _j = 0; _j < this.VectorOfReferrablesLength; ++_j) {_o.VectorOfReferrables.Add(this.VectorOfReferrables(_j).HasValue ? this.VectorOfReferrables(_j).Value.UnPack() : null);}
    _o.SingleWeakReference = this.SingleWeakReference;
    _o.VectorOfWeakReferences = new List<ulong>();
    for (var _j = 0; _j < this.VectorOfWeakReferencesLength; ++_j) {_o.VectorOfWeakReferences.Add(this.VectorOfWeakReferences(_j));}
    _o.VectorOfStrongReferrables = new List<MyGame.Example.ReferrableT>();
    for (var _j = 0; _j < this.VectorOfStrongReferrablesLength; ++_j) {_o.VectorOfStrongReferrables.Add(this.VectorOfStrongReferrables(_j).HasValue ? this.VectorOfStrongReferrables(_j).Value.UnPack() : null);}
    _o.CoOwningReference = this.CoOwningReference;
    _o.VectorOfCoOwningReferences = new List<ulong>();
    for (var _j = 0; _j < this.VectorOfCoOwningReferencesLength; ++_j) {_o.VectorOfCoOwningReferences.Add(this.VectorOfCoOwningReferences(_j));}
    _o.NonOwningReference = this.NonOwningReference;
    _o.VectorOfNonOwningReferences = new List<ulong>();
    for (var _j = 0; _j < this.VectorOfNonOwningReferencesLength; ++_j) {_o.VectorOfNonOwningReferences.Add(this.VectorOfNonOwningReferences(_j));}
    _o.AnyUnique = new MyGame.Example.AnyUniqueAliasesUnion();
    _o.AnyUnique.Type = this.AnyUniqueType;
    switch (this.AnyUniqueType) {
      default: break;
      case MyGame.Example.AnyUniqueAliases.M:
        _o.AnyUnique.Value = this.AnyUnique<MyGame.Example.Monster>().HasValue ? this.AnyUnique<MyGame.Example.Monster>().Value.UnPack() : null;
        break;
      case MyGame.Example.AnyUniqueAliases.TS:
        _o.AnyUnique.Value = this.AnyUnique<MyGame.Example.TestSimpleTableWithEnum>().HasValue ? this.AnyUnique<MyGame.Example.TestSimpleTableWithEnum>().Value.UnPack() : null;
        break;
      case MyGame.Example.AnyUniqueAliases.M2:
        _o.AnyUnique.Value = this.AnyUnique<MyGame.Example2.Monster>().HasValue ? this.AnyUnique<MyGame.Example2.Monster>().Value.UnPack() : null;
        break;
    }
    _o.AnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion();
    _o.AnyAmbiguous.Type = this.AnyAmbiguousType;
    switch (this.AnyAmbiguousType) {
      default: break;
      case MyGame.Example.AnyAmbiguousAliases.M1:
        _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
        break;
      case MyGame.Example.AnyAmbiguousAliases.M2:
        _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
        break;
      case MyGame.Example.AnyAmbiguousAliases.M3:
        _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
        break;
    }
    _o.VectorOfEnums = new List<MyGame.Example.Color>();
    for (var _j = 0; _j < this.VectorOfEnumsLength; ++_j) {_o.VectorOfEnums.Add(this.VectorOfEnums(_j));}
    _o.SignedEnum = this.SignedEnum;
    _o.Testrequirednestedflatbuffer = new List<byte>();
    for (var _j = 0; _j < this.TestrequirednestedflatbufferLength; ++_j) {_o.Testrequirednestedflatbuffer.Add(this.Testrequirednestedflatbuffer(_j));}
    _o.ScalarKeySortedTables = new List<MyGame.Example.StatT>();
    for (var _j = 0; _j < this.ScalarKeySortedTablesLength; ++_j) {_o.ScalarKeySortedTables.Add(this.ScalarKeySortedTables(_j).HasValue ? this.ScalarKeySortedTables(_j).Value.UnPack() : null);}
    _o.NativeInline = this.NativeInline.HasValue ? this.NativeInline.Value.UnPack() : null;
    _o.LongEnumNonEnumDefault = this.LongEnumNonEnumDefault;
    _o.LongEnumNormalDefault = this.LongEnumNormalDefault;
    _o.NanDefault = this.NanDefault;
    _o.InfDefault = this.InfDefault;
    _o.PositiveInfDefault = this.PositiveInfDefault;
    _o.InfinityDefault = this.InfinityDefault;
    _o.PositiveInfinityDefault = this.PositiveInfinityDefault;
    _o.NegativeInfDefault = this.NegativeInfDefault;
    _o.NegativeInfinityDefault = this.NegativeInfinityDefault;
    _o.DoubleInfDefault = this.DoubleInfDefault;
  }
  public static Offset<MyGame.Example.Monster> Pack(FlatBufferBuilder builder, MonsterT _o) {
    if (_o == null) return default(Offset<MyGame.Example.Monster>);
    var _name = _o.Name == null ? default(StringOffset) : builder.CreateString(_o.Name);
    var _inventory = default(VectorOffset);
    if (_o.Inventory != null) {
      var __inventory = _o.Inventory.ToArray();
      _inventory = CreateInventoryVector(builder, __inventory);
    }
    var _test_type = _o.Test == null ? MyGame.Example.Any.NONE : _o.Test.Type;
    var _test = _o.Test == null ? 0 : MyGame.Example.AnyUnion.Pack(builder, _o.Test);
    var _test4 = default(VectorOffset);
    if (_o.Test4 != null) {
      StartTest4Vector(builder, _o.Test4.Count);
      for (var _j = _o.Test4.Count - 1; _j >= 0; --_j) { MyGame.Example.Test.Pack(builder, _o.Test4[_j]); }
      _test4 = builder.EndVector();
    }
    var _testarrayofstring = default(VectorOffset);
    if (_o.Testarrayofstring != null) {
      var __testarrayofstring = new StringOffset[_o.Testarrayofstring.Count];
      for (var _j = 0; _j < __testarrayofstring.Length; ++_j) { __testarrayofstring[_j] = builder.CreateString(_o.Testarrayofstring[_j]); }
      _testarrayofstring = CreateTestarrayofstringVector(builder, __testarrayofstring);
    }
    var _testarrayoftables = default(VectorOffset);
    if (_o.Testarrayoftables != null) {
      var __testarrayoftables = new Offset<MyGame.Example.Monster>[_o.Testarrayoftables.Count];
      for (var _j = 0; _j < __testarrayoftables.Length; ++_j) { __testarrayoftables[_j] = MyGame.Example.Monster.Pack(builder, _o.Testarrayoftables[_j]); }
      _testarrayoftables = CreateTestarrayoftablesVector(builder, __testarrayoftables);
    }
    var _enemy = _o.Enemy == null ? default(Offset<MyGame.Example.Monster>) : MyGame.Example.Monster.Pack(builder, _o.Enemy);
    var _testnestedflatbuffer = default(VectorOffset);
    if (_o.Testnestedflatbuffer != null) {
      var __testnestedflatbuffer = _o.Testnestedflatbuffer.ToArray();
      _testnestedflatbuffer = CreateTestnestedflatbufferVector(builder, __testnestedflatbuffer);
    }
    var _testempty = _o.Testempty == null ? default(Offset<MyGame.Example.Stat>) : MyGame.Example.Stat.Pack(builder, _o.Testempty);
    var _testarrayofbools = default(VectorOffset);
    if (_o.Testarrayofbools != null) {
      var __testarrayofbools = _o.Testarrayofbools.ToArray();
      _testarrayofbools = CreateTestarrayofboolsVector(builder, __testarrayofbools);
    }
    var _testarrayofstring2 = default(VectorOffset);
    if (_o.Testarrayofstring2 != null) {
      var __testarrayofstring2 = new StringOffset[_o.Testarrayofstring2.Count];
      for (var _j = 0; _j < __testarrayofstring2.Length; ++_j) { __testarrayofstring2[_j] = builder.CreateString(_o.Testarrayofstring2[_j]); }
      _testarrayofstring2 = CreateTestarrayofstring2Vector(builder, __testarrayofstring2);
    }
    var _testarrayofsortedstruct = default(VectorOffset);
    if (_o.Testarrayofsortedstruct != null) {
      StartTestarrayofsortedstructVector(builder, _o.Testarrayofsortedstruct.Count);
      for (var _j = _o.Testarrayofsortedstruct.Count - 1; _j >= 0; --_j) { MyGame.Example.Ability.Pack(builder, _o.Testarrayofsortedstruct[_j]); }
      _testarrayofsortedstruct = builder.EndVector();
    }
    var _flex = default(VectorOffset);
    if (_o.Flex != null) {
      var __flex = _o.Flex.ToArray();
      _flex = CreateFlexVector(builder, __flex);
    }
    var _test5 = default(VectorOffset);
    if (_o.Test5 != null) {
      StartTest5Vector(builder, _o.Test5.Count);
      for (var _j = _o.Test5.Count - 1; _j >= 0; --_j) { MyGame.Example.Test.Pack(builder, _o.Test5[_j]); }
      _test5 = builder.EndVector();
    }
    var _vector_of_longs = default(VectorOffset);
    if (_o.VectorOfLongs != null) {
      var __vector_of_longs = _o.VectorOfLongs.ToArray();
      _vector_of_longs = CreateVectorOfLongsVector(builder, __vector_of_longs);
    }
    var _vector_of_doubles = default(VectorOffset);
    if (_o.VectorOfDoubles != null) {
      var __vector_of_doubles = _o.VectorOfDoubles.ToArray();
      _vector_of_doubles = CreateVectorOfDoublesVector(builder, __vector_of_doubles);
    }
    var _parent_namespace_test = _o.ParentNamespaceTest == null ? default(Offset<MyGame.InParentNamespace>) : MyGame.InParentNamespace.Pack(builder, _o.ParentNamespaceTest);
    var _vector_of_referrables = default(VectorOffset);
    if (_o.VectorOfReferrables != null) {
      var __vector_of_referrables = new Offset<MyGame.Example.Referrable>[_o.VectorOfReferrables.Count];
      for (var _j = 0; _j < __vector_of_referrables.Length; ++_j) { __vector_of_referrables[_j] = MyGame.Example.Referrable.Pack(builder, _o.VectorOfReferrables[_j]); }
      _vector_of_referrables = CreateVectorOfReferrablesVector(builder, __vector_of_referrables);
    }
    var _vector_of_weak_references = default(VectorOffset);
    if (_o.VectorOfWeakReferences != null) {
      var __vector_of_weak_references = _o.VectorOfWeakReferences.ToArray();
      _vector_of_weak_references = CreateVectorOfWeakReferencesVector(builder, __vector_of_weak_references);
    }
    var _vector_of_strong_referrables = default(VectorOffset);
    if (_o.VectorOfStrongReferrables != null) {
      var __vector_of_strong_referrables = new Offset<MyGame.Example.Referrable>[_o.VectorOfStrongReferrables.Count];
      for (var _j = 0; _j < __vector_of_strong_referrables.Length; ++_j) { __vector_of_strong_referrables[_j] = MyGame.Example.Referrable.Pack(builder, _o.VectorOfStrongReferrables[_j]); }
      _vector_of_strong_referrables = CreateVectorOfStrongReferrablesVector(builder, __vector_of_strong_referrables);
    }
    var _vector_of_co_owning_references = default(VectorOffset);
    if (_o.VectorOfCoOwningReferences != null) {
      var __vector_of_co_owning_references = _o.VectorOfCoOwningReferences.ToArray();
      _vector_of_co_owning_references = CreateVectorOfCoOwningReferencesVector(builder, __vector_of_co_owning_references);
    }
    var _vector_of_non_owning_references = default(VectorOffset);
    if (_o.VectorOfNonOwningReferences != null) {
      var __vector_of_non_owning_references = _o.VectorOfNonOwningReferences.ToArray();
      _vector_of_non_owning_references = CreateVectorOfNonOwningReferencesVector(builder, __vector_of_non_owning_references);
    }
    var _any_unique_type = _o.AnyUnique == null ? MyGame.Example.AnyUniqueAliases.NONE : _o.AnyUnique.Type;
    var _any_unique = _o.AnyUnique == null ? 0 : MyGame.Example.AnyUniqueAliasesUnion.Pack(builder, _o.AnyUnique);
    var _any_ambiguous_type = _o.AnyAmbiguous == null ? MyGame.Example.AnyAmbiguousAliases.NONE : _o.AnyAmbiguous.Type;
    var _any_ambiguous = _o.AnyAmbiguous == null ? 0 : MyGame.Example.AnyAmbiguousAliasesUnion.Pack(builder, _o.AnyAmbiguous);
    var _vector_of_enums = default(VectorOffset);
    if (_o.VectorOfEnums != null) {
      var __vector_of_enums = _o.VectorOfEnums.ToArray();
      _vector_of_enums = CreateVectorOfEnumsVector(builder, __vector_of_enums);
    }
    var _testrequirednestedflatbuffer = default(VectorOffset);
    if (_o.Testrequirednestedflatbuffer != null) {
      var __testrequirednestedflatbuffer = _o.Testrequirednestedflatbuffer.ToArray();
      _testrequirednestedflatbuffer = CreateTestrequirednestedflatbufferVector(builder, __testrequirednestedflatbuffer);
    }
    var _scalar_key_sorted_tables = default(VectorOffset);
    if (_o.ScalarKeySortedTables != null) {
      var __scalar_key_sorted_tables = new Offset<MyGame.Example.Stat>[_o.ScalarKeySortedTables.Count];
      for (var _j = 0; _j < __scalar_key_sorted_tables.Length; ++_j) { __scalar_key_sorted_tables[_j] = MyGame.Example.Stat.Pack(builder, _o.ScalarKeySortedTables[_j]); }
      _scalar_key_sorted_tables = CreateScalarKeySortedTablesVector(builder, __scalar_key_sorted_tables);
    }
    return CreateMonster(
      builder,
      _o.Pos,
      _o.Mana,
      _o.Hp,
      _name,
      _inventory,
      _o.Color,
      _test_type,
      _test,
      _test4,
      _testarrayofstring,
      _testarrayoftables,
      _enemy,
      _testnestedflatbuffer,
      _testempty,
      _o.Testbool,
      _o.Testhashs32Fnv1,
      _o.Testhashu32Fnv1,
      _o.Testhashs64Fnv1,
      _o.Testhashu64Fnv1,
      _o.Testhashs32Fnv1a,
      _o.Testhashu32Fnv1a,
      _o.Testhashs64Fnv1a,
      _o.Testhashu64Fnv1a,
      _testarrayofbools,
      _o.Testf,
      _o.Testf2,
      _o.Testf3,
      _testarrayofstring2,
      _testarrayofsortedstruct,
      _flex,
      _test5,
      _vector_of_longs,
      _vector_of_doubles,
      _parent_namespace_test,
      _vector_of_referrables,
      _o.SingleWeakReference,
      _vector_of_weak_references,
      _vector_of_strong_referrables,
      _o.CoOwningReference,
      _vector_of_co_owning_references,
      _o.NonOwningReference,
      _vector_of_non_owning_references,
      _any_unique_type,
      _any_unique,
      _any_ambiguous_type,
      _any_ambiguous,
      _vector_of_enums,
      _o.SignedEnum,
      _testrequirednestedflatbuffer,
      _scalar_key_sorted_tables,
      _o.NativeInline,
      _o.LongEnumNonEnumDefault,
      _o.LongEnumNormalDefault,
      _o.NanDefault,
      _o.InfDefault,
      _o.PositiveInfDefault,
      _o.InfinityDefault,
      _o.PositiveInfinityDefault,
      _o.NegativeInfDefault,
      _o.NegativeInfinityDefault,
      _o.DoubleInfDefault);
  }
}

public class MonsterT
{
  [Newtonsoft.Json.JsonProperty("pos")]
  public MyGame.Example.Vec3T Pos { get; set; }
  [Newtonsoft.Json.JsonProperty("mana")]
  public short Mana { get; set; }
  [Newtonsoft.Json.JsonProperty("hp")]
  public short Hp { get; set; }
  [Newtonsoft.Json.JsonProperty("name")]
  public string Name { get; set; }
  [Newtonsoft.Json.JsonProperty("inventory")]
  public List<byte> Inventory { get; set; }
  [Newtonsoft.Json.JsonProperty("color")]
  public MyGame.Example.Color Color { get; set; }
  [Newtonsoft.Json.JsonProperty("test_type")]
  private MyGame.Example.Any TestType {
    get {
      return this.Test != null ? this.Test.Type : MyGame.Example.Any.NONE;
    }
    set {
      this.Test = new MyGame.Example.AnyUnion();
      this.Test.Type = value;
    }
  }
  [Newtonsoft.Json.JsonProperty("test")]
  [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUnion_JsonConverter))]
  public MyGame.Example.AnyUnion Test { get; set; }
  [Newtonsoft.Json.JsonProperty("test4")]
  public List<MyGame.Example.TestT> Test4 { get; set; }
  [Newtonsoft.Json.JsonProperty("testarrayofstring")]
  public List<string> Testarrayofstring { get; set; }
  [Newtonsoft.Json.JsonProperty("testarrayoftables")]
  public List<MyGame.Example.MonsterT> Testarrayoftables { get; set; }
  [Newtonsoft.Json.JsonProperty("enemy")]
  public MyGame.Example.MonsterT Enemy { get; set; }
  [Newtonsoft.Json.JsonProperty("testnestedflatbuffer")]
  public List<byte> Testnestedflatbuffer { get; set; }
  [Newtonsoft.Json.JsonProperty("testempty")]
  public MyGame.Example.StatT Testempty { get; set; }
  [Newtonsoft.Json.JsonProperty("testbool")]
  public bool Testbool { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashs32_fnv1")]
  [Newtonsoft.Json.JsonIgnore()]
  public int Testhashs32Fnv1 { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashu32_fnv1")]
  [Newtonsoft.Json.JsonIgnore()]
  public uint Testhashu32Fnv1 { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashs64_fnv1")]
  [Newtonsoft.Json.JsonIgnore()]
  public long Testhashs64Fnv1 { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashu64_fnv1")]
  [Newtonsoft.Json.JsonIgnore()]
  public ulong Testhashu64Fnv1 { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashs32_fnv1a")]
  [Newtonsoft.Json.JsonIgnore()]
  public int Testhashs32Fnv1a { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashu32_fnv1a")]
  [Newtonsoft.Json.JsonIgnore()]
  public uint Testhashu32Fnv1a { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashs64_fnv1a")]
  [Newtonsoft.Json.JsonIgnore()]
  public long Testhashs64Fnv1a { get; set; }
  [Newtonsoft.Json.JsonProperty("testhashu64_fnv1a")]
  [Newtonsoft.Json.JsonIgnore()]
  public ulong Testhashu64Fnv1a { get; set; }
  [Newtonsoft.Json.JsonProperty("testarrayofbools")]
  public List<bool> Testarrayofbools { get; set; }
  [Newtonsoft.Json.JsonProperty("testf")]
  public float Testf { get; set; }
  [Newtonsoft.Json.JsonProperty("testf2")]
  public float Testf2 { get; set; }
  [Newtonsoft.Json.JsonProperty("testf3")]
  public float Testf3 { get; set; }
  [Newtonsoft.Json.JsonProperty("testarrayofstring2")]
  public List<string> Testarrayofstring2 { get; set; }
  [Newtonsoft.Json.JsonProperty("testarrayofsortedstruct")]
  public List<MyGame.Example.AbilityT> Testarrayofsortedstruct { get; set; }
  [Newtonsoft.Json.JsonProperty("flex")]
  public List<byte> Flex { get; set; }
  [Newtonsoft.Json.JsonProperty("test5")]
  public List<MyGame.Example.TestT> Test5 { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_longs")]
  public List<long> VectorOfLongs { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_doubles")]
  public List<double> VectorOfDoubles { get; set; }
  [Newtonsoft.Json.JsonProperty("parent_namespace_test")]
  public MyGame.InParentNamespaceT ParentNamespaceTest { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_referrables")]
  public List<MyGame.Example.ReferrableT> VectorOfReferrables { get; set; }
  [Newtonsoft.Json.JsonProperty("single_weak_reference")]
  [Newtonsoft.Json.JsonIgnore()]
  public ulong SingleWeakReference { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_weak_references")]
  [Newtonsoft.Json.JsonIgnore()]
  public List<ulong> VectorOfWeakReferences { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_strong_referrables")]
  public List<MyGame.Example.ReferrableT> VectorOfStrongReferrables { get; set; }
  [Newtonsoft.Json.JsonProperty("co_owning_reference")]
  [Newtonsoft.Json.JsonIgnore()]
  public ulong CoOwningReference { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_co_owning_references")]
  [Newtonsoft.Json.JsonIgnore()]
  public List<ulong> VectorOfCoOwningReferences { get; set; }
  [Newtonsoft.Json.JsonProperty("non_owning_reference")]
  [Newtonsoft.Json.JsonIgnore()]
  public ulong NonOwningReference { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_non_owning_references")]
  [Newtonsoft.Json.JsonIgnore()]
  public List<ulong> VectorOfNonOwningReferences { get; set; }
  [Newtonsoft.Json.JsonProperty("any_unique_type")]
  private MyGame.Example.AnyUniqueAliases AnyUniqueType {
    get {
      return this.AnyUnique != null ? this.AnyUnique.Type : MyGame.Example.AnyUniqueAliases.NONE;
    }
    set {
      this.AnyUnique = new MyGame.Example.AnyUniqueAliasesUnion();
      this.AnyUnique.Type = value;
    }
  }
  [Newtonsoft.Json.JsonProperty("any_unique")]
  [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUniqueAliasesUnion_JsonConverter))]
  public MyGame.Example.AnyUniqueAliasesUnion AnyUnique { get; set; }
  [Newtonsoft.Json.JsonProperty("any_ambiguous_type")]
  private MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType {
    get {
      return this.AnyAmbiguous != null ? this.AnyAmbiguous.Type : MyGame.Example.AnyAmbiguousAliases.NONE;
    }
    set {
      this.AnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion();
      this.AnyAmbiguous.Type = value;
    }
  }
  [Newtonsoft.Json.JsonProperty("any_ambiguous")]
  [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyAmbiguousAliasesUnion_JsonConverter))]
  public MyGame.Example.AnyAmbiguousAliasesUnion AnyAmbiguous { get; set; }
  [Newtonsoft.Json.JsonProperty("vector_of_enums")]
  public List<MyGame.Example.Color> VectorOfEnums { get; set; }
  [Newtonsoft.Json.JsonProperty("signed_enum")]
  public MyGame.Example.Race SignedEnum { get; set; }
  [Newtonsoft.Json.JsonProperty("testrequirednestedflatbuffer")]
  public List<byte> Testrequirednestedflatbuffer { get; set; }
  [Newtonsoft.Json.JsonProperty("scalar_key_sorted_tables")]
  public List<MyGame.Example.StatT> ScalarKeySortedTables { get; set; }
  [Newtonsoft.Json.JsonProperty("native_inline")]
  public MyGame.Example.TestT NativeInline { get; set; }
  [Newtonsoft.Json.JsonProperty("long_enum_non_enum_default")]
  public MyGame.Example.LongEnum LongEnumNonEnumDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("long_enum_normal_default")]
  public MyGame.Example.LongEnum LongEnumNormalDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("nan_default")]
  public float NanDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("inf_default")]
  public float InfDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("positive_inf_default")]
  public float PositiveInfDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("infinity_default")]
  public float InfinityDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("positive_infinity_default")]
  public float PositiveInfinityDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("negative_inf_default")]
  public float NegativeInfDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("negative_infinity_default")]
  public float NegativeInfinityDefault { get; set; }
  [Newtonsoft.Json.JsonProperty("double_inf_default")]
  public double DoubleInfDefault { get; set; }

  public MonsterT() {
    this.Pos = new MyGame.Example.Vec3T();
    this.Mana = 150;
    this.Hp = 100;
    this.Name = null;
    this.Inventory = null;
    this.Color = MyGame.Example.Color.Blue;
    this.Test = null;
    this.Test4 = null;
    this.Testarrayofstring = null;
    this.Testarrayoftables = null;
    this.Enemy = null;
    this.Testnestedflatbuffer = null;
    this.Testempty = null;
    this.Testbool = false;
    this.Testhashs32Fnv1 = 0;
    this.Testhashu32Fnv1 = 0;
    this.Testhashs64Fnv1 = 0;
    this.Testhashu64Fnv1 = 0;
    this.Testhashs32Fnv1a = 0;
    this.Testhashu32Fnv1a = 0;
    this.Testhashs64Fnv1a = 0;
    this.Testhashu64Fnv1a = 0;
    this.Testarrayofbools = null;
    this.Testf = 3.14159f;
    this.Testf2 = 3.0f;
    this.Testf3 = 0.0f;
    this.Testarrayofstring2 = null;
    this.Testarrayofsortedstruct = null;
    this.Flex = null;
    this.Test5 = null;
    this.VectorOfLongs = null;
    this.VectorOfDoubles = null;
    this.ParentNamespaceTest = null;
    this.VectorOfReferrables = null;
    this.SingleWeakReference = 0;
    this.VectorOfWeakReferences = null;
    this.VectorOfStrongReferrables = null;
    this.CoOwningReference = 0;
    this.VectorOfCoOwningReferences = null;
    this.NonOwningReference = 0;
    this.VectorOfNonOwningReferences = null;
    this.AnyUnique = null;
    this.AnyAmbiguous = null;
    this.VectorOfEnums = null;
    this.SignedEnum = MyGame.Example.Race.None;
    this.Testrequirednestedflatbuffer = null;
    this.ScalarKeySortedTables = null;
    this.NativeInline = new MyGame.Example.TestT();
    this.LongEnumNonEnumDefault = 0;
    this.LongEnumNormalDefault = MyGame.Example.LongEnum.LongOne;
    this.NanDefault = Single.NaN;
    this.InfDefault = Single.PositiveInfinity;
    this.PositiveInfDefault = Single.PositiveInfinity;
    this.InfinityDefault = Single.PositiveInfinity;
    this.PositiveInfinityDefault = Single.PositiveInfinity;
    this.NegativeInfDefault = Single.NegativeInfinity;
    this.NegativeInfinityDefault = Single.NegativeInfinity;
    this.DoubleInfDefault = Double.PositiveInfinity;
  }

  public static MonsterT DeserializeFromJson(string jsonText) {
    return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterT>(jsonText);
  }
  public string SerializeToJson() {
    return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
  }
  public static MonsterT DeserializeFromBinary(byte[] fbBuffer) {
    return Monster.GetRootAsMonster(new ByteBuffer(fbBuffer)).UnPack();
  }
  public byte[] SerializeToBinary() {
    var fbb = new FlatBufferBuilder(0x10000);
    Monster.FinishMonsterBuffer(fbb, Monster.Pack(fbb, this));
    return fbb.DataBuffer.ToSizedArray();
  }
}


static public class MonsterVerify
{
  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
  {
    return verifier.VerifyTableStart(tablePos)
      && verifier.VerifyField(tablePos, 4 /*Pos*/, 32 /*MyGame.Example.Vec3*/, 8, false)
      && verifier.VerifyField(tablePos, 6 /*Mana*/, 2 /*short*/, 2, false)
      && verifier.VerifyField(tablePos, 8 /*Hp*/, 2 /*short*/, 2, false)
      && verifier.VerifyString(tablePos, 10 /*Name*/, true)
      && verifier.VerifyVectorOfData(tablePos, 14 /*Inventory*/, 1 /*byte*/, false)
      && verifier.VerifyField(tablePos, 16 /*Color*/, 1 /*MyGame.Example.Color*/, 1, false)
      && verifier.VerifyField(tablePos, 18 /*TestType*/, 1 /*MyGame.Example.Any*/, 1, false)
      && verifier.VerifyUnion(tablePos, 18, 20 /*Test*/, MyGame.Example.AnyVerify.Verify, false)
      && verifier.VerifyVectorOfData(tablePos, 22 /*Test4*/, 4 /*MyGame.Example.Test*/, false)
      && verifier.VerifyVectorOfStrings(tablePos, 24 /*Testarrayofstring*/, false)
      && verifier.VerifyVectorOfTables(tablePos, 26 /*Testarrayoftables*/, MyGame.Example.MonsterVerify.Verify, false)
      && verifier.VerifyTable(tablePos, 28 /*Enemy*/, MyGame.Example.MonsterVerify.Verify, false)
      && verifier.VerifyNestedBuffer(tablePos, 30 /*Testnestedflatbuffer*/, MyGame.Example.MonsterVerify.Verify, false)
      && verifier.VerifyTable(tablePos, 32 /*Testempty*/, MyGame.Example.StatVerify.Verify, false)
      && verifier.VerifyField(tablePos, 34 /*Testbool*/, 1 /*bool*/, 1, false)
      && verifier.VerifyField(tablePos, 36 /*Testhashs32Fnv1*/, 4 /*int*/, 4, false)
      && verifier.VerifyField(tablePos, 38 /*Testhashu32Fnv1*/, 4 /*uint*/, 4, false)
      && verifier.VerifyField(tablePos, 40 /*Testhashs64Fnv1*/, 8 /*long*/, 8, false)
      && verifier.VerifyField(tablePos, 42 /*Testhashu64Fnv1*/, 8 /*ulong*/, 8, false)
      && verifier.VerifyField(tablePos, 44 /*Testhashs32Fnv1a*/, 4 /*int*/, 4, false)
      && verifier.VerifyField(tablePos, 46 /*Testhashu32Fnv1a*/, 4 /*uint*/, 4, false)
      && verifier.VerifyField(tablePos, 48 /*Testhashs64Fnv1a*/, 8 /*long*/, 8, false)
      && verifier.VerifyField(tablePos, 50 /*Testhashu64Fnv1a*/, 8 /*ulong*/, 8, false)
      && verifier.VerifyVectorOfData(tablePos, 52 /*Testarrayofbools*/, 1 /*bool*/, false)
      && verifier.VerifyField(tablePos, 54 /*Testf*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 56 /*Testf2*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 58 /*Testf3*/, 4 /*float*/, 4, false)
      && verifier.VerifyVectorOfStrings(tablePos, 60 /*Testarrayofstring2*/, false)
      && verifier.VerifyVectorOfData(tablePos, 62 /*Testarrayofsortedstruct*/, 8 /*MyGame.Example.Ability*/, false)
      && verifier.VerifyNestedBuffer(tablePos, 64 /*Flex*/, null, false)
      && verifier.VerifyVectorOfData(tablePos, 66 /*Test5*/, 4 /*MyGame.Example.Test*/, false)
      && verifier.VerifyVectorOfData(tablePos, 68 /*VectorOfLongs*/, 8 /*long*/, false)
      && verifier.VerifyVectorOfData(tablePos, 70 /*VectorOfDoubles*/, 8 /*double*/, false)
      && verifier.VerifyTable(tablePos, 72 /*ParentNamespaceTest*/, MyGame.InParentNamespaceVerify.Verify, false)
      && verifier.VerifyVectorOfTables(tablePos, 74 /*VectorOfReferrables*/, MyGame.Example.ReferrableVerify.Verify, false)
      && verifier.VerifyField(tablePos, 76 /*SingleWeakReference*/, 8 /*ulong*/, 8, false)
      && verifier.VerifyVectorOfData(tablePos, 78 /*VectorOfWeakReferences*/, 8 /*ulong*/, false)
      && verifier.VerifyVectorOfTables(tablePos, 80 /*VectorOfStrongReferrables*/, MyGame.Example.ReferrableVerify.Verify, false)
      && verifier.VerifyField(tablePos, 82 /*CoOwningReference*/, 8 /*ulong*/, 8, false)
      && verifier.VerifyVectorOfData(tablePos, 84 /*VectorOfCoOwningReferences*/, 8 /*ulong*/, false)
      && verifier.VerifyField(tablePos, 86 /*NonOwningReference*/, 8 /*ulong*/, 8, false)
      && verifier.VerifyVectorOfData(tablePos, 88 /*VectorOfNonOwningReferences*/, 8 /*ulong*/, false)
      && verifier.VerifyField(tablePos, 90 /*AnyUniqueType*/, 1 /*MyGame.Example.AnyUniqueAliases*/, 1, false)
      && verifier.VerifyUnion(tablePos, 90, 92 /*AnyUnique*/, MyGame.Example.AnyUniqueAliasesVerify.Verify, false)
      && verifier.VerifyField(tablePos, 94 /*AnyAmbiguousType*/, 1 /*MyGame.Example.AnyAmbiguousAliases*/, 1, false)
      && verifier.VerifyUnion(tablePos, 94, 96 /*AnyAmbiguous*/, MyGame.Example.AnyAmbiguousAliasesVerify.Verify, false)
      && verifier.VerifyVectorOfData(tablePos, 98 /*VectorOfEnums*/, 1 /*MyGame.Example.Color*/, false)
      && verifier.VerifyField(tablePos, 100 /*SignedEnum*/, 1 /*MyGame.Example.Race*/, 1, false)
      && verifier.VerifyNestedBuffer(tablePos, 102 /*Testrequirednestedflatbuffer*/, MyGame.Example.MonsterVerify.Verify, false)
      && verifier.VerifyVectorOfTables(tablePos, 104 /*ScalarKeySortedTables*/, MyGame.Example.StatVerify.Verify, false)
      && verifier.VerifyField(tablePos, 106 /*NativeInline*/, 4 /*MyGame.Example.Test*/, 2, false)
      && verifier.VerifyField(tablePos, 108 /*LongEnumNonEnumDefault*/, 8 /*MyGame.Example.LongEnum*/, 8, false)
      && verifier.VerifyField(tablePos, 110 /*LongEnumNormalDefault*/, 8 /*MyGame.Example.LongEnum*/, 8, false)
      && verifier.VerifyField(tablePos, 112 /*NanDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 114 /*InfDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 116 /*PositiveInfDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 118 /*InfinityDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 120 /*PositiveInfinityDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 122 /*NegativeInfDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 124 /*NegativeInfinityDefault*/, 4 /*float*/, 4, false)
      && verifier.VerifyField(tablePos, 126 /*DoubleInfDefault*/, 8 /*double*/, 8, false)
      && verifier.VerifyTableEnd(tablePos);
  }
}

}
