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

/**
 * @enum
 */
export namespace MyGame.Example{
export enum Color{
  Red= 1,
  Green= 2,
  Blue= 8
}};

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

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

  /**
   * @type {number}
   */
  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.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;
};

}
}
/**
 * @constructor
 */
export namespace MyGame.Example2{
export class Monster {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  bb: flatbuffers.ByteBuffer|null = null;

  /**
   * @type {number}
   */
  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.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;
};

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

  /**
   * @type {number}
   */
  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 {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  bb: flatbuffers.ByteBuffer|null = null;

  /**
   * @type {number}
   */
  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);
};

/**
 * @returns {MyGame.Example.Color}
 */
color():MyGame.Example.Color {
  var offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? /** @type {MyGame.Example.Color} */ (this.bb!.readInt8(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!.writeInt8(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;
};

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

  /**
   * @type {number}
   */
  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 /** @type {MyGame.Example.Color} */ (this.bb!.readInt8(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!.writeInt8(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(16, 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 {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  bb: flatbuffers.ByteBuffer|null = null;

  /**
   * @type {number}
   */
  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 {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  bb: flatbuffers.ByteBuffer|null = null;

  /**
   * @type {number}
   */
  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.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;
};

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

  /**
   * @type {number}
   */
  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);
};

/**
 * @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;
};

}
}
/**
 * an example documentation comment: monster object
 *
 * @constructor
 */
export namespace MyGame.Example{
export class Monster {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  bb: flatbuffers.ByteBuffer|null = null;

  /**
   * @type {number}
   */
  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
 * @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 ? /** @type {MyGame.Example.Color} */ (this.bb!.readInt8(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!.writeInt8(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 ? /** @type {MyGame.Example.Any} */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
};

/**
 * @param {MyGame.Example.Any} value
 * @returns {boolean}
 */
mutate_test_type(value:MyGame.Example.Any):boolean {
  var offset = this.bb!.__offset(this.bb_pos, 18);

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

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

/**
 * @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;
};

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

/**
 * @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
 * @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');
};

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

  /**
   * @type {number}
   */
  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);
};

/**
 * @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;
};

}
}
