npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

boardgame-utils

v1.3.43

Published

Utilities to make development in [boardgame.io](https://boardgame.io/) easier.

Downloads

5

Readme

Utilities to make development in boardgame.io easier.

npm install boardgame-utils

You can then import any of the named modules below.

  1. Cards
    1. buildDeck
    2. deck
  2. Grid
    1. buildGrid
    2. getCell
    3. getCoordsFromIndex
    4. getIndexFromCoords
  3. Vue
    1. Vue mixin
    2. Vue plugin
  4. Misc
    1. Misc Notes

Cards

buildDeck

import { buildDeck } from 'boardgame-utils'

Function to build a deck with options. Cards in the deck are objects in the same format as those in the deck function.

// defaults shown
buildDeck({
    low: 1, // lowest rank, inclusive
    high: 13, // highest rank, inclusive
    suits: ['hearts', 'diamonds', 'clubs', 'spades'] // each suit will receive
})

// build a deck of only red face cards
buildDeck({
    low: 11,
    high: 13,
    suits: ['hearts', 'diamonds']
})

deck

import { deck } from 'boardgame-utils'

A standard 52-card, 4-suit deck. Contains ranks from 1-13 inclusive and suits ['hearts', 'diamonds', 'clubs', 'spades']. Each card exists as an object with a rank and suit property - for example:

// ace of spades
{
    rank: 1,
    suit: 'spades'
}

// king of hearts
{
    rank: 13,
    suit: 'hearts'
}

It's left to the developer to handle face cards and aces high/low.

Grid

getCell

import { grid } from 'boardgame-utils'
const { getCell } = grid

getCell({
    x,
    y,
    board = [],
    width = 10
})

Get coordinates (x, y) from one-dimensional array board, given that board's width. For example, on a 3x3 board:

const board = [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
]

getCell(1, 1, board, 3) // = 4
getCell(2, 2, board, 3) // = 8

getCoordsFromIndex

import { grid } from 'boardgame-utils'
const { getCoordsFromIndex } = grid

getCoordsFromIndex(index, (width = 10))

Get { x, y } coordinates from a given index on a board with the given width. For example, on a 3x3 board:

const board = [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
]

getCoordsFromIndex(4, 3) // = { x: 1, y: 1 }
getCoordsFromIndex(8, 3) // = { x: 2, y: 2 }

getIndexFromCoords

import { grid } from 'boardgame-utils'
const { getIndexFromCoords } = grid

getIndexFromCoords({ x, y }, (width = 10))

Get index from given index { x, y } coordinates on a board with the given width. For example, on a 3x3 board:

const board = [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
]

getIndexFromCoords({x: 1, y: 1}, 3) // = 4
getIndexFromCoords({x: 2, y: 2}, 3) // = 8

taxicabDistance

import { grid } from 'boardgame-utils'
const { taxicabDistance } = grid

taxicabDistance(a, b)

Get taxicab distance from two vector2s For example:

const board = [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
]

taxicabDistance({x: 0, y: 0}, {x: 1, y: 1}) // = 2

taxicabDistanceFromIndices

import { grid } from 'boardgame-utils'
const { taxicabDistanceFromIndices } = grid

taxicabDistanceFromIndices(a, b, (width = 10))

Get taxicab distance from two indices given a board of width width. For example:

const board = [
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
]

taxicabDistanceFromIndices(0, 4, 3) // = 4
taxicabDistanceFromIndices(1, 4, 3) // = 1

Vue

mixin

import { mixin } from 'boardgame-utils'

A Vue mixin to handle setting up a boardgame.io client. This is suitable for small-scale games - larger ones should use the Vue plugin below.

{
    data: {
        // the initialized boardgame.io client
        client: null,

        // the options to pass to the client
        options: null,

        // whether to automatically set up client on mounted().
        setupClient: true
    },
    methods: {
        // runs before the client is initialized
        beforeClientInit(){},

        // initializes and saves the boardgame.io client
        // run automatically if setupClient == true
        initClient(){},

        // run after client is initialized and started
        onClientReady(){}
    },
    computed: {
        // current game state, null if not initialized
        G,

        // current game ctx, null if not initialized
        ctx
    }
}

An example setup in a Vue single-file component:

<template>
    <!-- only render if game is ready -->
    <section class="game" v-if="G">
        <!-- lets user play one of the cards defined in `data` -->
        <button v-for="(card, i) in cards" :key="i" @click="playCard(card)">
            Play {{ card }}
        </button>
    </section>
</template>

<script>
    import { mixin as boardgameMixin } from 'boardgame-utils'
    // options to pass to client (https://boardgame.io/documentation/#/api/Client?id=usage)
    import options from './your-game-options'

    export default {
        mixins: [boardgameMixin],
        data() {
            return {
                // use options imported above
                options: options,

                // example cards
                cards: [1, 2, 3]
            }
        },
        methods: {
            beforeClientInit() {
                // make sure we turn on the debug window
                this.options.debug = true
            },

            playCard(card) {
                // plays 1, 2, or 3
                // assumes we've defined a move called `playCard` in our game (https://boardgame.io/documentation/#/README?id=moves)
                this.client.moves.playCard(card)
            }
        }
    }
</script>

plugin

A Vue plugin to handle boardgame.io + Vue boilerplate.

To register:

import Vue from 'vue'
import { plugin as boardgamePlugin } from 'boardgame-utils'
// client options per https://boardgame.io/documentation/#/api/Client
import options from 'your-game-options'
// the plugin registers a vuex module called `boardgame` to handle state manipulation, so you'll also need to have your Vuex store ready to use
import store from 'your-vuex-store'

Vue.use(boardgamePlugin, {
    // client options (required)
    options: options,
    // Vuex store (required)
    store: store,
    // whether or not to initialize the client immediately (optional, default: true)
    initClient: true
})

The plugin adds the following in Vuex:

  • Store:

    • G - G from boardgame.io state
    • ctx - ctx from boardgame.io state
  • Mutations:

    • commit('UPDATE_STORE') - Updates the store's G and ctx to match the state of the game. Used internally and does not take any arguments.

    Since boardgame.io uses Proxied G and ctx objects, UPDATE_STORE is called to update the store's deep clones of those G and ctx objects. This keeps boardgame.io's internal state self-contained and the Vuex store reactive.

  • Actions:

    • dispatch('INIT_CLIENT', { options : {}}) - Creates a boardgame.io client with the given options. Called automatically unless initClient is set to false
    • dispatch('PLAY_MOVE', { move: 'moveName', options: {} }) - Runs a boardgame.io move with the (optional) given options.
    • dispatch('RESET_GAME') - Reset the game to its starting state.
    • dispatch('RUN_CLIENT_METHOD', { method: 'methodName', options: {} }) - Runs a method on client. For example, to reset the game, you could dispatch ('RUN_CLIENT_METHOD', {method: 'reset'}) (although resetting using the RESET_GAME action is recommended).
    • dispatch('RUN_EVENT', { event: 'eventName', options: {} }) - Runs a boardgame.io event with the (optional) given options.

The plugin also adds the following global mixin:

{
    computed: {
        G() {
            // alias for this.$store.state.boardgame.G
        },
        ctx() {
            // alias for this.$store.state.boardgame.ctx
        }
    }
}

Misc notes

Recommended boardgame.io workflow

  1. Prep lib/game dir
  2. Files:
    • index.js passes args to pass to options
    • phases.js contains phases to pass to index, including 1 start: true phase
    • moves.js contains all moves to pass to phases

Misc tips

  • Don't modify G nested properties (like G.enemies[0].hp - 10) directly in Vue events - call moves that include an index so the framework can do so (like <button @click="client.moves.changeHp(i, 10)"</button> in Vue and (index, amount) => G.enemies[index].hp -= amount in the relevant phase).