colyseus / schema

An incremental binary state serializer with delta encoding for games.
https://docs.colyseus.io/state/schema/
MIT License
129 stars 39 forks source link

[Feature]: null/undefined support for ArraySchema #175

Open mandrillxx opened 1 month ago

mandrillxx commented 1 month ago

Description & Use case

Description: Add the ability to add null/undefined objects within ArraySchema type

currently, this is restricted by this check in src/types/ArraySchema.ts#182

if (value === undefined || value === null) {
   console.error("ArraySchema items cannot be null nor undefined; Use `deleteAt(index)` instead.");
   return;
}

Usecase: My backend for a poker game is already made, and an array is made for the player seating:

export class Table {
   private _tablePlayers = (Player | null)[];

   constructor(numSeats = 4) {
      this._tablePlayers = new Array(numSeats).fill(null);
   }
}

and somebody can join any seat index, meaning the array can look like this:

[
   null,
   null,
   { username: "player" },
   null,
]

but when converting to a schema

export class Table extends Schema {
   @type([Player]) _tablePlayers = new ArraySchema<Player>();

   constructor(numSeats = 4) {
      new Array(numSeats).fill(null).forEach((seat, index) => (this._tablePlayers[index] = seat));
   }
}

this will no longer work, and the array will be empty. as seen in the failing test image

alongside null/undefined being integral parts of typescript/javascript, so maybe exclusively for js ecosystem

Optional: Proposed API

maybe a separate schema type, such as NullableArraySchema

export class NullableArraySchema<V = any> implements Array<V>, SchemaDecoderCallbacks { }
endel commented 1 month ago

Thanks for the suggestion - that'd be a nice addition, can't promise but will try to make it into https://github.com/colyseus/schema/pull/173

For now, I'd suggest inserting empty Player instances instead of having the null values.