Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
mage-parser: networked objects (concept)
// module:
// createGame: create a game instance
// findGames: find all game instances across all game servers
// user commands:
// join: adds actor id to list, returns global game state
// quit: removes actor id
// makeMove: send data
import * as mage from 'mage'
import { networked, rpc, stream } from 'mage-parser'
import Player from './Player'
@networked('GameClassNameOnClient') // Generates a network id on instanciation plz
export class GameState {
public state: mage.core.IState // required by @networked()
public players: Player[] = []
// required by @networked()
// This could be an array instead of a getterß
get actorIds() {
return this.players.map((player) => player.playerId)
}
constructor(initialPlayers: Player[]) {
this.state = new mage.core.State()
this.players = initialPlayers
// todo: game end, and what do we do
// on player disconnect???
}
@stream('onPlayerJoin') // client: interface which must be implemented
public join(player: Player) {
this.players.push(player) // This player will need to receive the Game object!
return player // will be streamed to all actors
}
@rpc('move') // on client: client method - optionally set a different name
public async onPlayerMove(state: mage.core.IState) {
// apply to local state
// change whatever
// return value will be streamed to all known
}
@rpc('addBomb') // on client: client method - optionally set a different name
public async onAddingBomb(state: mage.core.IState) {
const player = this.getPlayerFromState(state)
// Get player position
// Check if player has enough bombs left
// Place bomb (apply to local state)
// apply to local state
// change whatever
// return value will be streamed to all known
this.addBomb(new Bomb(x, y))
}
@stream('onBombAdded')
public async addBomb(bomb: Bomb) {
return bomb
})
@rpc('quit')
public async onPlayerQuit(state: mage.core.IState) {
const player = this.getPlayerFromState(state)
this.players = this.players.filter((p) => p.playerId !== player.playerId)
this.leave(player)
}
@stream('onPlayerLeave')
public leave(player: Player) {
return player.playeId
}
private getPlayerFromState(state: mage.core.IState) {
const player = this.players.find((player) => player.playerId === state.actorId)
if (!player) {
throw new Error('Not part of the game')
}
return player
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment