diff --git a/CHANGELOG.md b/CHANGELOG.md
index eaf9927a..e9724fa8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- With Spotify connected, the music player lists Up next, Recent, Playlists and Devices (`1` to `4`). Enter skips forward to a queued track, replays a recent one in its playlist or album, starts a playlist, or moves playback to another device.
- The Pets page and the landing page show Clawd dancing to music and his two idle variants.
+### Changed
+
+- The ghost and the robot walk left with hand-drawn frames instead of a mirrored right walk, so they stay lit from the top left like Clawd.
+
### Fixed
- The landing page's hop, fail and scrunch cards replay instead of freezing on their last frame.
diff --git a/art/crt/crt.art b/art/crt/crt.art
index b6437acf..7053c639 100644
--- a/art/crt/crt.art
+++ b/art/crt/crt.art
@@ -410,6 +410,112 @@ frame 110 dx=1 head=17,3 fx=8,14,u;6,13,u;2,11,u
............mM...mMMM...........
...........mMMM..xxxx...........
+anim walk-left loop exits=0,4
+frame 110 dx=-1 head=15,3 name=lcontact fx=23,15,u;25,15,u;27,14,u
+................................
+....................yY..........
+...................M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+........MmoDDDDDDDDDDomM........
+............mM....mM............
+...........mMMM..mMMM...........
+frame 110 dx=-1 head=15,4 name=ldown fx=24,15,u;26,14,u;28,13,u
+................................
+....................yY..........
+....................M...........
+...................M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+........MmoDDDDDDDDDDomM........
+...........mMMM..mMMM...........
+frame 110 dx=-1 head=15,2 fx=23,14,u;27,13,u;29,12,u
+................................
+....................yY..........
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+........MmoBsGsYsRsBDom.........
+..........oDDDDDDDDDDomM........
+............mM...mMMM...........
+............mM..................
+...........mMMM..xxxx...........
+frame 110 dx=-1 head=15,3 fx=22,15,u;24,14,u;28,12,u
+................................
+....................yY..........
+...................M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+........MmoDDDDDDDDDDomM........
+............mM...mMMM...........
+...........mMMM..xxxx...........
+frame 110 dx=-1 head=15,3 copy=lcontact fx=22,15,u;24,15,u;26,14,u
+frame 110 dx=-1 head=15,4 copy=ldown fx=23,15,u;25,14,u;27,13,u
+frame 110 dx=-1 head=15,2 fx=22,15,u;26,13,u;28,12,u
+................................
+....................yY..........
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDomM........
+........MmoDDDDDDDDDDo..........
+...........mMMM...mM............
+..................mM............
+...........xxxx..mMMM...........
+frame 110 dx=-1 head=15,3 fx=23,14,u;25,13,u;29,11,u
+................................
+....................yY..........
+...................M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBwsssssssssssBBDo.......
+.....oLBtgGttttttgGtttBDo.......
+.....oLBsGGssssssGGsssBDo.......
+.....oLBttttGttGttttttBDo.......
+.....oLBBssssGGssssssBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+........MmoDDDDDDDDDDomM........
+...........mMMM...mM............
+...........xxxx..mMMM...........
+
anim hop once
frame 130 head=16,4
................................
@@ -1546,6 +1652,96 @@ frame 140 dx=1 head=17,3 fx=4,0,n;3,1,u;6,1,u;7,2,n
...........mMMM..xxxx...........
frame 140 dx=1 head=17,3 copy=pw3 fx=2,0,n;5,0,u;6,2,n;4,1,u
+anim pant-walk-left loop exits=0,4
+frame 140 dx=-1 head=15,3 name=lpw0 fx=24,2,n;25,1,u;26,2,n;26,6,C
+................................
+.................MM.............
+...............YR..M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBeeeeeeeeeeeeBBDo.......
+.....oLBethhtttttthhteBDo.......
+.....oLBesGGssssssGGseBDo.......
+.....oLBettttGhhGtttteBDo.......
+.....oLBBessssRRsssseBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+.........moDDDDDDDDDDom.........
+.........M..mM....mM..M.........
+...........mMMM..mMMM...........
+frame 140 dx=-1 head=15,4 name=lpw1 fx=25,1,n;26,0,u;27,1,n;23,3,n
+................................
+................................
+.................MM.............
+...............YR..M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBeeeeeeeeeeeeBBDo.......
+.....oLBethhtttttthhteBDo.......
+.....oLBesGGssssssGGseBDo.......
+.....oLBettttGhhGtttteBDo.......
+.....oLBBessssRRsssseBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+.........moDDDDDDDDDDom.........
+.........M.mMMM..mMMM.M.........
+frame 140 dx=-1 head=15,3 fx=26,0,n;27,0,u;28,1,u;23,2,n
+................................
+.................MM.............
+...............YR..M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBeeeeeeeeeeeeBBDo.......
+.....oLBethhtttttthhteBDo.......
+.....oLBesGGssssssGGseBDo.......
+.....oLBettttGhhGtttteBDo.......
+.....oLBBessssRRsssseBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+.........moDDDDDDDDDDom.........
+.........M..mM...mMMM.M.........
+...........mMMM..xxxx...........
+frame 140 dx=-1 head=15,3 name=lpw3 fx=28,0,n;29,1,u;24,1,n;25,2,u
+................................
+................................
+..............YRM..M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBeeeeeeeeeeeeBBDo.......
+.....oLBethhtttttthhteBDo.......
+.....oLBesGGssssssGGseBDo.......
+.....oLBettttGhhGtttteBDo.......
+.....oLBBessssRRsssseBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+.........moDDDDDDDDDDom.........
+.........M..mM....mM..M.........
+...........mMMM..mMMM...........
+frame 140 dx=-1 head=15,3 copy=lpw0 fx=25,2,n;26,1,u;29,0,u;27,2,n;26,8,C
+frame 140 dx=-1 head=15,4 copy=lpw1 fx=26,1,n;27,0,u;24,3,n;23,3,u
+frame 140 dx=-1 head=15,3 fx=27,0,n;28,1,u;25,1,u;24,2,n
+................................
+.................MM.............
+...............YR..M............
+.......oooooooooooooooo.........
+......oLLLLLLLLLLLLLLLBo........
+.....oLBBeeeeeeeeeeeeBBDo.......
+.....oLBethhtttttthhteBDo.......
+.....oLBesGGssssssGGseBDo.......
+.....oLBettttGhhGtttteBDo.......
+.....oLBBessssRRsssseBBDo.......
+.....oBBGBBBBBBBBBMBMBBDo.......
+......oooooooooooooooooo........
+.........moBsGsYsRsBDom.........
+.........moDDDDDDDDDDom.........
+.........M.mMMM...mM..M.........
+...........xxxx..mMMM...........
+frame 140 dx=-1 head=15,3 copy=lpw3 fx=29,0,n;26,0,u;25,2,n;27,1,u
+
anim scrunch once
frame 100 head=16,2
....................yY..........
diff --git a/art/ghost/ghost.art b/art/ghost/ghost.art
index 503e8981..5a03e82a 100644
--- a/art/ghost/ghost.art
+++ b/art/ghost/ghost.art
@@ -326,6 +326,112 @@ frame 120 dx=1 head=13,1
...g...S..S..S..........
.........oooooo.........
+anim walk-left loop exits=0,4
+frame 120 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+....WWWWWWWWWWWWSSSf....
+......WWWWWWWWWWWS......
+........WS.WS.WS.WS.g...
+..........S..S..S..g....
+.........oooooo.........
+frame 120 dx=-1 head=11,0
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+....WWWWWWWWWWWWSSSfg...
+......WWWWWWWWWWWS......
+........W.WS.WS.WSS..g..
+...........S..S..S..g...
+........................
+..........oooo..........
+frame 120 dx=-1 head=11,0
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+....WWKKWWWWWWKKS.......
+......WWWWWWWWWWSSSf....
+......WWWWWWWWWWWS......
+........W.WS.WS.WSSg....
+.....................g..
+........................
+..........oooo..........
+frame 120 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+.....WWWWWWWWWWWSSS.....
+......WWWWWWWWWWWS......
+.........WS.WS.WS.S.f...
+...........S..S..S.fg...
+.........oooooo.........
+frame 120 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+....WWWWWWWWWWWWSSSf....
+......WWWWWWWWWWWS......
+........W.WS.WS.WSS..g..
+............S..S..S..g..
+.........oooooo.........
+frame 120 dx=-1 head=11,0
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+....WWWWWWWWWWWWSSSfg...
+......WWWWWWWWWWWS......
+........W.WS.WS.WSSg....
+.........S..S..S...g....
+........................
+..........oooo..........
+frame 120 dx=-1 head=11,0
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+....WWKKWWWWWWKKS.......
+......WWWWWWWWWWSSSf....
+......WWWWWWWWWWWS......
+.........WS.WS.WS.S.f...
+......................g.
+........................
+..........oooo..........
+frame 120 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WEEWWWWEEWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWWWWWWKKS.......
+.....WWWWWWWWWWWSSS.....
+......WWWWWWWWWWWS......
+........WS.WS.WS.WS.g...
+..........S..S..S...g...
+.........oooooo.........
+
anim working loop exits=0,3,6
frame 110 head=12,1
........................
@@ -1607,6 +1713,112 @@ frame 140 dx=1 head=13,2
...g.WS.WS.WS.WS........
.........oooooo.........
+anim pant-walk-left loop exits=0,4
+frame 140 dx=-1 head=11,2
+........................
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+....WWWWWWRWWWWWSSSf....
+......WWWWWWWWWWWS......
+........WS.WS.WS.WS.g...
+.........oooooo.........
+frame 140 dx=-1 head=11,1
+........................
+...C....LWWWWS..........
+...CC.LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+....WWWWWWRWWWWWSSSfg...
+......WWWWWWWWWWWS......
+........W.WS.WS.WSS..g..
+...........S..S..S..g...
+.........oooooo.........
+frame 140 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+...C.LWWWWWWWWWWS.......
+...CCWSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+....WWKKWEEWWWKKS.......
+......WWWWRWWWWWSSSf....
+......WWWWWWWWWWWS......
+........W.WS.WS.WSSg....
+.....................g..
+.........oooooo.........
+frame 140 dx=-1 head=11,2
+........................
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+.....WWWWWRWWWWWSSS.....
+......WWWWWWWWWWWS......
+.........WS.WS.WS.S.f...
+.........oooooo.........
+frame 140 dx=-1 head=11,2
+........................
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+....WWWWWWRWWWWWSSSf....
+......WWWWWWWWWWWS......
+........W.WS.WS.WSS..g..
+.........oooooo.........
+frame 140 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+....WWWWWWRWWWWWSSSfg...
+......WWWWWWWWWWWS......
+........W.WS.WS.WSSg....
+.........S..S..S...g....
+.........oooooo.........
+frame 140 dx=-1 head=11,1
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+....WWKKWEEWWWKKS.......
+......WWWWRWWWWWSSSf....
+......WWWWWWWWWWWS......
+.........WS.WS.WS.S.f...
+......................g.
+.........oooooo.........
+frame 140 dx=-1 head=11,2
+........................
+........................
+........LWWWWS..........
+......LLWWWWWWWS........
+.....LWWWWWWWWWWS.......
+.....WSSWWWWSSWWS.......
+.....WEEWWWWEEWWS.......
+.....WKKWEEWWWKKS.......
+.....WWWWWRWWWWWSSS.....
+......WWWWWWWWWWWS......
+........WS.WS.WS.WS.g...
+.........oooooo.........
+
anim scrunch once
frame 150 head=12,1
........................
diff --git a/docs/assets/ghost/pant-walk-left/00.png b/docs/assets/ghost/pant-walk-left/00.png
new file mode 100644
index 00000000..f08a1116
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/00.png differ
diff --git a/docs/assets/ghost/pant-walk-left/00.svg b/docs/assets/ghost/pant-walk-left/00.svg
new file mode 100644
index 00000000..789bba9e
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/00.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/01.png b/docs/assets/ghost/pant-walk-left/01.png
new file mode 100644
index 00000000..3886d3e5
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/01.png differ
diff --git a/docs/assets/ghost/pant-walk-left/01.svg b/docs/assets/ghost/pant-walk-left/01.svg
new file mode 100644
index 00000000..f936f9a5
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/01.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/02.png b/docs/assets/ghost/pant-walk-left/02.png
new file mode 100644
index 00000000..b38ac308
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/02.png differ
diff --git a/docs/assets/ghost/pant-walk-left/02.svg b/docs/assets/ghost/pant-walk-left/02.svg
new file mode 100644
index 00000000..2409de07
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/02.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/03.png b/docs/assets/ghost/pant-walk-left/03.png
new file mode 100644
index 00000000..9f878cac
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/03.png differ
diff --git a/docs/assets/ghost/pant-walk-left/03.svg b/docs/assets/ghost/pant-walk-left/03.svg
new file mode 100644
index 00000000..6551acec
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/03.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/04.png b/docs/assets/ghost/pant-walk-left/04.png
new file mode 100644
index 00000000..a757dabb
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/04.png differ
diff --git a/docs/assets/ghost/pant-walk-left/04.svg b/docs/assets/ghost/pant-walk-left/04.svg
new file mode 100644
index 00000000..91a453a3
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/04.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/05.png b/docs/assets/ghost/pant-walk-left/05.png
new file mode 100644
index 00000000..f88b462e
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/05.png differ
diff --git a/docs/assets/ghost/pant-walk-left/05.svg b/docs/assets/ghost/pant-walk-left/05.svg
new file mode 100644
index 00000000..fdd7e335
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/05.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/06.png b/docs/assets/ghost/pant-walk-left/06.png
new file mode 100644
index 00000000..294e2048
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/06.png differ
diff --git a/docs/assets/ghost/pant-walk-left/06.svg b/docs/assets/ghost/pant-walk-left/06.svg
new file mode 100644
index 00000000..650af7a2
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/06.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/07.png b/docs/assets/ghost/pant-walk-left/07.png
new file mode 100644
index 00000000..0006379b
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/07.png differ
diff --git a/docs/assets/ghost/pant-walk-left/07.svg b/docs/assets/ghost/pant-walk-left/07.svg
new file mode 100644
index 00000000..2a76a4a0
--- /dev/null
+++ b/docs/assets/ghost/pant-walk-left/07.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/pant-walk-left/clip.gif b/docs/assets/ghost/pant-walk-left/clip.gif
new file mode 100644
index 00000000..ae4ef236
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/clip.gif differ
diff --git a/docs/assets/ghost/pant-walk-left/clip.mp4 b/docs/assets/ghost/pant-walk-left/clip.mp4
new file mode 100644
index 00000000..297981cf
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/clip.mp4 differ
diff --git a/docs/assets/ghost/pant-walk-left/clip.webm b/docs/assets/ghost/pant-walk-left/clip.webm
new file mode 100644
index 00000000..4492f466
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/clip.webm differ
diff --git a/docs/assets/ghost/pant-walk-left/sheet.png b/docs/assets/ghost/pant-walk-left/sheet.png
new file mode 100644
index 00000000..309dceee
Binary files /dev/null and b/docs/assets/ghost/pant-walk-left/sheet.png differ
diff --git a/docs/assets/ghost/walk-left/00.png b/docs/assets/ghost/walk-left/00.png
new file mode 100644
index 00000000..65eff8e8
Binary files /dev/null and b/docs/assets/ghost/walk-left/00.png differ
diff --git a/docs/assets/ghost/walk-left/00.svg b/docs/assets/ghost/walk-left/00.svg
new file mode 100644
index 00000000..d302ed94
--- /dev/null
+++ b/docs/assets/ghost/walk-left/00.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/01.png b/docs/assets/ghost/walk-left/01.png
new file mode 100644
index 00000000..fe4dae2a
Binary files /dev/null and b/docs/assets/ghost/walk-left/01.png differ
diff --git a/docs/assets/ghost/walk-left/01.svg b/docs/assets/ghost/walk-left/01.svg
new file mode 100644
index 00000000..12893f60
--- /dev/null
+++ b/docs/assets/ghost/walk-left/01.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/02.png b/docs/assets/ghost/walk-left/02.png
new file mode 100644
index 00000000..b3b84e53
Binary files /dev/null and b/docs/assets/ghost/walk-left/02.png differ
diff --git a/docs/assets/ghost/walk-left/02.svg b/docs/assets/ghost/walk-left/02.svg
new file mode 100644
index 00000000..2ff874bd
--- /dev/null
+++ b/docs/assets/ghost/walk-left/02.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/03.png b/docs/assets/ghost/walk-left/03.png
new file mode 100644
index 00000000..d79da8a6
Binary files /dev/null and b/docs/assets/ghost/walk-left/03.png differ
diff --git a/docs/assets/ghost/walk-left/03.svg b/docs/assets/ghost/walk-left/03.svg
new file mode 100644
index 00000000..29591506
--- /dev/null
+++ b/docs/assets/ghost/walk-left/03.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/04.png b/docs/assets/ghost/walk-left/04.png
new file mode 100644
index 00000000..61a0dcc3
Binary files /dev/null and b/docs/assets/ghost/walk-left/04.png differ
diff --git a/docs/assets/ghost/walk-left/04.svg b/docs/assets/ghost/walk-left/04.svg
new file mode 100644
index 00000000..3f4452a6
--- /dev/null
+++ b/docs/assets/ghost/walk-left/04.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/05.png b/docs/assets/ghost/walk-left/05.png
new file mode 100644
index 00000000..859954f2
Binary files /dev/null and b/docs/assets/ghost/walk-left/05.png differ
diff --git a/docs/assets/ghost/walk-left/05.svg b/docs/assets/ghost/walk-left/05.svg
new file mode 100644
index 00000000..7ac5b8c6
--- /dev/null
+++ b/docs/assets/ghost/walk-left/05.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/06.png b/docs/assets/ghost/walk-left/06.png
new file mode 100644
index 00000000..d72cac00
Binary files /dev/null and b/docs/assets/ghost/walk-left/06.png differ
diff --git a/docs/assets/ghost/walk-left/06.svg b/docs/assets/ghost/walk-left/06.svg
new file mode 100644
index 00000000..81dc4788
--- /dev/null
+++ b/docs/assets/ghost/walk-left/06.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/07.png b/docs/assets/ghost/walk-left/07.png
new file mode 100644
index 00000000..88fde841
Binary files /dev/null and b/docs/assets/ghost/walk-left/07.png differ
diff --git a/docs/assets/ghost/walk-left/07.svg b/docs/assets/ghost/walk-left/07.svg
new file mode 100644
index 00000000..5d004ba4
--- /dev/null
+++ b/docs/assets/ghost/walk-left/07.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/ghost/walk-left/clip.gif b/docs/assets/ghost/walk-left/clip.gif
new file mode 100644
index 00000000..92500eee
Binary files /dev/null and b/docs/assets/ghost/walk-left/clip.gif differ
diff --git a/docs/assets/ghost/walk-left/clip.mp4 b/docs/assets/ghost/walk-left/clip.mp4
new file mode 100644
index 00000000..44d76b46
Binary files /dev/null and b/docs/assets/ghost/walk-left/clip.mp4 differ
diff --git a/docs/assets/ghost/walk-left/clip.webm b/docs/assets/ghost/walk-left/clip.webm
new file mode 100644
index 00000000..6b88f18a
Binary files /dev/null and b/docs/assets/ghost/walk-left/clip.webm differ
diff --git a/docs/assets/ghost/walk-left/sheet.png b/docs/assets/ghost/walk-left/sheet.png
new file mode 100644
index 00000000..77cac10d
Binary files /dev/null and b/docs/assets/ghost/walk-left/sheet.png differ
diff --git a/docs/assets/robot/pant-walk-left/00.png b/docs/assets/robot/pant-walk-left/00.png
new file mode 100644
index 00000000..9cd35184
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/00.png differ
diff --git a/docs/assets/robot/pant-walk-left/00.svg b/docs/assets/robot/pant-walk-left/00.svg
new file mode 100644
index 00000000..cfb0baeb
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/00.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/01.png b/docs/assets/robot/pant-walk-left/01.png
new file mode 100644
index 00000000..c5b03975
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/01.png differ
diff --git a/docs/assets/robot/pant-walk-left/01.svg b/docs/assets/robot/pant-walk-left/01.svg
new file mode 100644
index 00000000..09e7eca0
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/01.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/02.png b/docs/assets/robot/pant-walk-left/02.png
new file mode 100644
index 00000000..4e8327ca
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/02.png differ
diff --git a/docs/assets/robot/pant-walk-left/02.svg b/docs/assets/robot/pant-walk-left/02.svg
new file mode 100644
index 00000000..8a1fa2b9
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/02.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/03.png b/docs/assets/robot/pant-walk-left/03.png
new file mode 100644
index 00000000..bf237e5c
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/03.png differ
diff --git a/docs/assets/robot/pant-walk-left/03.svg b/docs/assets/robot/pant-walk-left/03.svg
new file mode 100644
index 00000000..c234816d
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/03.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/04.png b/docs/assets/robot/pant-walk-left/04.png
new file mode 100644
index 00000000..50f2dd55
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/04.png differ
diff --git a/docs/assets/robot/pant-walk-left/04.svg b/docs/assets/robot/pant-walk-left/04.svg
new file mode 100644
index 00000000..69ec5a1b
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/04.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/05.png b/docs/assets/robot/pant-walk-left/05.png
new file mode 100644
index 00000000..adb957d3
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/05.png differ
diff --git a/docs/assets/robot/pant-walk-left/05.svg b/docs/assets/robot/pant-walk-left/05.svg
new file mode 100644
index 00000000..7f57ae58
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/05.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/06.png b/docs/assets/robot/pant-walk-left/06.png
new file mode 100644
index 00000000..334599f3
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/06.png differ
diff --git a/docs/assets/robot/pant-walk-left/06.svg b/docs/assets/robot/pant-walk-left/06.svg
new file mode 100644
index 00000000..c5bb9042
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/06.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/07.png b/docs/assets/robot/pant-walk-left/07.png
new file mode 100644
index 00000000..ce0fa36b
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/07.png differ
diff --git a/docs/assets/robot/pant-walk-left/07.svg b/docs/assets/robot/pant-walk-left/07.svg
new file mode 100644
index 00000000..786be96a
--- /dev/null
+++ b/docs/assets/robot/pant-walk-left/07.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/pant-walk-left/clip.gif b/docs/assets/robot/pant-walk-left/clip.gif
new file mode 100644
index 00000000..0dcaddd9
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/clip.gif differ
diff --git a/docs/assets/robot/pant-walk-left/clip.mp4 b/docs/assets/robot/pant-walk-left/clip.mp4
new file mode 100644
index 00000000..84adb5f4
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/clip.mp4 differ
diff --git a/docs/assets/robot/pant-walk-left/clip.webm b/docs/assets/robot/pant-walk-left/clip.webm
new file mode 100644
index 00000000..7753f4b5
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/clip.webm differ
diff --git a/docs/assets/robot/pant-walk-left/sheet.png b/docs/assets/robot/pant-walk-left/sheet.png
new file mode 100644
index 00000000..dd72ff4d
Binary files /dev/null and b/docs/assets/robot/pant-walk-left/sheet.png differ
diff --git a/docs/assets/robot/walk-left/00.png b/docs/assets/robot/walk-left/00.png
new file mode 100644
index 00000000..3c546e7b
Binary files /dev/null and b/docs/assets/robot/walk-left/00.png differ
diff --git a/docs/assets/robot/walk-left/00.svg b/docs/assets/robot/walk-left/00.svg
new file mode 100644
index 00000000..8550c18b
--- /dev/null
+++ b/docs/assets/robot/walk-left/00.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/01.png b/docs/assets/robot/walk-left/01.png
new file mode 100644
index 00000000..31a88eda
Binary files /dev/null and b/docs/assets/robot/walk-left/01.png differ
diff --git a/docs/assets/robot/walk-left/01.svg b/docs/assets/robot/walk-left/01.svg
new file mode 100644
index 00000000..b9455eff
--- /dev/null
+++ b/docs/assets/robot/walk-left/01.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/02.png b/docs/assets/robot/walk-left/02.png
new file mode 100644
index 00000000..0c588aba
Binary files /dev/null and b/docs/assets/robot/walk-left/02.png differ
diff --git a/docs/assets/robot/walk-left/02.svg b/docs/assets/robot/walk-left/02.svg
new file mode 100644
index 00000000..d02acc5e
--- /dev/null
+++ b/docs/assets/robot/walk-left/02.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/03.png b/docs/assets/robot/walk-left/03.png
new file mode 100644
index 00000000..6133b6e6
Binary files /dev/null and b/docs/assets/robot/walk-left/03.png differ
diff --git a/docs/assets/robot/walk-left/03.svg b/docs/assets/robot/walk-left/03.svg
new file mode 100644
index 00000000..9793f55b
--- /dev/null
+++ b/docs/assets/robot/walk-left/03.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/04.png b/docs/assets/robot/walk-left/04.png
new file mode 100644
index 00000000..cfc2d672
Binary files /dev/null and b/docs/assets/robot/walk-left/04.png differ
diff --git a/docs/assets/robot/walk-left/04.svg b/docs/assets/robot/walk-left/04.svg
new file mode 100644
index 00000000..b2973924
--- /dev/null
+++ b/docs/assets/robot/walk-left/04.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/05.png b/docs/assets/robot/walk-left/05.png
new file mode 100644
index 00000000..87c9c117
Binary files /dev/null and b/docs/assets/robot/walk-left/05.png differ
diff --git a/docs/assets/robot/walk-left/05.svg b/docs/assets/robot/walk-left/05.svg
new file mode 100644
index 00000000..0f2c05c3
--- /dev/null
+++ b/docs/assets/robot/walk-left/05.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/06.png b/docs/assets/robot/walk-left/06.png
new file mode 100644
index 00000000..ad73c334
Binary files /dev/null and b/docs/assets/robot/walk-left/06.png differ
diff --git a/docs/assets/robot/walk-left/06.svg b/docs/assets/robot/walk-left/06.svg
new file mode 100644
index 00000000..db20c5d7
--- /dev/null
+++ b/docs/assets/robot/walk-left/06.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/07.png b/docs/assets/robot/walk-left/07.png
new file mode 100644
index 00000000..684b0d12
Binary files /dev/null and b/docs/assets/robot/walk-left/07.png differ
diff --git a/docs/assets/robot/walk-left/07.svg b/docs/assets/robot/walk-left/07.svg
new file mode 100644
index 00000000..b383ecaa
--- /dev/null
+++ b/docs/assets/robot/walk-left/07.svg
@@ -0,0 +1 @@
+
diff --git a/docs/assets/robot/walk-left/clip.gif b/docs/assets/robot/walk-left/clip.gif
new file mode 100644
index 00000000..17f9a7cc
Binary files /dev/null and b/docs/assets/robot/walk-left/clip.gif differ
diff --git a/docs/assets/robot/walk-left/clip.mp4 b/docs/assets/robot/walk-left/clip.mp4
new file mode 100644
index 00000000..d60c6dc9
Binary files /dev/null and b/docs/assets/robot/walk-left/clip.mp4 differ
diff --git a/docs/assets/robot/walk-left/clip.webm b/docs/assets/robot/walk-left/clip.webm
new file mode 100644
index 00000000..a8c5ad9d
Binary files /dev/null and b/docs/assets/robot/walk-left/clip.webm differ
diff --git a/docs/assets/robot/walk-left/sheet.png b/docs/assets/robot/walk-left/sheet.png
new file mode 100644
index 00000000..b0206558
Binary files /dev/null and b/docs/assets/robot/walk-left/sheet.png differ
diff --git a/hooks/sprites/crt.ts b/hooks/sprites/crt.ts
index 32f4706f..aca08141 100644
--- a/hooks/sprites/crt.ts
+++ b/hooks/sprites/crt.ts
@@ -39,6 +39,16 @@ export const CRT_SHEET: PetSheet = {
{ ms: 110, dx: 1, head: [17,2], px: ["................................","....................yY..........",".........oooooooooooooooo.......","........oLLLLLLLLLLLLLLLBo......",".......oLBBwsssssssssssBBDo.....",".......oLBtttgGttttttgGtBDo.....",".......oLBsssGGssssssGGsBDo.....",".......oLBttttttGttGttttBDo.....",".......oLBBssssssGGssssBBDo.....",".......oBBGBBBBBBBBBMBMBBDo.....","........oooooooooooooooooo......","........MmoBsGsYsRsBDom.........","...u......oDDDDDDDDDDomM........",".....u......mM...mMMM...........","............mM..................",".........u.mMMM..xxxx..........."] },
{ ms: 110, dx: 1, head: [17,3], px: ["................................","....................yY..........",".....................M..........",".........oooooooooooooooo.......","........oLLLLLLLLLLLLLLLBo......",".......oLBBwsssssssssssBBDo.....",".......oLBtttgGttttttgGtBDo.....",".......oLBsssGGssssssGGsBDo.....",".......oLBttttttGttGttttBDo.....",".......oLBBssssssGGssssBBDo.....",".......oBBGBBBBBBBBBMBMBBDo.....","..u.....oooooooooooooooooo......",".........moBsGsYsRsBDom.........","......u.MmoDDDDDDDDDDomM........","........u...mM...mMMM...........","...........mMMM..xxxx..........."] },
] },
+ "walk-left": { loop: true, frames: [
+ { ms: 110, dx: -1, head: [15,3], px: ["................................","....................yY..........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........","........MmoDDDDDDDDDDomM........","............mM....mM.......u....","...........mMMM..mMMM..u.u......"], exit: true },
+ { ms: 110, dx: -1, head: [15,4], px: ["................................","....................yY..........","....................M...........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.....u...","........MmoDDDDDDDDDDomM..u.....","...........mMMM..mMMM...u......."] },
+ { ms: 110, dx: -1, head: [15,2], px: ["................................","....................yY..........",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........","........MmoBsGsYsRsBDom.........","..........oDDDDDDDDDDomM.....u..","............mM...mMMM......u....","............mM.........u........","...........mMMM..xxxx..........."] },
+ { ms: 110, dx: -1, head: [15,3], px: ["................................","....................yY..........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.....u...","........MmoDDDDDDDDDDomM........","............mM...mMMM...u.......","...........mMMM..xxxx.u........."] },
+ { ms: 110, dx: -1, head: [15,3], px: ["................................","....................yY..........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........","........MmoDDDDDDDDDDomM........","............mM....mM......u.....","...........mMMM..mMMM.u.u......."], exit: true },
+ { ms: 110, dx: -1, head: [15,4], px: ["................................","....................yY..........","....................M...........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom....u....","........MmoDDDDDDDDDDomM.u......","...........mMMM..mMMM..u........"] },
+ { ms: 110, dx: -1, head: [15,2], px: ["................................","....................yY..........",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDomM........","........MmoDDDDDDDDDDo......u...","...........mMMM...mM......u.....","..................mM............","...........xxxx..mMMM.u........."] },
+ { ms: 110, dx: -1, head: [15,3], px: ["................................","....................yY..........","...................M............",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBwsssssssssssBBDo.......",".....oLBtgGttttttgGtttBDo.......",".....oLBsGGssssssGGsssBDo.......",".....oLBttttGttGttttttBDo.......",".....oLBBssssGGssssssBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo.....u..",".........moBsGsYsRsBDom.........","........MmoDDDDDDDDDDomM.u......","...........mMMM...mM...u........","...........xxxx..mMMM..........."] },
+ ] },
"hop": { loop: false, frames: [
{ ms: 130, head: [16,4], px: ["................................","....................yY..........","....................M...........","....................M...........","........oooooooooooooooo........",".......oLLLLLLLLLLLLLLLBo.......","......oLBBwsssssssssssBBDo......","......oLBttttttttttttttBDo......","......oLBssGGssssssGGssBDo......","......oLBttttttttttttttBDo......","......oLBBsssssGGsssssBBDo......","......oBBGBBBBBBBBBMBMBBDo......",".......oooooooooooooooooo.......",".........moBsGsYsRsBDom.........","........MmoDDDDDDDDDDomM........","...........mMMM..mMMM..........."] },
{ ms: 120, head: [16,6], px: ["................................","................................","................................","....................yY..........","....................M...........","....................M...........",".......oooooooooooooooooo.......","......oLLLLLLLLLLLLLLLLLBo......",".....oLBBwsssssssssssssBBDo.....",".....oLBttGGGttttttGGGttBDo.....",".....oLBsssssssGGsssssssBDo.....",".....oLBBttttttttttttttBBDo.....",".....oBBGBBBBBBBBBBBMBMBBDo.....","......oooooooooooooooooooo......","......MmmoDDDDDDDDDDDDommM......","..........mMMM....mMMM.........."] },
@@ -135,6 +145,16 @@ export const CRT_SHEET: PetSheet = {
{ ms: 140, dx: 1, head: [17,3], px: ["....n...........................","...u..u...............MM........",".......n.............M..YR......",".........oooooooooooooooo.......","........oLLLLLLLLLLLLLLLBo......",".......oLBBeeeeeeeeeeeeBBDo.....",".......oLBethhtttttthhteBDo.....",".......oLBesGGssssssGGseBDo.....",".......oLBettttGhhGtttteBDo.....",".......oLBBessssRRsssseBBDo.....",".......oBBGBBBBBBBBBMBMBBDo.....","........oooooooooooooooooo......",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM...mMMM.M.........","...........mMMM..xxxx..........."] },
{ ms: 140, dx: 1, head: [17,3], px: ["..n..u..........................","....u...........................","......n..............M..M.......",".........ooooooooooooooooYR.....","........oLLLLLLLLLLLLLLLBo......",".......oLBBeeeeeeeeeeeeBBDo.....",".......oLBethhtttttthhteBDo.....",".......oLBesGGssssssGGseBDo.....",".......oLBettttGhhGtttteBDo.....",".......oLBBessssRRsssseBBDo.....",".......oBBGBBBBBBBBBMBMBBDo.....","........oooooooooooooooooo......",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM....mM..M.........","...........mMMM..mMMM..........."] },
] },
+ "pant-walk-left": { loop: true, frames: [
+ { ms: 140, dx: -1, head: [15,3], px: ["................................",".................MM......u......","...............YR..M....n.n.....",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.C.....",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM....mM..M.........","...........mMMM..mMMM..........."], exit: true },
+ { ms: 140, dx: -1, head: [15,4], px: ["..........................u.....",".........................n.n....",".................MM.............","...............YR..M...n........",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M.mMMM..mMMM.M........."] },
+ { ms: 140, dx: -1, head: [15,3], px: ["..........................nu....",".................MM.........u...","...............YR..M...n........",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM...mMMM.M.........","...........mMMM..xxxx..........."] },
+ { ms: 140, dx: -1, head: [15,3], px: ["............................n...","........................n....u..","..............YRM..M.....u......",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM....mM..M.........","...........mMMM..mMMM..........."] },
+ { ms: 140, dx: -1, head: [15,3], px: [".............................u..",".................MM.......u.....","...............YR..M.....n.n....",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.C.....",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM....mM..M.........","...........mMMM..mMMM..........."], exit: true },
+ { ms: 140, dx: -1, head: [15,4], px: ["...........................u....","..........................n.....",".................MM.............","...............YR..M...un.......",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M.mMMM..mMMM.M........."] },
+ { ms: 140, dx: -1, head: [15,3], px: ["...........................n....",".................MM......u..u...","...............YR..M....n.......",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M.mMMM...mM..M.........","...........xxxx..mMMM..........."] },
+ { ms: 140, dx: -1, head: [15,3], px: ["..........................u..n..","...........................u....","..............YRM..M.....n......",".......oooooooooooooooo.........","......oLLLLLLLLLLLLLLLBo........",".....oLBBeeeeeeeeeeeeBBDo.......",".....oLBethhtttttthhteBDo.......",".....oLBesGGssssssGGseBDo.......",".....oLBettttGhhGtttteBDo.......",".....oLBBessssRRsssseBBDo.......",".....oBBGBBBBBBBBBMBMBBDo.......","......oooooooooooooooooo........",".........moBsGsYsRsBDom.........",".........moDDDDDDDDDDom.........",".........M..mM....mM..M.........","...........mMMM..mMMM..........."] },
+ ] },
"scrunch": { loop: false, frames: [
{ ms: 100, head: [16,2], px: ["....................yY..........","....................M...........","........oooooooooooooooo........",".......oLLLLLLLLLLLLLLLBo.......","......oLBBwGGssssssGGsBBDo......","......oLBttGGttttttGGttBDo......","......oLBssssssssssssssBDo......","......oLBttttttGGttttttBDo......","......oLBBsssssGGsssssBBDo......","......oBBGBBBBBBBBBMBMBBDo......",".......oooooooooooooooooo.......",".........moBsGsYsRsBDom.........","........MmoDDDDDDDDDDomM........","............mM....mM............","............mM....mM............","...........mMMM..mMMM..........."] },
{ ms: 80, head: [16,6], px: ["................................","................................","................................","....................yY..........","....................M...........","....................M...........",".......oooooooooooooooooo.......","......oLLLLLLLLLLLLLLLLLBo......",".....oLBBwsssssssssssssBBDo.....",".....oLBttGGGttttttGGGttBDo.....",".....oLBsssssssGGsssssssBDo.....",".....oLBBttttttttttttttBBDo.....",".....oBBGBBBBBBBBBBBMBMBBDo.....","......oooooooooooooooooooo......","......MmmoDDDDDDDDDDDDommM......","..........mMMM....mMMM.........."] },
diff --git a/hooks/sprites/ghost.ts b/hooks/sprites/ghost.ts
index 5fdc9161..c7218575 100644
--- a/hooks/sprites/ghost.ts
+++ b/hooks/sprites/ghost.ts
@@ -33,6 +33,16 @@ export const GHOST_SHEET: PetSheet = {
{ ms: 120, dx: 1, head: [13,0], px: ["..........LWWWWS........","........LLWWWWWWWS......",".......LWWWWWWWWWWS.....",".......WWWEEWWWWEES.....",".......WWWEEWWWWEES.....",".......WKKWWWWWWKKSS....","....fWWWWWWWWWWWWS......","......WWWWWWWWWWWS......","...f.S.WS.WS.WS.........",".g......................","........................","..........oooo.........."] },
{ ms: 120, dx: 1, head: [13,1], px: ["........................","..........LWWWWS........","........LLWWWWWWWS......",".......LWWWWWWWWWWS.....",".......WWWEEWWWWEES.....",".......WWWEEWWWWEES.....",".......WKKWWWWWWKKS.....",".....WWWWWWWWWWWWSS.....","......WWWWWWWWWWWS......","...g.WS.WS.WS.WS........","...g...S..S..S..........",".........oooooo........."] },
] },
+ "walk-left": { loop: true, frames: [
+ { ms: 120, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......","....WWWWWWWWWWWWSSSf....","......WWWWWWWWWWWS......","........WS.WS.WS.WS.g...","..........S..S..S..g....",".........oooooo........."], exit: true },
+ { ms: 120, dx: -1, head: [11,0], px: ["........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......","....WWWWWWWWWWWWSSSfg...","......WWWWWWWWWWWS......","........W.WS.WS.WSS..g..","...........S..S..S..g...","........................","..........oooo.........."] },
+ { ms: 120, dx: -1, head: [11,0], px: ["........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......","....WWKKWWWWWWKKS.......","......WWWWWWWWWWSSSf....","......WWWWWWWWWWWS......","........W.WS.WS.WSSg....",".....................g..","........................","..........oooo.........."] },
+ { ms: 120, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......",".....WWWWWWWWWWWSSS.....","......WWWWWWWWWWWS......",".........WS.WS.WS.S.f...","...........S..S..S.fg...",".........oooooo........."] },
+ { ms: 120, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......","....WWWWWWWWWWWWSSSf....","......WWWWWWWWWWWS......","........W.WS.WS.WSS..g..","............S..S..S..g..",".........oooooo........."], exit: true },
+ { ms: 120, dx: -1, head: [11,0], px: ["........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......","....WWWWWWWWWWWWSSSfg...","......WWWWWWWWWWWS......","........W.WS.WS.WSSg....",".........S..S..S...g....","........................","..........oooo.........."] },
+ { ms: 120, dx: -1, head: [11,0], px: ["........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......","....WWKKWWWWWWKKS.......","......WWWWWWWWWWSSSf....","......WWWWWWWWWWWS......",".........WS.WS.WS.S.f...","......................g.","........................","..........oooo.........."] },
+ { ms: 120, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WEEWWWWEEWWS.......",".....WEEWWWWEEWWS.......",".....WKKWWWWWWKKS.......",".....WWWWWWWWWWWSSS.....","......WWWWWWWWWWWS......","........WS.WS.WS.WS.g...","..........S..S..S...g...",".........oooooo........."] },
+ ] },
"working": { loop: true, frames: [
{ ms: 110, head: [12,1], px: ["........................",".........LWWWWS.........",".......LLWWWWWWWS.......","......LWWWWWWWWWWS......","......WWWWWWWWWWWS......","......WWEEWWWWEEWS......","......WWEEWWWWEEWS......",".....WWKKWWWWWWKKSS.....","......WWWWWWWWWWWS......",".....sZsZsZssZsZsZs.....",".....ZsZsZsZZsZsZsZ.....",".....uuuZZZZZZZZuuu....."], exit: true },
{ ms: 110, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......","......WWWWWWWWWWWS......","......WEEWWWWEEWWS......","......WEEWWWWEEWWS......",".....WWKKWWWWWWKKSS.....",".....hWWWWWWWWWWWS......",".....sisZsZssZsZsZs.....",".....ZsZsZsZZsZsZsZ.....",".....uuuZZZZZZZZuuu....."] },
@@ -150,6 +160,16 @@ export const GHOST_SHEET: PetSheet = {
{ ms: 140, dx: 1, head: [13,1], px: ["........................","..........LWWWWS........","........LLWWWWWWWS......",".......LWWWWWWWWWWS.....",".......WWWSSWWWWSSS.....",".......WWWEEWWWWEES.....",".......WKKWWWEEWKKSS....","....fWWWWWWWWRWWWS......","......WWWWWWWWWWWS......","...f.S.WS.WS.WS.........",".g......................",".........oooooo........."] },
{ ms: 140, dx: 1, head: [13,2], px: ["........................","........................","..........LWWWWS........","........LLWWWWWWWS......",".......LWWWWWWWWWWS.....",".......WWWSSWWWWSSS.....",".......WWWEEWWWWEES.....",".......WKKWWWEEWKKS.....",".....WWWWWWWWRWWWSS.....","......WWWWWWWWWWWS......","...g.WS.WS.WS.WS........",".........oooooo........."] },
] },
+ "pant-walk-left": { loop: true, frames: [
+ { ms: 140, dx: -1, head: [11,2], px: ["........................","........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......","....WWWWWWRWWWWWSSSf....","......WWWWWWWWWWWS......","........WS.WS.WS.WS.g...",".........oooooo........."], exit: true },
+ { ms: 140, dx: -1, head: [11,1], px: ["........................","...C....LWWWWS..........","...CC.LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......","....WWWWWWRWWWWWSSSfg...","......WWWWWWWWWWWS......","........W.WS.WS.WSS..g..","...........S..S..S..g...",".........oooooo........."] },
+ { ms: 140, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........","...C.LWWWWWWWWWWS.......","...CCWSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......","....WWKKWEEWWWKKS.......","......WWWWRWWWWWSSSf....","......WWWWWWWWWWWS......","........W.WS.WS.WSSg....",".....................g..",".........oooooo........."] },
+ { ms: 140, dx: -1, head: [11,2], px: ["........................","........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......",".....WWWWWRWWWWWSSS.....","......WWWWWWWWWWWS......",".........WS.WS.WS.S.f...",".........oooooo........."] },
+ { ms: 140, dx: -1, head: [11,2], px: ["........................","........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......","....WWWWWWRWWWWWSSSf....","......WWWWWWWWWWWS......","........W.WS.WS.WSS..g..",".........oooooo........."], exit: true },
+ { ms: 140, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......","....WWWWWWRWWWWWSSSfg...","......WWWWWWWWWWWS......","........W.WS.WS.WSSg....",".........S..S..S...g....",".........oooooo........."] },
+ { ms: 140, dx: -1, head: [11,1], px: ["........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......","....WWKKWEEWWWKKS.......","......WWWWRWWWWWSSSf....","......WWWWWWWWWWWS......",".........WS.WS.WS.S.f...","......................g.",".........oooooo........."] },
+ { ms: 140, dx: -1, head: [11,2], px: ["........................","........................","........LWWWWS..........","......LLWWWWWWWS........",".....LWWWWWWWWWWS.......",".....WSSWWWWSSWWS.......",".....WEEWWWWEEWWS.......",".....WKKWEEWWWKKS.......",".....WWWWWRWWWWWSSS.....","......WWWWWWWWWWWS......","........WS.WS.WS.WS.g...",".........oooooo........."] },
+ ] },
"scrunch": { loop: false, frames: [
{ ms: 150, head: [12,1], px: ["........................",".........LWWWWS.........",".......LLWWWWWWWS.......","......LWWWWWWWWWWS......","......WWSSWWWWSSWS......","......WWEEWWWWEEWS......",".....WWWppppppppWSS.....","......WWpZZZpZZpWS......","......WWppppppppWS......","......WS.WS.WS.WS.......","........................",".........oooooo........."] },
{ ms: 250, head: [12,1], px: ["........................",".........LWWWWS.........",".......LLWWWWWWWS.......","......LWWWWWWWWWWS......","......WWWSSWWWWSSS......","......WWWEEWWWWEES......",".....WWWppppppppWSS.....","......WWpZZZpZZpWS......","......WWppppppppWS......",".......WS.WS.WS.WS......","........................",".........oooooo........."] },
diff --git a/test/pets.test.ts b/test/pets.test.ts
index 3b4601d4..748ced93 100644
--- a/test/pets.test.ts
+++ b/test/pets.test.ts
@@ -320,13 +320,15 @@ test('a juggle right after the egg unlock, then back to idle', () => {
expect(petPose(p, 1000 + 3001)).toBe('idle')
})
-test('the ghost follows the user-pet rules: the spec animations plus the dances, walks facing right, headphones and lie-down', () => {
+test('the ghost follows the user-pet rules: the spec animations plus the dances, hand-drawn left walks, headphones and lie-down', () => {
const s = BUILTIN_SHEETS.ghost!
expect([s.w, s.h]).toEqual([24, 12])
- expect(Object.keys(s.animations).filter(n => !IDLE_VARIANTS.includes(n)).sort()).toEqual([...PET_ANIMS.filter(n => !IDLE_VARIANTS.includes(n)), 'dance', 'work-dance'].sort())
+ expect(Object.keys(s.animations).filter(n => !IDLE_VARIANTS.includes(n)).sort()).toEqual([...PET_ANIMS.filter(n => !IDLE_VARIANTS.includes(n)), 'dance', 'work-dance', 'walk-left', 'pant-walk-left'].sort())
expect(Object.keys(s.outfits ?? {})).toEqual(['headphones', 'bow', 'witch', 'crown'])
expect(Object.keys(s.transitions ?? {})).toEqual(['lie-down'])
for (const f of s.animations.walk!.frames) expect(f.dx).toBe(1)
+ for (const f of s.animations['walk-left']!.frames) expect(f.dx).toBe(-1)
+ for (const f of s.animations['pant-walk-left']!.frames) expect(f.dx).toBe(-1)
expect(isClawd('ghost')).toBe(false)
expect(petPalette(s, 'ghost', { body: '#000001' })).toEqual(s.palette)
expect(stripRows(s, [])).toBe(6)
@@ -337,13 +339,15 @@ test('the built-in sheets are clawd, the robot and the ghost, all playable', ()
for (const s of Object.values(BUILTIN_SHEETS)) expect(() => validateSheet(s)).not.toThrow()
})
-test('the robot follows the user-pet rules: the spec animations plus the dances, mirrored walks, headphones and the level outfits', () => {
+test('the robot follows the user-pet rules: the spec animations plus the dances, hand-drawn left walks, headphones and the level outfits', () => {
const s = BUILTIN_SHEETS.robot!
expect([s.w, s.h]).toEqual([32, 16])
- expect(Object.keys(s.animations).filter(n => !IDLE_VARIANTS.includes(n)).sort()).toEqual([...PET_ANIMS.filter(n => !IDLE_VARIANTS.includes(n)), 'dance', 'work-dance'].sort())
+ expect(Object.keys(s.animations).filter(n => !IDLE_VARIANTS.includes(n)).sort()).toEqual([...PET_ANIMS.filter(n => !IDLE_VARIANTS.includes(n)), 'dance', 'work-dance', 'walk-left', 'pant-walk-left'].sort())
expect(Object.keys(s.outfits ?? {})).toEqual(['headphones', 'propeller', 'tophat', 'crown'])
expect(s.transitions ?? {}).toEqual({})
for (const f of s.animations.walk!.frames) expect(f.dx).toBe(1)
+ for (const f of s.animations['walk-left']!.frames) expect(f.dx).toBe(-1)
+ for (const f of s.animations['pant-walk-left']!.frames) expect(f.dx).toBe(-1)
})
test('a pack tint recolors only Clawd', () => {