This project flips the script on Micro-Frontends expansion. Typical micro-frontends extend functionality in a lateral/horizontal manner, adding additional pages or components. This project exemplifies Micro-Frontends in a "stacking" or vertically expanding manner, each Micro-Frontend rendering it's own <canvas>
to be stacked on top of all other canvas.
The end result is a game of Snake with runtime-plugin support.
This example runs in Code Sandbox! (You may need to Fork the sandbox, then run yarn install
in a terminal and restart the sandbox to clear the state-file error. This is due to some combination of user-error and Yarn3 "install" quirks on a Container sandbox.)
Exposed at http://localhost:1339
This module holds the game engine itself, it is a simple MobX store exposing observables and methods to modify the game state. No output is rendered by this module.
Public API:
- methods:
setPlayerPosition()
- update the player's position to a new Vector2dgetRandomPosition()
- always returns a new random Vector2d within the bounds of play areasetVelocity()
- update the player velocitysetFPS()
- set the game speedsetTailSize()
- update the maximum tail sizesuspendGame()
- suspends (does not destroy) the current gamestartGame()
- starts the game, safe to call even if game is already started
- Properties:
gridSize
- the current grid size (defaults to 20)- [observable]
playerPosition
- Vector2d position of the player - [observable]
trail
- list of all coordinates that are part of the curent Player Trail fps
- the current game speed- [computed]
frameInterval
- the frameInterval in-use by the render engine, computed based on the value offps
running
- determines whether the render loop is executing- [observable]
tailSize
- the maximum size of the player's tail - [computed]
score
- the tail size minus starting tail size lastFrameTime
- the time of the last frame render, used by the render engine to control game/render speedvelocity
- Current Velocity2d of the player. e.g.{x: 1, y: 0}
= player is moving to the "right" by 1 tile at a time
Runs at: http://localhost:1337
This module renders the Snake itself based on the game state provided by the GameStore.
This module also resolves any plugins at runtime via Webpack's Module Federation Plugin. Plugins are rendered into Game's Stage as individual Layers (each plugin provides it's own <canvas>
element!)
Plugins are only stored in this monorepo for example sake. See external plugins examples:
Plugins are allowed to do almost anything they would like.
At a minimum, a plugin is expected to consume the game state from prop gameStore
, render something into it's own <Layer>
(it's own <canvas>
element), and register a reaction to produce a side-affect.
Exposed at: http://localhost:1338
- Type: Reward
- Tunctionality
- Renders a Red
<Rect>
to a random position in the canvas - Reacts to changes in Player/Apple Position, when collisions occur the Tail Size is increased
- Renders a Red
- Type: Penalty
- Functionality
- Renders a Purple
<Rect>
to a random position in the canvas - Reacts to changes in Player/Plum Position, when collisions occur the game speed is increased for a short duration, eventually returning to the non-penalized state.
- Renders a Purple
Exposed at: http://localhost:1340
- Type: Exotic
- Functionality
- Renders an Orange
<Star>
to a random position in the canvas - Reacts to changes in Player/Orange Position, when collisions occur the Player Position is set to a random location. The GameStore continues to advance the Player based on existing Velocity from the new position.
- Renders an Orange