Skip to content

Instantly share code, notes, and snippets.

@sarahzinger
Created August 19, 2022 18:38
Show Gist options
  • Save sarahzinger/1d3689003aa2087a39cac15c94c58b29 to your computer and use it in GitHub Desktop.
Save sarahzinger/1d3689003aa2087a39cac15c94c58b29 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
const gotchiMachine = Machine(
{
id: 'gotchi',
initial: 'feed',
context: {
uid: '',
datasourceType: '',
hunger: 0, // x/100
lastFed: Date.now(),
lifeStage: 'egg',
dark: false,
poop: false,
happiness: 1,
education: 0,
sickness: 0,
cleanness: 1,
energy: 1,
gamePoints: 0, // x/4 hearts
lastGame: Date.now(),
currentGameRounds: 0, // x/4 rounds
needsAttention: false,
},
states: {
feed: {
initial: 'unselected',
on: {
A: { target: '#gotchi.light' },
B: { target: '#gotchi.feed.choose' },
C: { target: '#gotchi.feed.unselected' },
},
states: {
unselected: {},
choose: {
initial: 'snack',
states: {
snack: {
on: {
A: { target: '#gotchi.feed.choose.meal' },
B: {
target: '#gotchi.feed.eat.snack',
actions: [
assign({
hunger: (context) => {
return context.hunger + 10;
},
lastFed: () => {
return Date.now();
},
cleanness: (context) => {
return context.cleanness - 10;
},
energy: (context) => {
return context.energy + 20;
},
happiness: (context) => {
return context.happiness + 50;
},
}),
'saveContext',
],
},
},
},
meal: {
on: {
A: { target: '#gotchi.feed.choose.snack' },
B: {
target: '#gotchi.feed.eat.meal',
actions: [
assign({
hunger: (context) => {
return context.hunger + 1;
},
lastFed: () => {
return Date.now();
},
cleanness: (context) => {
return context.cleanness - 20;
},
energy: (context) => {
return context.energy + 30;
},
happiness: (context) => {
return context.happiness + 30;
},
}),
'saveContext',
],
},
},
},
},
},
eat: {
states: {
snack: {
after: {
3000: '#gotchi.feed.eat.burp',
},
},
meal: {
after: {
3000: '#gotchi.feed.eat.burp',
},
},
burp: {
after: {
1000: '#gotchi.feed.unselected',
},
},
},
},
},
},
light: {
initial: 'unselected',
on: {
A: { target: '#gotchi.play' },
B: {
target: '#gotchi.light.choose',
},
C: { target: '#gotchi.light.unselected' },
},
states: {
unselected: {},
choose: {
initial: 'selectLightsOn',
states: {
selectLightsOn: {
on: {
A: '#gotchi.light.choose.selectLightsOff',
B: {
target: '#gotchi.light.toggle.lightsOn',
actions: assign({
dark: (context) => {
return true;
},
happiness: (context) => {
if (context.energy < 10) {
return context.happiness - 20;
}
return context.happiness;
},
}),
},
},
},
selectLightsOff: {
on: {
A: '#gotchi.light.choose.selectLightsOn',
B: {
target: '#gotchi.light.toggle.lightsOff',
actions: assign({
dark: (context) => {
return true;
},
happiness: (context) => {
if (context.energy > 10) {
return context.happiness - 20;
}
return context.happiness + 40;
},
energy: (context) => {
if (context.energy > 10) {
return context.energy;
}
return context.energy + 100;
},
}),
},
},
},
},
},
toggle: {
states: {
lightsOn: {},
lightsOff: {},
},
},
},
},
play: {
initial: 'unselected',
on: {
A: {
target: '#gotchi.medicine',
},
B: {
target: '#gotchi.play.game',
},
C: {
target: '#gotchi.play.unselected',
},
},
states: {
unselected: {},
game: {
initial: 'loading',
states: {
loading: {
after: {
3000: '#gotchi.play.game.waitingForChoice',
},
},
waitingForChoice: {
on: {
A: '#gotchi.play.game.left',
B: '#gotchi.play.game.right',
},
},
// hardcoding left is wrong and right is right for demo purposes
left: {
after: {
3000: [
// { target: '#gotchi.play.game.correct', cond: { type: 'randomWinOrLose' } },
// { target: '#gotchi.play.game.incorrect' },
{ target: '#gotchi.play.game.incorrect' },
],
},
},
right: {
after: {
3000: [
// { target: '#gotchi.play.game.correct', cond: { type: 'randomWinOrLose' } },
// { target: '#gotchi.play.game.incorrect' },
{ target: '#gotchi.play.game.correct' },
],
},
},
correct: {
after: {
1: [
{ target: '#gotchi.play.game.gameFinished', cond: { type: 'isGameFinished' } },
{ target: '#gotchi.play.game.waitingForChoice' },
],
},
entry: assign({
currentGameRounds: (context) => {
return context.currentGameRounds + 1;
},
gamePoints: (context) => {
return context.gamePoints + 1;
},
}),
},
incorrect: {
after: {
1: [
{ target: '#gotchi.play.game.gameFinished', cond: { type: 'isGameFinished' } },
{ target: '#gotchi.play.game.waitingForChoice' },
],
},
entry: assign({
currentGameRounds: (context) => {
return context.currentGameRounds + 1;
},
gamePoints: (context) => {
return context.gamePoints - 1;
},
}),
},
//hard coding that we win for demo purposes
gameFinished: {
after: {
1: [
// { target: '#gotchi.play.game.win', cond: { type: 'didYouWinGame' } },
// { target: '#gotchi.play.game.lose' },
{ target: '#gotchi.play.game.win' },
],
},
entry: [
assign({
happiness: (context) => {
return context.happiness + 1;
},
lastGame: () => {
return Date.now();
},
}),
'saveContext',
],
},
win: {
after: {
3000: '#gotchi.play.unselected',
},
},
lose: {
after: {
3000: '#gotchi.play.unselected',
},
},
},
},
},
},
medicine: {
on: {
A: {
target: '#gotchi.bath',
},
B: {
target: '#gotchi.medicine.giveMedicine',
},
C: {
target: '#gotchi.medicine.unselected',
},
},
initial: 'unselected',
states: {
unselected: {},
giveMedicine: {},
},
},
bath: {
on: {
A: {
target: '#gotchi.health',
},
B: {
target: '#gotchi.bath.bathing',
},
},
inital: 'unselected',
states: {
unselected: {},
bathing: {
after: {
8000: '#gotchi.bath.unselected',
},
entry: [
assign({
cleanness: (context) => {
return 100;
},
poop: () => false,
}),
'saveContext',
],
},
},
},
health: {
on: {
A: {
target: '#gotchi.discipline',
},
B: {
target: '#gotchi.health.dashboard',
},
C: {
target: '#gotchi.health.unselected',
},
},
initial: 'unselected',
states: {
unselected: {},
dashboard: {},
},
},
discipline: {
on: {
A: {
target: '#gotchi.feed',
},
B: {
target: '#gotchi.discipline.yell',
},
C: {
target: '#gotchi.discipline.unselected',
},
},
initial: 'unselected',
states: {
unselected: {},
yell: {},
},
},
},
on: {
UPDATE_CONTEXT_FROM_STREAMING_DATA: {
actions: assign({
hunger: (context, savedContext) => {
return savedContext.hunger;
},
happiness: (context, savedContext) => {
return savedContext.happiness;
},
lifeStage: (context, savedContext) => {
return savedContext.lifeStage;
},
education: (context, savedContext) => {
return savedContext.education;
},
sickness: (context, savedContext) => {
return savedContext.sickness;
},
cleanness: (context, savedContext) => {
return savedContext.cleanness;
},
energy: (context, savedContext) => {
return savedContext.energy;
},
dark: (context, savedContext) => {
return savedContext.dark;
},
poop: (context, savedContext) => {
return savedContext.poop;
},
uid: (context, savedContext) => {
return savedContext.uid;
},
datasourceType: (context, savedContext) => {
return savedContext.datasourceType;
},
}),
},
SAVE: {
actions: ['saveContext'],
},
},
},
{
actions: {
saveContext: (context) => {
console.log("save")
},
},
guards: {
randomWinOrLose: () => {
return Math.random() < 0.5;
},
isGameFinished: (context) => {
return context.currentGameRounds == 5;
},
didYouWinGame: (context) => {
return context.gamePoints > 2;
},
},
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment