Game Development with Vue.js / Nuxt.js and Phaser

Winnie Hellmann


Frontend Engineer

GitLab Logo



…would you do that?

ponfused carrot
ponfused carrot

picture by Nathan Friend

Why browser games? 🚿

  • click and play
    • good for game jams
    • good to share with friends
  • powerful platform
    • text rendering and alignment
    • pre-defined UI components
    • asset loading and caching built-in
  • developer tools
  • simple update mechanism

Why Phaser?

  • MIT License
  • parsers and renderers for
    • tiled maps
    • animated sprites
  • physics engines
  • particle emitters
  • 2D / 3D cameras
  • tweens
  • very detailed documentation
  • big collection of examples

Why Vue.js?

  • collocate HTML, CSS, JavaScript with Single File Components
  • extract / reuse components such as menus, modals, or overlays
  • Vue Router allows navigation between main menu, game, settings, …
  • reactivity allows to synchronize different components of the game

Why Vuex?

  • official state management solution for Vue.js
  • decouples components
  • allows global application state
  • makes business logic testable without rendering


…can you do?

giant rubber duck
giant rubber duck

picture by Florentijn Hofman

Game entities in store

  • actions to initialize and access entities

  • keep entities in local variables of store modules

  • Disadvantages:

    • each exposed Phaser method requires an action
    • debug tools cannot easily access entities
    • strong coupling of Phaser and store

Reactive game entities

  • overwrite properties of game entities with (derived) store state

  • actions/mutations update store

  • Phaser rendering picks up changes

  • Disadvantages:

    • only works for properties
    • breaks if Phaser overwrites property
    • property changes may cause performance problems

Store watchers

  • game entities register watchers for relevant store state

  • Disadvantages:

    • potentially more verbose
    • difficult to find all code that depends on certain state
    • not possible to track events that don’t mutate state

Subscribe action

  • listener for dispatched store actions

  • triggers even if state remains same

  • Disadvantages:

    • hard to track when following data flow


…can you do it?

drawing of recipes
drawing of recipes

picture by dasMaichen


…is the carrot back?

ponfused carrot
ponfused carrot

picture by Nathan Friend

Wrapper components?

  • Vue follows the One-Way Data Flow
    ⇒ data to child components via reactive props
  • Phaser objects are doubly linked
    ⇒ Vue fails to recurse them
  • some Phaser objects are updated often (physics, tweens)
    ⇒ performance problems
  • Object.freeze() prevents reactivity
    …but also updating properties such as position

Wrapper components?

  • Vue components need single root DOM element
    …but Phaser renders to canvas
  • workaround:
    create HTML comment using render function
    …but that does not allow child components
  • workaround:
    a lot of <div>s

All games?

  • avoid store actions for data that changes often (for example position with physics)
  • possible workarounds:
    • debounce
    • tile-based movement
    • collision events
  • good fit: Adventure, Point And Click, Puzzle
  • still ok: Jump ‘n’ Run
  • bad fit: First-person shooter, Racing

Thanks for listening!