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

/**
 * Composite components of Monster color.
 *
 * @enum {number}
 */
export namespace MyGame.Example{
export enum Color{
  Red= 1,

  /**
   * \brief color Green
   * Green is bit_flag with value (1u << 1)
   */
  Green= 2,

  /**
   * \brief color Blue (1u << 3)
   */
  Blue= 8
}};

/**
 * @enum {number}
 */
export namespace MyGame.Example{
export enum Race{
  None= -1,
  Human= 0,
  Dwarf= 1,
  Elf= 2
}};

/**
 * @enum {number}
 */
export namespace MyGame.Example{
export enum Any{
  NONE= 0,
  Monster= 1,
  TestSimpleTableWithEnum= 2,
  MyGame_Example2_Monster= 3
}};

/**
 * @enum {number}
 */
export namespace MyGame.Example{
export enum AnyUniqueAliases{
  NONE= 0,
  M= 1,
  TS= 2,
  M2= 3
}};

/**
 * @enum {number}
 */
export namespace MyGame.Example{
export enum AnyAmbiguousAliases{
  NONE= 0,
  M1= 1,
  M2= 2,
  M3= 3
}};

/**
 * @constructor
 */
export namespace MyGame{
export class InParentNamespace {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns InParentNamespace
 */
__init(i:number, bb:flatbuffers.ByteBuffer):InParentNamespace {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param InParentNamespace= obj
 * @returns InParentNamespace
 */
static getRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
  return (obj || new InParentNamespace()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param InParentNamespace= obj
 * @returns InParentNamespace
 */
static getSizePrefixedRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new InParentNamespace()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.Builder builder
 */
static startInParentNamespace(builder:flatbuffers.Builder) {
  builder.startObject(0);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset {
  InParentNamespace.startInParentNamespace(builder);
  return InParentNamespace.endInParentNamespace(builder);
}
}
}
/**
 * @constructor
 */
export namespace MyGame.Example2{
export class Monster {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Monster
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Monster= obj
 * @returns Monster
 */
static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
  return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Monster= obj
 * @returns Monster
 */
static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.Builder builder
 */
static startMonster(builder:flatbuffers.Builder) {
  builder.startObject(0);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
  Monster.startMonster(builder);
  return Monster.endMonster(builder);
}
}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class Test {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Test
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Test {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @returns number
 */
a():number {
  return this.bb!.readInt16(this.bb_pos);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_a(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 0);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt16(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
b():number {
  return this.bb!.readInt8(this.bb_pos + 2);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_b(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 2);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt8(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 * @param number a
 * @param number b
 * @returns flatbuffers.Offset
 */
static createTest(builder:flatbuffers.Builder, a: number, b: number):flatbuffers.Offset {
  builder.prep(2, 4);
  builder.pad(1);
  builder.writeInt8(b);
  builder.writeInt16(a);
  return builder.offset();
};

}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class TestSimpleTableWithEnum {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns TestSimpleTableWithEnum
 */
__init(i:number, bb:flatbuffers.ByteBuffer):TestSimpleTableWithEnum {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param TestSimpleTableWithEnum= obj
 * @returns TestSimpleTableWithEnum
 */
static getRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
  return (obj || new TestSimpleTableWithEnum()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param TestSimpleTableWithEnum= obj
 * @returns TestSimpleTableWithEnum
 */
static getSizePrefixedRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new TestSimpleTableWithEnum()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @returns MyGame.Example.Color
 */
color():MyGame.Example.Color {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
};

/**
 * @param MyGame.Example.Color value
 * @returns boolean
 */
mutate_color(value:MyGame.Example.Color):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint8(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 */
static startTestSimpleTableWithEnum(builder:flatbuffers.Builder) {
  builder.startObject(1);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.Color color
 */
static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
  builder.addFieldInt8(0, color, MyGame.Example.Color.Green);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endTestSimpleTableWithEnum(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createTestSimpleTableWithEnum(builder:flatbuffers.Builder, color:MyGame.Example.Color):flatbuffers.Offset {
  TestSimpleTableWithEnum.startTestSimpleTableWithEnum(builder);
  TestSimpleTableWithEnum.addColor(builder, color);
  return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
}
}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class Vec3 {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Vec3
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Vec3 {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @returns number
 */
x():number {
  return this.bb!.readFloat32(this.bb_pos);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_x(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 0);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
y():number {
  return this.bb!.readFloat32(this.bb_pos + 4);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_y(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
z():number {
  return this.bb!.readFloat32(this.bb_pos + 8);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_z(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 8);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
test1():number {
  return this.bb!.readFloat64(this.bb_pos + 16);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_test1(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 16);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns MyGame.Example.Color
 */
test2():MyGame.Example.Color {
  return /**  */ (this.bb!.readUint8(this.bb_pos + 24));
};

/**
 * @param MyGame.Example.Color value
 * @returns boolean
 */
mutate_test2(value:MyGame.Example.Color):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 24);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint8(this.bb_pos + offset, value);
  return true;
};

/**
 * @param MyGame.Example.Test= obj
 * @returns MyGame.Example.Test|null
 */
test3(obj?:MyGame.Example.Test):MyGame.Example.Test|null {
  return (obj || new MyGame.Example.Test()).__init(this.bb_pos + 26, this.bb!);
};

/**
 * @param flatbuffers.Builder builder
 * @param number x
 * @param number y
 * @param number z
 * @param number test1
 * @param MyGame.Example.Color test2
 * @param number test3_a
 * @param number test3_b
 * @returns flatbuffers.Offset
 */
static createVec3(builder:flatbuffers.Builder, x: number, y: number, z: number, test1: number, test2: MyGame.Example.Color, test3_a: number, test3_b: number):flatbuffers.Offset {
  builder.prep(8, 32);
  builder.pad(2);
  builder.prep(2, 4);
  builder.pad(1);
  builder.writeInt8(test3_b);
  builder.writeInt16(test3_a);
  builder.pad(1);
  builder.writeInt8(test2);
  builder.writeFloat64(test1);
  builder.pad(4);
  builder.writeFloat32(z);
  builder.writeFloat32(y);
  builder.writeFloat32(x);
  return builder.offset();
};

}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class Ability {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Ability
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Ability {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @returns number
 */
id():number {
  return this.bb!.readUint32(this.bb_pos);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_id(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 0);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
distance():number {
  return this.bb!.readUint32(this.bb_pos + 4);
};

/**
 * @param number value
 * @returns boolean
 */
mutate_distance(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint32(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 * @param number id
 * @param number distance
 * @returns flatbuffers.Offset
 */
static createAbility(builder:flatbuffers.Builder, id: number, distance: number):flatbuffers.Offset {
  builder.prep(4, 8);
  builder.writeInt32(distance);
  builder.writeInt32(id);
  return builder.offset();
};

}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class Stat {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Stat
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Stat {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Stat= obj
 * @returns Stat
 */
static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
  return (obj || new Stat()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Stat= obj
 * @returns Stat
 */
static getSizePrefixedRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new Stat()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.Encoding= optionalEncoding
 * @returns string|Uint8Array|null
 */
id():string|null
id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
id(optionalEncoding?:any):string|Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
};

/**
 * @returns flatbuffers.Long
 */
val():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 6);
  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_val(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 6);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
count():number {
  var offset = this.bb!.__offset(this.bb_pos, 8);
  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_count(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 8);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint16(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 */
static startStat(builder:flatbuffers.Builder) {
  builder.startObject(3);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset idOffset
 */
static addId(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset) {
  builder.addFieldOffset(0, idOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long val
 */
static addVal(builder:flatbuffers.Builder, val:flatbuffers.Long) {
  builder.addFieldInt64(1, val, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param number count
 */
static addCount(builder:flatbuffers.Builder, count:number) {
  builder.addFieldInt16(2, count, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endStat(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createStat(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset, val:flatbuffers.Long, count:number):flatbuffers.Offset {
  Stat.startStat(builder);
  Stat.addId(builder, idOffset);
  Stat.addVal(builder, val);
  Stat.addCount(builder, count);
  return Stat.endStat(builder);
}
}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class Referrable {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Referrable
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Referrable {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Referrable= obj
 * @returns Referrable
 */
static getRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
  return (obj || new Referrable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Referrable= obj
 * @returns Referrable
 */
static getSizePrefixedRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new Referrable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @returns flatbuffers.Long
 */
id():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_id(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 */
static startReferrable(builder:flatbuffers.Builder) {
  builder.startObject(1);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long id
 */
static addId(builder:flatbuffers.Builder, id:flatbuffers.Long) {
  builder.addFieldInt64(0, id, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endReferrable(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createReferrable(builder:flatbuffers.Builder, id:flatbuffers.Long):flatbuffers.Offset {
  Referrable.startReferrable(builder);
  Referrable.addId(builder, id);
  return Referrable.endReferrable(builder);
}
}
}
/**
 * an example documentation comment: "monster object"
 *
 * @constructor
 */
export namespace MyGame.Example{
export class Monster {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns Monster
 */
__init(i:number, bb:flatbuffers.ByteBuffer):Monster {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Monster= obj
 * @returns Monster
 */
static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
  return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param Monster= obj
 * @returns Monster
 */
static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @returns boolean
 */
static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
  return bb.__has_identifier('MONS');
};

/**
 * @param MyGame.Example.Vec3= obj
 * @returns MyGame.Example.Vec3|null
 */
pos(obj?:MyGame.Example.Vec3):MyGame.Example.Vec3|null {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? (obj || new MyGame.Example.Vec3()).__init(this.bb_pos + offset, this.bb!) : null;
};

/**
 * @returns number
 */
mana():number {
  var offset = this.bb!.__offset(this.bb_pos, 6);
  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 150;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_mana(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 6);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt16(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
hp():number {
  var offset = this.bb!.__offset(this.bb_pos, 8);
  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 100;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_hp(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 8);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt16(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Encoding= optionalEncoding
 * @returns string|Uint8Array|null
 */
name():string|null
name(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
name(optionalEncoding?:any):string|Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 10);
  return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
};

/**
 * @param number index
 * @returns number
 */
inventory(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 14);
  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
};

/**
 * @returns number
 */
inventoryLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 14);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Uint8Array
 */
inventoryArray():Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 14);
  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @returns MyGame.Example.Color
 */
color():MyGame.Example.Color {
  var offset = this.bb!.__offset(this.bb_pos, 16);
  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
};

/**
 * @param MyGame.Example.Color value
 * @returns boolean
 */
mutate_color(value:MyGame.Example.Color):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 16);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint8(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns MyGame.Example.Any
 */
testType():MyGame.Example.Any {
  var offset = this.bb!.__offset(this.bb_pos, 18);
  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
};

/**
 * @param flatbuffers.Table obj
 * @returns ?flatbuffers.Table
 */
test<T extends flatbuffers.Table>(obj:T):T|null {
  var offset = this.bb!.__offset(this.bb_pos, 20);
  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
};

/**
 * @param number index
 * @param MyGame.Example.Test= obj
 * @returns MyGame.Example.Test
 */
test4(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
  var offset = this.bb!.__offset(this.bb_pos, 22);
  return offset ? (obj || new MyGame.Example.Test()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
};

/**
 * @returns number
 */
test4Length():number {
  var offset = this.bb!.__offset(this.bb_pos, 22);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @param flatbuffers.Encoding= optionalEncoding
 * @returns string|Uint8Array
 */
testarrayofstring(index: number):string
testarrayofstring(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
testarrayofstring(index: number,optionalEncoding?:any):string|Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 24);
  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};

/**
 * @returns number
 */
testarrayofstringLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 24);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * an example documentation comment: this will end up in the generated code
 * multiline too
 *
 * @param number index
 * @param MyGame.Example.Monster= obj
 * @returns MyGame.Example.Monster
 */
testarrayoftables(index: number, obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
  var offset = this.bb!.__offset(this.bb_pos, 26);
  return offset ? (obj || new MyGame.Example.Monster()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};

/**
 * @returns number
 */
testarrayoftablesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 26);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param MyGame.Example.Monster= obj
 * @returns MyGame.Example.Monster|null
 */
enemy(obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
  var offset = this.bb!.__offset(this.bb_pos, 28);
  return offset ? (obj || new MyGame.Example.Monster()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};

/**
 * @param number index
 * @returns number
 */
testnestedflatbuffer(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 30);
  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
};

/**
 * @returns number
 */
testnestedflatbufferLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 30);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Uint8Array
 */
testnestedflatbufferArray():Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 30);
  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @param MyGame.Example.Stat= obj
 * @returns MyGame.Example.Stat|null
 */
testempty(obj?:MyGame.Example.Stat):MyGame.Example.Stat|null {
  var offset = this.bb!.__offset(this.bb_pos, 32);
  return offset ? (obj || new MyGame.Example.Stat()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};

/**
 * @returns boolean
 */
testbool():boolean {
  var offset = this.bb!.__offset(this.bb_pos, 34);
  return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
};

/**
 * @param boolean value
 * @returns boolean
 */
mutate_testbool(value:boolean):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 34);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt8(this.bb_pos + offset, +value);
  return true;
};

/**
 * @returns number
 */
testhashs32Fnv1():number {
  var offset = this.bb!.__offset(this.bb_pos, 36);
  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testhashs32_fnv1(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 36);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
testhashu32Fnv1():number {
  var offset = this.bb!.__offset(this.bb_pos, 38);
  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testhashu32_fnv1(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 38);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
testhashs64Fnv1():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 40);
  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_testhashs64_fnv1(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 40);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
testhashu64Fnv1():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 42);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_testhashu64_fnv1(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 42);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
testhashs32Fnv1a():number {
  var offset = this.bb!.__offset(this.bb_pos, 44);
  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testhashs32_fnv1a(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 44);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
testhashu32Fnv1a():number {
  var offset = this.bb!.__offset(this.bb_pos, 46);
  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testhashu32_fnv1a(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 46);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
testhashs64Fnv1a():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 48);
  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_testhashs64_fnv1a(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 48);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
testhashu64Fnv1a():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 50);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_testhashu64_fnv1a(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 50);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @returns boolean
 */
testarrayofbools(index: number):boolean|null {
  var offset = this.bb!.__offset(this.bb_pos, 52);
  return offset ? !!this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : false;
};

/**
 * @returns number
 */
testarrayofboolsLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 52);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Int8Array
 */
testarrayofboolsArray():Int8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 52);
  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @returns number
 */
testf():number {
  var offset = this.bb!.__offset(this.bb_pos, 54);
  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.14159;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testf(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 54);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
testf2():number {
  var offset = this.bb!.__offset(this.bb_pos, 56);
  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 3.0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testf2(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 56);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
testf3():number {
  var offset = this.bb!.__offset(this.bb_pos, 58);
  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_testf3(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 58);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @param flatbuffers.Encoding= optionalEncoding
 * @returns string|Uint8Array
 */
testarrayofstring2(index: number):string
testarrayofstring2(index: number,optionalEncoding:flatbuffers.Encoding):string|Uint8Array
testarrayofstring2(index: number,optionalEncoding?:any):string|Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 60);
  return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};

/**
 * @returns number
 */
testarrayofstring2Length():number {
  var offset = this.bb!.__offset(this.bb_pos, 60);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @param MyGame.Example.Ability= obj
 * @returns MyGame.Example.Ability
 */
testarrayofsortedstruct(index: number, obj?:MyGame.Example.Ability):MyGame.Example.Ability|null {
  var offset = this.bb!.__offset(this.bb_pos, 62);
  return offset ? (obj || new MyGame.Example.Ability()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null;
};

/**
 * @returns number
 */
testarrayofsortedstructLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 62);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @returns number
 */
flex(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 64);
  return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
};

/**
 * @returns number
 */
flexLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 64);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Uint8Array
 */
flexArray():Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 64);
  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @param number index
 * @param MyGame.Example.Test= obj
 * @returns MyGame.Example.Test
 */
test5(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
  var offset = this.bb!.__offset(this.bb_pos, 66);
  return offset ? (obj || new MyGame.Example.Test()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
};

/**
 * @returns number
 */
test5Length():number {
  var offset = this.bb!.__offset(this.bb_pos, 66);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @returns flatbuffers.Long
 */
vectorOfLongs(index: number):flatbuffers.Long|null {
  var offset = this.bb!.__offset(this.bb_pos, 68);
  return offset ? this.bb!.readInt64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
};

/**
 * @returns number
 */
vectorOfLongsLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 68);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @returns number
 */
vectorOfDoubles(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 70);
  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
};

/**
 * @returns number
 */
vectorOfDoublesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 70);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Float64Array
 */
vectorOfDoublesArray():Float64Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 70);
  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @param MyGame.InParentNamespace= obj
 * @returns MyGame.InParentNamespace|null
 */
parentNamespaceTest(obj?:MyGame.InParentNamespace):MyGame.InParentNamespace|null {
  var offset = this.bb!.__offset(this.bb_pos, 72);
  return offset ? (obj || new MyGame.InParentNamespace()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};

/**
 * @param number index
 * @param MyGame.Example.Referrable= obj
 * @returns MyGame.Example.Referrable
 */
vectorOfReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
  var offset = this.bb!.__offset(this.bb_pos, 74);
  return offset ? (obj || new MyGame.Example.Referrable()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};

/**
 * @returns number
 */
vectorOfReferrablesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 74);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns flatbuffers.Long
 */
singleWeakReference():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 76);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_single_weak_reference(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 76);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @returns flatbuffers.Long
 */
vectorOfWeakReferences(index: number):flatbuffers.Long|null {
  var offset = this.bb!.__offset(this.bb_pos, 78);
  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
};

/**
 * @returns number
 */
vectorOfWeakReferencesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 78);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @param number index
 * @param MyGame.Example.Referrable= obj
 * @returns MyGame.Example.Referrable
 */
vectorOfStrongReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
  var offset = this.bb!.__offset(this.bb_pos, 80);
  return offset ? (obj || new MyGame.Example.Referrable()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};

/**
 * @returns number
 */
vectorOfStrongReferrablesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 80);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns flatbuffers.Long
 */
coOwningReference():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 82);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_co_owning_reference(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 82);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @returns flatbuffers.Long
 */
vectorOfCoOwningReferences(index: number):flatbuffers.Long|null {
  var offset = this.bb!.__offset(this.bb_pos, 84);
  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
};

/**
 * @returns number
 */
vectorOfCoOwningReferencesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 84);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns flatbuffers.Long
 */
nonOwningReference():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 86);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_non_owning_reference(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 86);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @returns flatbuffers.Long
 */
vectorOfNonOwningReferences(index: number):flatbuffers.Long|null {
  var offset = this.bb!.__offset(this.bb_pos, 88);
  return offset ? this.bb!.readUint64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : this.bb!.createLong(0, 0);
};

/**
 * @returns number
 */
vectorOfNonOwningReferencesLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 88);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns MyGame.Example.AnyUniqueAliases
 */
anyUniqueType():MyGame.Example.AnyUniqueAliases {
  var offset = this.bb!.__offset(this.bb_pos, 90);
  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
};

/**
 * @param flatbuffers.Table obj
 * @returns ?flatbuffers.Table
 */
anyUnique<T extends flatbuffers.Table>(obj:T):T|null {
  var offset = this.bb!.__offset(this.bb_pos, 92);
  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
};

/**
 * @returns MyGame.Example.AnyAmbiguousAliases
 */
anyAmbiguousType():MyGame.Example.AnyAmbiguousAliases {
  var offset = this.bb!.__offset(this.bb_pos, 94);
  return offset ? /**  */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
};

/**
 * @param flatbuffers.Table obj
 * @returns ?flatbuffers.Table
 */
anyAmbiguous<T extends flatbuffers.Table>(obj:T):T|null {
  var offset = this.bb!.__offset(this.bb_pos, 96);
  return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
};

/**
 * @param number index
 * @returns MyGame.Example.Color
 */
vectorOfEnums(index: number):MyGame.Example.Color|null {
  var offset = this.bb!.__offset(this.bb_pos, 98);
  return offset ? /**  */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /**  */ (0);
};

/**
 * @returns number
 */
vectorOfEnumsLength():number {
  var offset = this.bb!.__offset(this.bb_pos, 98);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Uint8Array
 */
vectorOfEnumsArray():Uint8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 98);
  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @returns MyGame.Example.Race
 */
signedEnum():MyGame.Example.Race {
  var offset = this.bb!.__offset(this.bb_pos, 100);
  return offset ? /**  */ (this.bb!.readInt8(this.bb_pos + offset)) : MyGame.Example.Race.None;
};

/**
 * @param MyGame.Example.Race value
 * @returns boolean
 */
mutate_signed_enum(value:MyGame.Example.Race):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 100);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt8(this.bb_pos + offset, value);
  return true;
};

/**
 * @param flatbuffers.Builder builder
 */
static startMonster(builder:flatbuffers.Builder) {
  builder.startObject(49);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset posOffset
 */
static addPos(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset) {
  builder.addFieldStruct(0, posOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number mana
 */
static addMana(builder:flatbuffers.Builder, mana:number) {
  builder.addFieldInt16(1, mana, 150);
};

/**
 * @param flatbuffers.Builder builder
 * @param number hp
 */
static addHp(builder:flatbuffers.Builder, hp:number) {
  builder.addFieldInt16(2, hp, 100);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset nameOffset
 */
static addName(builder:flatbuffers.Builder, nameOffset:flatbuffers.Offset) {
  builder.addFieldOffset(3, nameOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset inventoryOffset
 */
static addInventory(builder:flatbuffers.Builder, inventoryOffset:flatbuffers.Offset) {
  builder.addFieldOffset(5, inventoryOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createInventoryVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startInventoryVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.Color color
 */
static addColor(builder:flatbuffers.Builder, color:MyGame.Example.Color) {
  builder.addFieldInt8(6, color, MyGame.Example.Color.Blue);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.Any testType
 */
static addTestType(builder:flatbuffers.Builder, testType:MyGame.Example.Any) {
  builder.addFieldInt8(7, testType, MyGame.Example.Any.NONE);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testOffset
 */
static addTest(builder:flatbuffers.Builder, testOffset:flatbuffers.Offset) {
  builder.addFieldOffset(8, testOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset test4Offset
 */
static addTest4(builder:flatbuffers.Builder, test4Offset:flatbuffers.Offset) {
  builder.addFieldOffset(9, test4Offset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTest4Vector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 2);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testarrayofstringOffset
 */
static addTestarrayofstring(builder:flatbuffers.Builder, testarrayofstringOffset:flatbuffers.Offset) {
  builder.addFieldOffset(10, testarrayofstringOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Offset> data
 * @returns flatbuffers.Offset
 */
static createTestarrayofstringVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
  builder.startVector(4, data.length, 4);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addOffset(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestarrayofstringVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testarrayoftablesOffset
 */
static addTestarrayoftables(builder:flatbuffers.Builder, testarrayoftablesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(11, testarrayoftablesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Offset> data
 * @returns flatbuffers.Offset
 */
static createTestarrayoftablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
  builder.startVector(4, data.length, 4);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addOffset(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestarrayoftablesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset enemyOffset
 */
static addEnemy(builder:flatbuffers.Builder, enemyOffset:flatbuffers.Offset) {
  builder.addFieldOffset(12, enemyOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testnestedflatbufferOffset
 */
static addTestnestedflatbuffer(builder:flatbuffers.Builder, testnestedflatbufferOffset:flatbuffers.Offset) {
  builder.addFieldOffset(13, testnestedflatbufferOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createTestnestedflatbufferVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestnestedflatbufferVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testemptyOffset
 */
static addTestempty(builder:flatbuffers.Builder, testemptyOffset:flatbuffers.Offset) {
  builder.addFieldOffset(14, testemptyOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param boolean testbool
 */
static addTestbool(builder:flatbuffers.Builder, testbool:boolean) {
  builder.addFieldInt8(15, +testbool, +false);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testhashs32Fnv1
 */
static addTesthashs32Fnv1(builder:flatbuffers.Builder, testhashs32Fnv1:number) {
  builder.addFieldInt32(16, testhashs32Fnv1, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testhashu32Fnv1
 */
static addTesthashu32Fnv1(builder:flatbuffers.Builder, testhashu32Fnv1:number) {
  builder.addFieldInt32(17, testhashu32Fnv1, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long testhashs64Fnv1
 */
static addTesthashs64Fnv1(builder:flatbuffers.Builder, testhashs64Fnv1:flatbuffers.Long) {
  builder.addFieldInt64(18, testhashs64Fnv1, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long testhashu64Fnv1
 */
static addTesthashu64Fnv1(builder:flatbuffers.Builder, testhashu64Fnv1:flatbuffers.Long) {
  builder.addFieldInt64(19, testhashu64Fnv1, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param number testhashs32Fnv1a
 */
static addTesthashs32Fnv1a(builder:flatbuffers.Builder, testhashs32Fnv1a:number) {
  builder.addFieldInt32(20, testhashs32Fnv1a, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testhashu32Fnv1a
 */
static addTesthashu32Fnv1a(builder:flatbuffers.Builder, testhashu32Fnv1a:number) {
  builder.addFieldInt32(21, testhashu32Fnv1a, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long testhashs64Fnv1a
 */
static addTesthashs64Fnv1a(builder:flatbuffers.Builder, testhashs64Fnv1a:flatbuffers.Long) {
  builder.addFieldInt64(22, testhashs64Fnv1a, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long testhashu64Fnv1a
 */
static addTesthashu64Fnv1a(builder:flatbuffers.Builder, testhashu64Fnv1a:flatbuffers.Long) {
  builder.addFieldInt64(23, testhashu64Fnv1a, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testarrayofboolsOffset
 */
static addTestarrayofbools(builder:flatbuffers.Builder, testarrayofboolsOffset:flatbuffers.Offset) {
  builder.addFieldOffset(24, testarrayofboolsOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<boolean> data
 * @returns flatbuffers.Offset
 */
static createTestarrayofboolsVector(builder:flatbuffers.Builder, data:boolean[]):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(+data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestarrayofboolsVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testf
 */
static addTestf(builder:flatbuffers.Builder, testf:number) {
  builder.addFieldFloat32(25, testf, 3.14159);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testf2
 */
static addTestf2(builder:flatbuffers.Builder, testf2:number) {
  builder.addFieldFloat32(26, testf2, 3.0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number testf3
 */
static addTestf3(builder:flatbuffers.Builder, testf3:number) {
  builder.addFieldFloat32(27, testf3, 0.0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testarrayofstring2Offset
 */
static addTestarrayofstring2(builder:flatbuffers.Builder, testarrayofstring2Offset:flatbuffers.Offset) {
  builder.addFieldOffset(28, testarrayofstring2Offset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Offset> data
 * @returns flatbuffers.Offset
 */
static createTestarrayofstring2Vector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
  builder.startVector(4, data.length, 4);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addOffset(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestarrayofstring2Vector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset testarrayofsortedstructOffset
 */
static addTestarrayofsortedstruct(builder:flatbuffers.Builder, testarrayofsortedstructOffset:flatbuffers.Offset) {
  builder.addFieldOffset(29, testarrayofsortedstructOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTestarrayofsortedstructVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset flexOffset
 */
static addFlex(builder:flatbuffers.Builder, flexOffset:flatbuffers.Offset) {
  builder.addFieldOffset(30, flexOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createFlexVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startFlexVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset test5Offset
 */
static addTest5(builder:flatbuffers.Builder, test5Offset:flatbuffers.Offset) {
  builder.addFieldOffset(31, test5Offset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startTest5Vector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 2);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfLongsOffset
 */
static addVectorOfLongs(builder:flatbuffers.Builder, vectorOfLongsOffset:flatbuffers.Offset) {
  builder.addFieldOffset(32, vectorOfLongsOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Long> data
 * @returns flatbuffers.Offset
 */
static createVectorOfLongsVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfLongsVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfDoublesOffset
 */
static addVectorOfDoubles(builder:flatbuffers.Builder, vectorOfDoublesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(33, vectorOfDoublesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createVectorOfDoublesVector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addFloat64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfDoublesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset parentNamespaceTestOffset
 */
static addParentNamespaceTest(builder:flatbuffers.Builder, parentNamespaceTestOffset:flatbuffers.Offset) {
  builder.addFieldOffset(34, parentNamespaceTestOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfReferrablesOffset
 */
static addVectorOfReferrables(builder:flatbuffers.Builder, vectorOfReferrablesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(35, vectorOfReferrablesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Offset> data
 * @returns flatbuffers.Offset
 */
static createVectorOfReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
  builder.startVector(4, data.length, 4);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addOffset(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long singleWeakReference
 */
static addSingleWeakReference(builder:flatbuffers.Builder, singleWeakReference:flatbuffers.Long) {
  builder.addFieldInt64(36, singleWeakReference, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfWeakReferencesOffset
 */
static addVectorOfWeakReferences(builder:flatbuffers.Builder, vectorOfWeakReferencesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(37, vectorOfWeakReferencesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Long> data
 * @returns flatbuffers.Offset
 */
static createVectorOfWeakReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfWeakReferencesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfStrongReferrablesOffset
 */
static addVectorOfStrongReferrables(builder:flatbuffers.Builder, vectorOfStrongReferrablesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(38, vectorOfStrongReferrablesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Offset> data
 * @returns flatbuffers.Offset
 */
static createVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
  builder.startVector(4, data.length, 4);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addOffset(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfStrongReferrablesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(4, numElems, 4);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long coOwningReference
 */
static addCoOwningReference(builder:flatbuffers.Builder, coOwningReference:flatbuffers.Long) {
  builder.addFieldInt64(39, coOwningReference, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfCoOwningReferencesOffset
 */
static addVectorOfCoOwningReferences(builder:flatbuffers.Builder, vectorOfCoOwningReferencesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(40, vectorOfCoOwningReferencesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Long> data
 * @returns flatbuffers.Offset
 */
static createVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfCoOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long nonOwningReference
 */
static addNonOwningReference(builder:flatbuffers.Builder, nonOwningReference:flatbuffers.Long) {
  builder.addFieldInt64(41, nonOwningReference, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfNonOwningReferencesOffset
 */
static addVectorOfNonOwningReferences(builder:flatbuffers.Builder, vectorOfNonOwningReferencesOffset:flatbuffers.Offset) {
  builder.addFieldOffset(42, vectorOfNonOwningReferencesOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<flatbuffers.Long> data
 * @returns flatbuffers.Offset
 */
static createVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, data:flatbuffers.Long[]):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfNonOwningReferencesVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.AnyUniqueAliases anyUniqueType
 */
static addAnyUniqueType(builder:flatbuffers.Builder, anyUniqueType:MyGame.Example.AnyUniqueAliases) {
  builder.addFieldInt8(43, anyUniqueType, MyGame.Example.AnyUniqueAliases.NONE);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset anyUniqueOffset
 */
static addAnyUnique(builder:flatbuffers.Builder, anyUniqueOffset:flatbuffers.Offset) {
  builder.addFieldOffset(44, anyUniqueOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.AnyAmbiguousAliases anyAmbiguousType
 */
static addAnyAmbiguousType(builder:flatbuffers.Builder, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases) {
  builder.addFieldInt8(45, anyAmbiguousType, MyGame.Example.AnyAmbiguousAliases.NONE);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset anyAmbiguousOffset
 */
static addAnyAmbiguous(builder:flatbuffers.Builder, anyAmbiguousOffset:flatbuffers.Offset) {
  builder.addFieldOffset(46, anyAmbiguousOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vectorOfEnumsOffset
 */
static addVectorOfEnums(builder:flatbuffers.Builder, vectorOfEnumsOffset:flatbuffers.Offset) {
  builder.addFieldOffset(47, vectorOfEnumsOffset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<MyGame.Example.Color> data
 * @returns flatbuffers.Offset
 */
static createVectorOfEnumsVector(builder:flatbuffers.Builder, data:MyGame.Example.Color[]):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVectorOfEnumsVector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param MyGame.Example.Race signedEnum
 */
static addSignedEnum(builder:flatbuffers.Builder, signedEnum:MyGame.Example.Race) {
  builder.addFieldInt8(48, signedEnum, MyGame.Example.Race.None);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  builder.requiredField(offset, 10); // name
  return offset;
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset offset
 */
static finishMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
  builder.finish(offset, 'MONS');
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset offset
 */
static finishSizePrefixedMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
  builder.finish(offset, 'MONS', true);
};

static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, mana:number, hp:number, nameOffset:flatbuffers.Offset, inventoryOffset:flatbuffers.Offset, color:MyGame.Example.Color, testType:MyGame.Example.Any, testOffset:flatbuffers.Offset, test4Offset:flatbuffers.Offset, testarrayofstringOffset:flatbuffers.Offset, testarrayoftablesOffset:flatbuffers.Offset, enemyOffset:flatbuffers.Offset, testnestedflatbufferOffset:flatbuffers.Offset, testemptyOffset:flatbuffers.Offset, testbool:boolean, testhashs32Fnv1:number, testhashu32Fnv1:number, testhashs64Fnv1:flatbuffers.Long, testhashu64Fnv1:flatbuffers.Long, testhashs32Fnv1a:number, testhashu32Fnv1a:number, testhashs64Fnv1a:flatbuffers.Long, testhashu64Fnv1a:flatbuffers.Long, testarrayofboolsOffset:flatbuffers.Offset, testf:number, testf2:number, testf3:number, testarrayofstring2Offset:flatbuffers.Offset, testarrayofsortedstructOffset:flatbuffers.Offset, flexOffset:flatbuffers.Offset, test5Offset:flatbuffers.Offset, vectorOfLongsOffset:flatbuffers.Offset, vectorOfDoublesOffset:flatbuffers.Offset, parentNamespaceTestOffset:flatbuffers.Offset, vectorOfReferrablesOffset:flatbuffers.Offset, singleWeakReference:flatbuffers.Long, vectorOfWeakReferencesOffset:flatbuffers.Offset, vectorOfStrongReferrablesOffset:flatbuffers.Offset, coOwningReference:flatbuffers.Long, vectorOfCoOwningReferencesOffset:flatbuffers.Offset, nonOwningReference:flatbuffers.Long, vectorOfNonOwningReferencesOffset:flatbuffers.Offset, anyUniqueType:MyGame.Example.AnyUniqueAliases, anyUniqueOffset:flatbuffers.Offset, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases, anyAmbiguousOffset:flatbuffers.Offset, vectorOfEnumsOffset:flatbuffers.Offset, signedEnum:MyGame.Example.Race):flatbuffers.Offset {
  Monster.startMonster(builder);
  Monster.addPos(builder, posOffset);
  Monster.addMana(builder, mana);
  Monster.addHp(builder, hp);
  Monster.addName(builder, nameOffset);
  Monster.addInventory(builder, inventoryOffset);
  Monster.addColor(builder, color);
  Monster.addTestType(builder, testType);
  Monster.addTest(builder, testOffset);
  Monster.addTest4(builder, test4Offset);
  Monster.addTestarrayofstring(builder, testarrayofstringOffset);
  Monster.addTestarrayoftables(builder, testarrayoftablesOffset);
  Monster.addEnemy(builder, enemyOffset);
  Monster.addTestnestedflatbuffer(builder, testnestedflatbufferOffset);
  Monster.addTestempty(builder, testemptyOffset);
  Monster.addTestbool(builder, testbool);
  Monster.addTesthashs32Fnv1(builder, testhashs32Fnv1);
  Monster.addTesthashu32Fnv1(builder, testhashu32Fnv1);
  Monster.addTesthashs64Fnv1(builder, testhashs64Fnv1);
  Monster.addTesthashu64Fnv1(builder, testhashu64Fnv1);
  Monster.addTesthashs32Fnv1a(builder, testhashs32Fnv1a);
  Monster.addTesthashu32Fnv1a(builder, testhashu32Fnv1a);
  Monster.addTesthashs64Fnv1a(builder, testhashs64Fnv1a);
  Monster.addTesthashu64Fnv1a(builder, testhashu64Fnv1a);
  Monster.addTestarrayofbools(builder, testarrayofboolsOffset);
  Monster.addTestf(builder, testf);
  Monster.addTestf2(builder, testf2);
  Monster.addTestf3(builder, testf3);
  Monster.addTestarrayofstring2(builder, testarrayofstring2Offset);
  Monster.addTestarrayofsortedstruct(builder, testarrayofsortedstructOffset);
  Monster.addFlex(builder, flexOffset);
  Monster.addTest5(builder, test5Offset);
  Monster.addVectorOfLongs(builder, vectorOfLongsOffset);
  Monster.addVectorOfDoubles(builder, vectorOfDoublesOffset);
  Monster.addParentNamespaceTest(builder, parentNamespaceTestOffset);
  Monster.addVectorOfReferrables(builder, vectorOfReferrablesOffset);
  Monster.addSingleWeakReference(builder, singleWeakReference);
  Monster.addVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset);
  Monster.addVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset);
  Monster.addCoOwningReference(builder, coOwningReference);
  Monster.addVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset);
  Monster.addNonOwningReference(builder, nonOwningReference);
  Monster.addVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset);
  Monster.addAnyUniqueType(builder, anyUniqueType);
  Monster.addAnyUnique(builder, anyUniqueOffset);
  Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
  Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
  Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
  Monster.addSignedEnum(builder, signedEnum);
  return Monster.endMonster(builder);
}
}
}
/**
 * @constructor
 */
export namespace MyGame.Example{
export class TypeAliases {
  bb: flatbuffers.ByteBuffer|null = null;

  bb_pos:number = 0;
/**
 * @param number i
 * @param flatbuffers.ByteBuffer bb
 * @returns TypeAliases
 */
__init(i:number, bb:flatbuffers.ByteBuffer):TypeAliases {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param TypeAliases= obj
 * @returns TypeAliases
 */
static getRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
  return (obj || new TypeAliases()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param flatbuffers.ByteBuffer bb
 * @param TypeAliases= obj
 * @returns TypeAliases
 */
static getSizePrefixedRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new TypeAliases()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @returns number
 */
i8():number {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? this.bb!.readInt8(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_i8(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt8(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
u8():number {
  var offset = this.bb!.__offset(this.bb_pos, 6);
  return offset ? this.bb!.readUint8(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_u8(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 6);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint8(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
i16():number {
  var offset = this.bb!.__offset(this.bb_pos, 8);
  return offset ? this.bb!.readInt16(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_i16(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 8);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt16(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
u16():number {
  var offset = this.bb!.__offset(this.bb_pos, 10);
  return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_u16(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 10);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint16(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
i32():number {
  var offset = this.bb!.__offset(this.bb_pos, 12);
  return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_i32(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 12);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
u32():number {
  var offset = this.bb!.__offset(this.bb_pos, 14);
  return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_u32(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 14);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
i64():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 16);
  return offset ? this.bb!.readInt64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_i64(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 16);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns flatbuffers.Long
 */
u64():flatbuffers.Long {
  var offset = this.bb!.__offset(this.bb_pos, 18);
  return offset ? this.bb!.readUint64(this.bb_pos + offset) : this.bb!.createLong(0, 0);
};

/**
 * @param flatbuffers.Long value
 * @returns boolean
 */
mutate_u64(value:flatbuffers.Long):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 18);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeUint64(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
f32():number {
  var offset = this.bb!.__offset(this.bb_pos, 20);
  return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_f32(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 20);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat32(this.bb_pos + offset, value);
  return true;
};

/**
 * @returns number
 */
f64():number {
  var offset = this.bb!.__offset(this.bb_pos, 22);
  return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0;
};

/**
 * @param number value
 * @returns boolean
 */
mutate_f64(value:number):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 22);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeFloat64(this.bb_pos + offset, value);
  return true;
};

/**
 * @param number index
 * @returns number
 */
v8(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 24);
  return offset ? this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
};

/**
 * @returns number
 */
v8Length():number {
  var offset = this.bb!.__offset(this.bb_pos, 24);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Int8Array
 */
v8Array():Int8Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 24);
  return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @param number index
 * @returns number
 */
vf64(index: number):number|null {
  var offset = this.bb!.__offset(this.bb_pos, 26);
  return offset ? this.bb!.readFloat64(this.bb!.__vector(this.bb_pos + offset) + index * 8) : 0;
};

/**
 * @returns number
 */
vf64Length():number {
  var offset = this.bb!.__offset(this.bb_pos, 26);
  return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
};

/**
 * @returns Float64Array
 */
vf64Array():Float64Array|null {
  var offset = this.bb!.__offset(this.bb_pos, 26);
  return offset ? new Float64Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
};

/**
 * @param flatbuffers.Builder builder
 */
static startTypeAliases(builder:flatbuffers.Builder) {
  builder.startObject(12);
};

/**
 * @param flatbuffers.Builder builder
 * @param number i8
 */
static addI8(builder:flatbuffers.Builder, i8:number) {
  builder.addFieldInt8(0, i8, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number u8
 */
static addU8(builder:flatbuffers.Builder, u8:number) {
  builder.addFieldInt8(1, u8, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number i16
 */
static addI16(builder:flatbuffers.Builder, i16:number) {
  builder.addFieldInt16(2, i16, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number u16
 */
static addU16(builder:flatbuffers.Builder, u16:number) {
  builder.addFieldInt16(3, u16, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number i32
 */
static addI32(builder:flatbuffers.Builder, i32:number) {
  builder.addFieldInt32(4, i32, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number u32
 */
static addU32(builder:flatbuffers.Builder, u32:number) {
  builder.addFieldInt32(5, u32, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long i64
 */
static addI64(builder:flatbuffers.Builder, i64:flatbuffers.Long) {
  builder.addFieldInt64(6, i64, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Long u64
 */
static addU64(builder:flatbuffers.Builder, u64:flatbuffers.Long) {
  builder.addFieldInt64(7, u64, builder.createLong(0, 0));
};

/**
 * @param flatbuffers.Builder builder
 * @param number f32
 */
static addF32(builder:flatbuffers.Builder, f32:number) {
  builder.addFieldFloat32(8, f32, 0.0);
};

/**
 * @param flatbuffers.Builder builder
 * @param number f64
 */
static addF64(builder:flatbuffers.Builder, f64:number) {
  builder.addFieldFloat64(9, f64, 0.0);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset v8Offset
 */
static addV8(builder:flatbuffers.Builder, v8Offset:flatbuffers.Offset) {
  builder.addFieldOffset(10, v8Offset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createV8Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(1, data.length, 1);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addInt8(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startV8Vector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(1, numElems, 1);
};

/**
 * @param flatbuffers.Builder builder
 * @param flatbuffers.Offset vf64Offset
 */
static addVf64(builder:flatbuffers.Builder, vf64Offset:flatbuffers.Offset) {
  builder.addFieldOffset(11, vf64Offset, 0);
};

/**
 * @param flatbuffers.Builder builder
 * @param Array.<number> data
 * @returns flatbuffers.Offset
 */
static createVf64Vector(builder:flatbuffers.Builder, data:number[] | Uint8Array):flatbuffers.Offset {
  builder.startVector(8, data.length, 8);
  for (var i = data.length - 1; i >= 0; i--) {
    builder.addFloat64(data[i]);
  }
  return builder.endVector();
};

/**
 * @param flatbuffers.Builder builder
 * @param number numElems
 */
static startVf64Vector(builder:flatbuffers.Builder, numElems:number) {
  builder.startVector(8, numElems, 8);
};

/**
 * @param flatbuffers.Builder builder
 * @returns flatbuffers.Offset
 */
static endTypeAliases(builder:flatbuffers.Builder):flatbuffers.Offset {
  var offset = builder.endObject();
  return offset;
};

static createTypeAliases(builder:flatbuffers.Builder, i8:number, u8:number, i16:number, u16:number, i32:number, u32:number, i64:flatbuffers.Long, u64:flatbuffers.Long, f32:number, f64:number, v8Offset:flatbuffers.Offset, vf64Offset:flatbuffers.Offset):flatbuffers.Offset {
  TypeAliases.startTypeAliases(builder);
  TypeAliases.addI8(builder, i8);
  TypeAliases.addU8(builder, u8);
  TypeAliases.addI16(builder, i16);
  TypeAliases.addU16(builder, u16);
  TypeAliases.addI32(builder, i32);
  TypeAliases.addU32(builder, u32);
  TypeAliases.addI64(builder, i64);
  TypeAliases.addU64(builder, u64);
  TypeAliases.addF32(builder, f32);
  TypeAliases.addF64(builder, f64);
  TypeAliases.addV8(builder, v8Offset);
  TypeAliases.addVf64(builder, vf64Offset);
  return TypeAliases.endTypeAliases(builder);
}
}
}
