summaryrefslogtreecommitdiff
path: root/pixel-client
diff options
context:
space:
mode:
Diffstat (limited to 'pixel-client')
-rw-r--r--pixel-client/Cargo.toml15
-rw-r--r--pixel-client/assets/.gitignore4
-rw-r--r--pixel-client/assets/connect.csv1
-rw-r--r--pixel-client/assets/items.ini66
-rw-r--r--pixel-client/assets/misc.ini7
-rw-r--r--pixel-client/assets/palette.csv122
-rw-r--r--pixel-client/assets/textures/book.ta18
-rw-r--r--pixel-client/assets/textures/bread.ta16
-rw-r--r--pixel-client/assets/textures/bread_slice.ta21
-rw-r--r--pixel-client/assets/textures/burned.ta5
-rw-r--r--pixel-client/assets/textures/chair.ta30
-rw-r--r--pixel-client/assets/textures/coconut.ta24
-rw-r--r--pixel-client/assets/textures/coconut_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/coconut_strawberry_puree_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/costumer.ta38
-rw-r--r--pixel-client/assets/textures/counter.ta36
-rw-r--r--pixel-client/assets/textures/counter_window_ns_bottom.ta48
-rw-r--r--pixel-client/assets/textures/counter_window_ns_top.ta48
-rw-r--r--pixel-client/assets/textures/counter_window_we_bottom.ta48
-rw-r--r--pixel-client/assets/textures/counter_window_we_top.ta48
-rw-r--r--pixel-client/assets/textures/crate_back.ta36
-rw-r--r--pixel-client/assets/textures/crate_front.ta36
-rw-r--r--pixel-client/assets/textures/cutting_board.ta36
-rw-r--r--pixel-client/assets/textures/door_ns.ta42
-rw-r--r--pixel-client/assets/textures/door_we.ta72
-rw-r--r--pixel-client/assets/textures/dough.ta16
-rw-r--r--pixel-client/assets/textures/dough_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/fish.ta19
-rw-r--r--pixel-client/assets/textures/fish_slice.ta16
-rw-r--r--pixel-client/assets/textures/floor.ta24
-rw-r--r--pixel-client/assets/textures/flour.ta16
-rw-r--r--pixel-client/assets/textures/flour_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/freezer.ta42
-rw-r--r--pixel-client/assets/textures/glass.ta19
-rw-r--r--pixel-client/assets/textures/grass.ta30
-rw-r--r--pixel-client/assets/textures/interact_target_thick.ta24
-rw-r--r--pixel-client/assets/textures/interact_target_thin.ta24
-rw-r--r--pixel-client/assets/textures/leek.ta18
-rw-r--r--pixel-client/assets/textures/leek_in_pot.ta10
-rw-r--r--pixel-client/assets/textures/milk_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/milk_strawberry_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/nigiri_rice.ta15
-rw-r--r--pixel-client/assets/textures/oven.ta40
-rw-r--r--pixel-client/assets/textures/particle.ta2
-rw-r--r--pixel-client/assets/textures/path.ta24
-rw-r--r--pixel-client/assets/textures/plate.ta23
-rw-r--r--pixel-client/assets/textures/plate_dirty.ta23
-rw-r--r--pixel-client/assets/textures/player.ta38
-rw-r--r--pixel-client/assets/textures/pot_back.ta20
-rw-r--r--pixel-client/assets/textures/pot_front.ta20
-rw-r--r--pixel-client/assets/textures/rice.ta22
-rw-r--r--pixel-client/assets/textures/rice_cooked_in_pot.ta6
-rw-r--r--pixel-client/assets/textures/rice_flour.ta5
-rw-r--r--pixel-client/assets/textures/rice_flour_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/rice_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/rice_in_pot.ta6
-rw-r--r--pixel-client/assets/textures/sink.ta36
-rw-r--r--pixel-client/assets/textures/solid.ta1
-rw-r--r--pixel-client/assets/textures/steak.ta20
-rw-r--r--pixel-client/assets/textures/steak_in_pot.ta9
-rw-r--r--pixel-client/assets/textures/steak_raw.ta20
-rw-r--r--pixel-client/assets/textures/steak_raw_in_pot.ta9
-rw-r--r--pixel-client/assets/textures/stove.ta36
-rw-r--r--pixel-client/assets/textures/strawberry.ta23
-rw-r--r--pixel-client/assets/textures/strawberry_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/strawberry_icecream.ta14
-rw-r--r--pixel-client/assets/textures/strawberry_icecream_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/strawberry_puree_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/strawberry_shake_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/strawberry_shake_glass.ta19
-rw-r--r--pixel-client/assets/textures/table.ta36
-rw-r--r--pixel-client/assets/textures/tomato.ta17
-rw-r--r--pixel-client/assets/textures/tomato_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/tomato_juice_foodprocessor.ta26
-rw-r--r--pixel-client/assets/textures/tomato_juice_in_pot.ta12
-rw-r--r--pixel-client/assets/textures/tomato_slice.ta14
-rw-r--r--pixel-client/assets/textures/tomato_soup.ta18
-rw-r--r--pixel-client/assets/textures/tomato_soup_in_pot.ta16
-rw-r--r--pixel-client/assets/textures/trash.ta36
-rw-r--r--pixel-client/assets/textures/tree.ta72
-rw-r--r--pixel-client/assets/textures/wall_ns.ta47
-rw-r--r--pixel-client/assets/textures/wall_we.ta42
-rw-r--r--pixel-client/assets/textures/wall_wen.ta54
-rw-r--r--pixel-client/assets/textures/wall_wens.ta54
-rw-r--r--pixel-client/assets/textures/wall_wes.ta48
-rw-r--r--pixel-client/assets/textures/wall_wn.ta54
-rw-r--r--pixel-client/assets/textures/wall_wns.ta54
-rw-r--r--pixel-client/assets/textures/wall_ws.ta48
-rw-r--r--pixel-client/assets/textures/water_glass.ta19
-rw-r--r--pixel-client/assets/textures/window.ta42
-rw-r--r--pixel-client/assets/tiles.ini54
-rw-r--r--pixel-client/makefile37
-rw-r--r--pixel-client/src/game.rs344
-rw-r--r--pixel-client/src/helper.rs11
-rw-r--r--pixel-client/src/main.rs105
-rw-r--r--pixel-client/src/network.rs123
-rw-r--r--pixel-client/src/render/misc.rs17
-rw-r--r--pixel-client/src/render/mod.rs158
-rw-r--r--pixel-client/src/render/sprite.rs76
-rw-r--r--pixel-client/src/tilemap.rs117
-rw-r--r--pixel-client/tools/Cargo.toml12
-rw-r--r--pixel-client/tools/src/bin/bunnymark.rs104
-rw-r--r--pixel-client/tools/src/bin/tex_compose.rs135
-rw-r--r--pixel-client/tools/src/bin/tex_export.rs75
-rw-r--r--pixel-client/tools/src/bin/tex_import.rs75
-rw-r--r--pixel-client/tools/src/bin/tex_pack.rs95
-rw-r--r--pixel-client/tools/src/lib.rs0
108 files changed, 4117 insertions, 0 deletions
diff --git a/pixel-client/Cargo.toml b/pixel-client/Cargo.toml
new file mode 100644
index 00000000..d7cb336c
--- /dev/null
+++ b/pixel-client/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "light-client"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+sdl2 = { version = "0.37.0", features = ["image", "ttf"] }
+hurrycurry-protocol = { path = "../server/protocol" }
+tungstenite = { version = "0.23.0", features = ["rustls-tls-native-roots"] }
+serde_json = "1.0.120"
+bincode = "2.0.0-rc.3"
+log = "0.4.22"
+env_logger = "0.11.3"
+anyhow = "1.0.86"
+clap = { version = "4.5.9", features = ["derive"] }
diff --git a/pixel-client/assets/.gitignore b/pixel-client/assets/.gitignore
new file mode 100644
index 00000000..89bda45f
--- /dev/null
+++ b/pixel-client/assets/.gitignore
@@ -0,0 +1,4 @@
+*.png
+/atlas.ta
+/atlas.meta.csv
+/sprites
diff --git a/pixel-client/assets/connect.csv b/pixel-client/assets/connect.csv
new file mode 100644
index 00000000..9278f64c
--- /dev/null
+++ b/pixel-client/assets/connect.csv
@@ -0,0 +1 @@
+wall,door,wall-window,counter-window
diff --git a/pixel-client/assets/items.ini b/pixel-client/assets/items.ini
new file mode 100644
index 00000000..10bb2064
--- /dev/null
+++ b/pixel-client/assets/items.ini
@@ -0,0 +1,66 @@
+tomato=tomato
+raw-steak=steak_raw
+flour=flour
+leek=leek
+rice=rice
+fish=fish
+coconut=coconut
+strawberry=strawberry
+
+
+foodprocessor=foodprocessor
+dough-foodprocessor=dough_foodprocessor
+flour-foodprocessor=flour_foodprocessor
+tomato-foodprocessor=tomato_foodprocessor
+tomato-juice-foodprocessor=tomato_juice_foodprocessor
+strawberry-foodprocessor=strawberry_foodprocessor
+strawberry-puree-foodprocessor=strawberry_puree_foodprocessor
+coconut-foodprocessor=coconut_foodprocessor
+milk-foodprocessor=milk_foodprocessor
+coconut-strawberry-puree-foodprocessor=coconut_strawberry_puree_foodprocessor
+milk-strawberry-foodprocessor=milk_strawberry_foodprocessor
+strawberry-shake-foodprocessor=strawberry_shake_foodprocessor
+strawberry-icecream-foodprocessor=strawberry_icecream_foodprocessor
+rice-foodprocessor=rice_foodprocessor
+rice-flour-foodprocessor=rice_flour_foodprocessor
+
+
+pot=pot_back,pot_front
+rice-flour-pot=pot_back,rice_flour,pot_front
+burned-pot=pot_back,burned,pot_front
+raw-steak-pot=pot_back,steak_raw_in_pot,pot_front
+steak-pot=pot_back,steak_in_pot,pot_front
+leek-pot=pot_back,leek_in_pot,pot_front
+tomato-soup-pot=pot_back,tomato_soup_in_pot,pot_front
+tomato-juice-pot=pot_back,tomato_juice_in_pot,pot_front
+leek-tomato-juice-pot=pot_back,tomato_juice_in_pot,leek_in_pot,pot_front
+rice-pot=pot_back,rice_in_pot,pot_front
+cooked-rice-pot=pot_back,rice_cooked_in_pot,pot_front
+
+
+sliced-tomato=tomato_slice
+sliced-fish=fish_slice
+bread=bread
+burned=burned
+dough=dough
+bread-slice=bread_slice
+nigiri=nigiri_rice,fish_slice
+
+
+glass=glass
+strawberry-shake-glass=strawberry_shake_glass
+water-glass=water_glass
+
+
+plate=plate
+dirty-plate=plate_dirty
+tomato-slice-plate=plate,tomato_slice~x8~y16
+strawberry-icecream-plate=plate,strawberry_icecream
+steak-plate=plate,steak
+bread-slice-plate=plate,bread_slice
+bread-slice-steak-plate=plate,bread_slice,steak
+bread-slice-sliced-tomato-plate=plate,bread_slice,tomato_slice
+bread-slice-sliced-tomato-steak-plate=plate,bread_slice,steak,tomato_slice
+sliced-tomato-steak-plate=plate,steak,tomato_slice
+tomato-soup-plate=plate,tomato_soup
+nigiri-plate=plate,nigiri_rice,fish_slice
diff --git a/pixel-client/assets/misc.ini b/pixel-client/assets/misc.ini
new file mode 100644
index 00000000..60a91e77
--- /dev/null
+++ b/pixel-client/assets/misc.ini
@@ -0,0 +1,7 @@
+
+player=player
+costumer=costumer
+interact-target-thick=interact_target_thick
+interact-target-thin=interact_target_thin
+solid=solid
+particle=particle
diff --git a/pixel-client/assets/palette.csv b/pixel-client/assets/palette.csv
new file mode 100644
index 00000000..87376994
--- /dev/null
+++ b/pixel-client/assets/palette.csv
@@ -0,0 +1,122 @@
+ ,0,0,0,0
+a,255,255,255,255
+b,242,242,242,255
+c,230,230,230,255
+d,217,217,217,255
+e,204,204,204,255
+f,191,191,191,255
+g,178,178,178,255
+h,166,166,166,255
+i,153,153,153,255
+j,140,140,140,255
+k,128,128,128,255
+l,115,115,115,255
+m,102,102,102,255
+n,89,89,89,255
+o,76,76,76,255
+p,64,64,64,255
+q,51,51,51,255
+r,38,38,38,255
+s,26,26,26,255
+t,0,0,0,255
+u,242,252,36,255
+v,255,234,0,255
+w,254,167,17,255
+x,254,139,104,255
+y,251,59,2,255
+z,254,53,33,255
+A,208,0,0,255
+B,168,31,61,255
+C,120,4,34,255
+D,43,0,0,255
+E,241,226,197,255
+F,254,228,179,255
+G,254,218,187,255
+H,254,194,142,255
+I,216,143,87,255
+J,189,99,64,255
+K,162,64,43,255
+L,99,53,45,255
+M,107,40,51,255
+N,52,18,12,255
+O,231,203,143,255
+P,209,179,139,255
+Q,193,177,127,255
+R,215,152,11,255
+S,255,177,0,255
+T,254,139,0,255
+U,255,106,0,255
+V,183,65,0,255
+W,95,62,29,255
+X,59,35,0,255
+Y,254,202,218,255
+Z,254,101,203,255
+0,254,19,146,255
+1,221,48,98,255
+2,192,74,109,255
+3,137,22,136,255
+4,77,38,137,255
+5,68,21,33,255
+6,44,17,57,255
+7,36,20,34,255
+8,255,255,125,255
+9,255,255,0,255
+!,255,127,0,255
+",255,125,125,255
+§,255,125,255,255
+$,255,0,254,255
+%,255,0,127,255
+&,255,0,0,255
+/,127,0,0,255
+(,10,10,0,255
+),246,253,255,255
+=,233,247,255,255
+?,207,230,254,255
+[,170,199,254,255
+],119,179,254,255
+{,30,116,253,255
+},0,70,170,255
+^,47,68,118,255
++,0,48,82,255
+-,14,14,37,255
+*,238,245,240,255
+~,214,229,222,255
+#,172,216,185,255
+',108,173,198,255
+.,66,169,175,255
+:,0,127,127,255
+;,73,103,92,255
+\,46,78,78,255
+<,29,50,57,255
+>,15,28,33,255
+|,216,255,244,255
+ö,184,244,245,255
+ä,174,204,181,255
+ü,118,197,120,255
+Ö,53,135,87,255
+Ä,64,155,104,255
+Ü,70,135,104,255
+ß,31,81,43,255
+¿,42,60,55,255
+¡,18,46,29,255
+ẞ,239,255,201,255
+Æ,230,243,133,255
+æ,188,245,28,255
+€,212,220,24,255
+Ø,130,211,34,255
+ł,92,127,0,255
+Ł,89,147,43,255
+Ω,41,127,0,255
+€,0,67,32,255
+«,28,51,34,255
+»,0,255,127,255
+‹,0,255,0,255
+›,125,255,125,255
+„,125,255,255,255
+“,0,255,255,255
+@,125,125,255,255
+Ŧ,127,0,255,255
+ŧ,0,0,255,255
+ø,63,0,127,255
+¤,0,0,127,255
+°,255,255,255,128
diff --git a/pixel-client/assets/textures/book.ta b/pixel-client/assets/textures/book.ta
new file mode 100644
index 00000000..b9ca1ad6
--- /dev/null
+++ b/pixel-client/assets/textures/book.ta
@@ -0,0 +1,18 @@
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+33333333333333
+$$$$$$$$$$$$$$
+$GGGGGGGGGGGG
+$cccccccccccc
+$$$$$$$$$$$$$$
diff --git a/pixel-client/assets/textures/bread.ta b/pixel-client/assets/textures/bread.ta
new file mode 100644
index 00000000..5f4c8b85
--- /dev/null
+++ b/pixel-client/assets/textures/bread.ta
@@ -0,0 +1,16 @@
+ KKK
+ KKLLKKKKLLKK
+ LLLKKLLKKKLLLKKLL
+ KLLKKLLKKKKLLKKKLLLK
+ KKLLKKLLKKKLLKKKKLLKKK
+ KKLLKKKLLKKKLLKKKKLLKKK
+ KKLLKKKLKKKKLLKKKKLKKKKK
+ KKKLKKKKKKKKKKLKKKKLLKKKKK
+ KKKKKKKKKKKKKKKKKKKKKKKKKK
+LLKKKKKKKKKKKKKKKKKKKKKKKKL
+LLLKKKKKKKKKKKKKKKKKKKKKLLL
+LLLLLKKKKKKKKKKKKKKKKKLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLLLLLLL
diff --git a/pixel-client/assets/textures/bread_slice.ta b/pixel-client/assets/textures/bread_slice.ta
new file mode 100644
index 00000000..658b2d36
--- /dev/null
+++ b/pixel-client/assets/textures/bread_slice.ta
@@ -0,0 +1,21 @@
+ LLLLLLLLLLLL
+ LLLLLLLLLLLLLLLL
+ LLLLLJJJJJJJJLLLLL
+ LLLLJJJJJJJJJJJJLLLL
+LLLLJJJJJJJJJJJJJLLLL
+LLLJJJJJJJJJJJJJJJLLLL
+LLLJJJJJJJJJJJJJJJJLLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLJJJJJJJJJJJJJJJJJJLL
+LLLJJJJJJJJJJJJJJJJLLL
+ LLLLLLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLLLL
diff --git a/pixel-client/assets/textures/burned.ta b/pixel-client/assets/textures/burned.ta
new file mode 100644
index 00000000..fa13c7cb
--- /dev/null
+++ b/pixel-client/assets/textures/burned.ta
@@ -0,0 +1,5 @@
+ (D((((DD
+ ((>(>>>>(((
+((D>((Dt>>((D(
+ ((((>tDtDD((
+ ((((>(((
diff --git a/pixel-client/assets/textures/chair.ta b/pixel-client/assets/textures/chair.ta
new file mode 100644
index 00000000..f739e389
--- /dev/null
+++ b/pixel-client/assets/textures/chair.ta
@@ -0,0 +1,30 @@
+ JJJJJJJJJJJJJJ
+ JJJJJJJJJJJJJJJJJJ
+ JJJJJJJJJJJJJJJJJJJJJK
+ JJJJJJJJJJJJJJJJJJJJJJKK
+ JJJJJJJJJKKJJKKKKJJJJJJJKK
+ JJJJJJJJJJJJJJJJJJKJJJJJJKK
+ JJJJJJJKJJJJJJJJJJJJJJJJJJJK
+ JJJJJJJKJJJJJJJJJJJJJJJJJJJJKK
+ JJJJJJKJJJJJJJJJJJJJJJJJKJJJJK
+ JJJJJKJJJJJJJJJJJJJJJJJJJKJJJKK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJKJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJKJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJKJJJJ
+LKJJJJKJJJJJJJJJJJJJJJJJJJKJJJJJ
+LKJJJJKJJJJJJJJJJJJJJJJJJJJJJJJJ
+ KKJJJJKJJJJJJJJJJJJJJJJJJJJJJJL
+ LKKJJJJKJJJJJJJJJJJJJJJJJJJJJLL
+ LLKJJJJJJJJJJJJJJJJJJJKJJJJJJL
+ LKKJJJJJJJJJJJJJJJJKKJJJJJJL
+ LKKJJJJJJKKJJJJJKJJJJJJJJLL
+ LLKKKKJJJJJKKJJJJJJJJJJJLL
+ mLLLKKKJJJJJJJJJJJJJJJLLLm
+ mmLLLLKKKJJJJJJJJJJJLLLLm
+ mmmjLLLLLLKKKJJJLLLLLLmmm
+ mmmjjLLLLLLLLLLLLLLmmmm
+ mmjjjjjjLLLLLLjjmmmmm
+ mmjjjjjjjjjjjjmmmmm
+ mmmjjjjjjjjjjmmmm
+ mmmmmjjjjjmmm
diff --git a/pixel-client/assets/textures/coconut.ta b/pixel-client/assets/textures/coconut.ta
new file mode 100644
index 00000000..78d1d10d
--- /dev/null
+++ b/pixel-client/assets/textures/coconut.ta
@@ -0,0 +1,24 @@
+ K
+ KLN
+ LLLKKNL
+ LLLLLLLLLNN5
+ NNLLLLLNNLLNL5
+ NNFFFFNNLLLLLLLL
+ NFFFPPPPPLKLLKKKL
+ NFFPPPPPPLKLLLKKLL
+ NNFFPPPPQQLKLLLKKKL
+NNNFPPPQQQQLKLLNLKKLL
+NNKLPPPQQQQLLLNNLKKNL
+NKLLLPQQQQLLKLNLLLKLNL
+NKKLLLL55LLKKLLLLLKLNL
+NKKLNNL5LLLKLLL55LLLNL
+KKKKNLLLLLKKLLLLLLLLNL
+KKKKNLLLLLLLLLLL5LLLL
+KKKKLLLNLLLLLKLLLLLLL
+ KKKLLNLLLLLKKLLLLL5
+ KKKLNLLLLKKLLLNLN5
+ KKKKKLNLLKLLLLNNN
+ KKKKKNLLLLNLNNN
+ KKNNLNNLNNNNN
+ NNNNNN55N
+ NN555
diff --git a/pixel-client/assets/textures/coconut_foodprocessor.ta b/pixel-client/assets/textures/coconut_foodprocessor.ta
new file mode 100644
index 00000000..2d52ec49
--- /dev/null
+++ b/pixel-client/assets/textures/coconut_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ hL°°°°°°°hhh
+[[[hDL]]]]]]h[[h
+[]]h]]LLLL]Lh]]h
+[]]h]LLLXLL]h]]h
+]]]hLWWXLLLLh]]h
+]]]hWWLLWLLLhhh]
+]]]hWWLLWWLWh]]]
+]]]hWXXLWWWWh]]]
+]]]hWXXLWWW5h]]]
+]]]]hLXXWW5h]]]]
+]]]]]hWWMMh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/coconut_strawberry_puree_foodprocessor.ta b/pixel-client/assets/textures/coconut_strawberry_puree_foodprocessor.ta
new file mode 100644
index 00000000..e2d9f4c8
--- /dev/null
+++ b/pixel-client/assets/textures/coconut_strawberry_puree_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°hWWWWh°h
+ hN(hhhhNNh
+ h(XNNNNNWhhh
+[[[hNNXXXWWWh[[h
+[]]hBBXXWWWBh]]h
+[]]h2BBBBBB2h]]h
+]]]h22222222h]]h
+]]]h22222222hhh]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]]h222222h]]]]
+]]]]]h2222h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/costumer.ta b/pixel-client/assets/textures/costumer.ta
new file mode 100644
index 00000000..602b0b21
--- /dev/null
+++ b/pixel-client/assets/textures/costumer.ta
@@ -0,0 +1,38 @@
+
+
+
+
+ vvvvv
+ vvvvvvvvv
+ vvvvvvvvvv
+ vvvvvvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvv
+ Rvvvvvvvvvv
+ RvvvvvvvvvR
+ RvvvvvvvR
+ RRvvvRR
+ wwwwRRwww
+ wwwwwwwvvvv
+ wwwwvvvvvvvv
+ vvwvvvvvvvvvv
+ vvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvvvv
+ wvvvvvvvvvvvvvvvvvvvvvvvvw
+ wwvvvvvvvvvvvvvvvvvvvvvvww
+ wwwvvvvvvvvvvvvvvvvvvvwww
+ wwwwwvvvvvvvvvvvvvvvwwww
+ wwwwwwwvvvvvvvvvvwwwww
+ wwwwwwwwwwwwwwwwwwww
+ wwwwwwwwwwwwwwww
+ wwwwwwwwwwwwww
+ wwwwwwwwwwww
diff --git a/pixel-client/assets/textures/counter.ta b/pixel-client/assets/textures/counter.ta
new file mode 100644
index 00000000..846fdbe3
--- /dev/null
+++ b/pixel-client/assets/textures/counter.ta
@@ -0,0 +1,36 @@
+KKKJJJJJJJJJJJJJJJJJJJJJJJJJJKKK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJKKKKKJJJJJJJJJJJJJJJJJJJKKKKKK
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPI
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPI
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPI
+IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPI
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
diff --git a/pixel-client/assets/textures/counter_window_ns_bottom.ta b/pixel-client/assets/textures/counter_window_ns_bottom.ta
new file mode 100644
index 00000000..30db9f28
--- /dev/null
+++ b/pixel-client/assets/textures/counter_window_ns_bottom.ta
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+KKKJJJJJJJJJJJJJJJJJJJJJJJJJJKKK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JKKKKKJJJJJJJJJJJJJJJJJJJJJKKKKK
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+
diff --git a/pixel-client/assets/textures/counter_window_ns_top.ta b/pixel-client/assets/textures/counter_window_ns_top.ta
new file mode 100644
index 00000000..8ac68858
--- /dev/null
+++ b/pixel-client/assets/textures/counter_window_ns_top.ta
@@ -0,0 +1,48 @@
+ LLLLLL
+ LLLLLL
+ LLLLLL
+ LLLLLL
+ LLLLLLLL
+ LLLLLLLL
+ LLLLLLLLLL
+ LLLLLLLLLLLL
+ LLLLLLLLLLLL
+ LLLLLLLLLLLLLL
+ LLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLL
+ LLLLLLLLLLLLLL
+ LLLLLLLLLLLL
+ LLLLLLLLLLLL
+ LLLLLLLLLL
+ LLLLLLLL
+ LLLLLLLL
+ LLLLLL
+ LLLLLL
+ LLLLLL
+ LLLLLL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/counter_window_we_bottom.ta b/pixel-client/assets/textures/counter_window_we_bottom.ta
new file mode 100644
index 00000000..8cce3e6a
--- /dev/null
+++ b/pixel-client/assets/textures/counter_window_we_bottom.ta
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJK
+JKKKKKKJJJJJJJJJJJJJJJJJJJKKKKKK
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/counter_window_we_top.ta b/pixel-client/assets/textures/counter_window_we_top.ta
new file mode 100644
index 00000000..b7113a01
--- /dev/null
+++ b/pixel-client/assets/textures/counter_window_we_top.ta
@@ -0,0 +1,48 @@
+ LL
+ LLLLLL
+ LLLLLLLL
+ LLLLLLLLLLLL
+ LLLLLLLLLLLLLLLL
+ LLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+cccccLLLLLLLLLLLLLLLLLLLLLLccccc
+ccccccccLLLLLLLLLLLLLLLLcccccccc
+cc LLLLLLLLLLLL cc
+cc LLLLLLLL cc
+cc LLLLLL cc
+cc LL cc
+cc cc
+cc cc
+cc cc
+cc cc
+cc cc
+ff ff
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/crate_back.ta b/pixel-client/assets/textures/crate_back.ta
new file mode 100644
index 00000000..2f434d67
--- /dev/null
+++ b/pixel-client/assets/textures/crate_back.ta
@@ -0,0 +1,36 @@
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+NNNNNNNLNNNNNNNNLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNNLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNNLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNNLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNNLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNLLNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNLNNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNLNNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNLNNNNNNNNLNNNNNNN
+NNNNNNNLNNNNNNNLNNNNNNNNLNNNNNNN
+NNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
diff --git a/pixel-client/assets/textures/crate_front.ta b/pixel-client/assets/textures/crate_front.ta
new file mode 100644
index 00000000..ff6e2d83
--- /dev/null
+++ b/pixel-client/assets/textures/crate_front.ta
@@ -0,0 +1,36 @@
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+L L
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+LKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKL
+KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+L L
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+LKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKL
+KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+L L
+LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+LKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKL
diff --git a/pixel-client/assets/textures/cutting_board.ta b/pixel-client/assets/textures/cutting_board.ta
new file mode 100644
index 00000000..e6137c94
--- /dev/null
+++ b/pixel-client/assets/textures/cutting_board.ta
@@ -0,0 +1,36 @@
+
+
+ xPPxxxxxxxxxxxxxxxxxxPPP
+ xxxxxxxxxxxxxxxxxxxxxxxP
+ PxxxxxxxxxxxxxxxxxxxxxxP
+ Pxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ Pxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxP
+ Pxxxxxxxxxxxxxxxxxxxxxxx
+ xxxxxxxxxxxxxxxxxxxxxxxP
+ xxxxxxxxxxxxxxxxxxxxxxxP
+ PxxxxxxxxxxxxxxxxxxxxxxP
+ PPPxxxxxxxxxxxxxxxxxxPPP
+ LLLLLLLLLLLLLLLLLLLLLLLL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/door_ns.ta b/pixel-client/assets/textures/door_ns.ta
new file mode 100644
index 00000000..8c9270f6
--- /dev/null
+++ b/pixel-client/assets/textures/door_ns.ta
@@ -0,0 +1,42 @@
+jjj jjj
+jjjjjjjjj jjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjfffffffjjjjjjjjjjjjj
+jjjjjfffffffffffffffffffffjjjjjj
+jjffffffffffffffffffffffffffffjj
+ffffffffffffffffffffffffffffffff
+ffffffffffUUUUUUUUUUUfffffffffff
+ffffffUUUUUUUIIIIIUUUUUUUfffffff
+ffffUUUUUIIIIIIIIIIIIIUUUUUfffff
+fffUUUIIIIIIIIIIIIIIIIIIIUUUUfff
+ffUUUIIIIIIIIIIIIIIIIIIIIIIIUUff
+fUUUIIIIIIIIIIIIIIIIIIIIIIIIIUUf
+UUIIIIIIIIIIIIIIIIIIIIIIIIIIIIUU
+UIIIIIIIIIIIIIIIIIIIIIIIIIIIIIUU
+UIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIU
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIII IIII IIIIIII
+IIIIII II IIIIII
+IIIIII II IIIIII
+IIIIIII IIII IIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIII IIII IIIIIII
+IIIIII II IIIIII
+IIIIII II IIIIII
+IIIIIII IIII IIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIUUUUUUIIIIIIIIIIIIIIIIIIIIIII
+IIIUIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIUIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
diff --git a/pixel-client/assets/textures/door_we.ta b/pixel-client/assets/textures/door_we.ta
new file mode 100644
index 00000000..d8ccf839
--- /dev/null
+++ b/pixel-client/assets/textures/door_we.ta
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjj
+ jjjj
+ jjjj
+ jjjj
+ jjjj
+ jj
+ jj
+ jj
+ jj
+ jj
+ jjjj
+ jjjj
+ jjjj
+ jjjj
+ jjjj
+ jjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/dough.ta b/pixel-client/assets/textures/dough.ta
new file mode 100644
index 00000000..157aaaf9
--- /dev/null
+++ b/pixel-client/assets/textures/dough.ta
@@ -0,0 +1,16 @@
+ FFF
+ FFHHFFFFHHFF
+ FHHFFHHFFFHHHFFHH
+ FHHFFHHFFFFHHFFFHHHF
+ FFHHFFHHFFFHHFFFFHHFFF
+ FFHHFFFHHFFFHHFFFFHHFFF
+ FFHHFFFHFFFFHHFFFFHFFFFF
+ FFFHFFFFFFFFFFHFFFFHHFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFF
+HHFFFFFFFFFFFFFFFFFFFFFFFFH
+HHHFFFFFFFFFFFFFFFFFFFFFHHH
+HHHHHFFFFFFFFFFFFFFFFFHHHHH
+HHHHHHHHHHHHHHHHHHHHHHHHHHH
+ HHHHHHHHHHHHHHHHHHHHHHHHH
+ HHHHHHHHHHHHHHHHHHHHHHH
+ HHHHHHHHHHHHHHHHHHHHH
diff --git a/pixel-client/assets/textures/dough_foodprocessor.ta b/pixel-client/assets/textures/dough_foodprocessor.ta
new file mode 100644
index 00000000..df2b08fa
--- /dev/null
+++ b/pixel-client/assets/textures/dough_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[hFFFFFFFFh[[h
+[]]hFFFFFFFFh]]h
+[]]hFFFFFFFFh]]h
+]]]hFFFFFFFFh]]h
+]]]hFFFFFFFFhhh]
+]]]hFFFFFFFFh]]]
+]]]hFFFFFFFFh]]]
+]]]hFFFFFFFFh]]]
+]]]]hFFFFFFh]]]]
+]]]]]hFFFFh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/fish.ta b/pixel-client/assets/textures/fish.ta
new file mode 100644
index 00000000..c1f8f151
--- /dev/null
+++ b/pixel-client/assets/textures/fish.ta
@@ -0,0 +1,19 @@
+ oo oo
+ ooooo oo
+ oooooooo
+ nnnnoooo
+ nnnnooo
+ nnknnno
+ nnnkmnnn
+ mmmkkkmkn
+ llmkjkkkkn
+ llljjkjkkg
+ kkkljjjjjkgg
+ kkkkkjjjjjjxxg
+ ljkjjjjjjjjxxxgg
+ jlljjjjjjjjjjxxgg
+ Fjjjxjjjjjjjjiggg
+FLFjjjljjxxjjiggg
+FFjjjjxlxgxxiggg
+jjjmlxlgggggggg
+ mmll gggggg
diff --git a/pixel-client/assets/textures/fish_slice.ta b/pixel-client/assets/textures/fish_slice.ta
new file mode 100644
index 00000000..efecbc73
--- /dev/null
+++ b/pixel-client/assets/textures/fish_slice.ta
@@ -0,0 +1,16 @@
+ yy
+ zzzyyy
+ VVVVyzyy
+ VVVVVVVyVVy
+ VVVVVVVyyzzVV
+ zzVVyyyVzyyzzV
+ VVVVVVzyzzzyzz
+ VVVVVVVVzyyyyz
+ VVVVVVVVzyyyzz
+ zzzyyyyyzyyzz
+ zzzzzyyyyzyzz
+ yyyyyyyzVzzz
+ yyyyyyyyVzz
+ yyyyyyVVVz
+yzzzVVVV
+zzzzz
diff --git a/pixel-client/assets/textures/floor.ta b/pixel-client/assets/textures/floor.ta
new file mode 100644
index 00000000..ed84d15b
--- /dev/null
+++ b/pixel-client/assets/textures/floor.ta
@@ -0,0 +1,24 @@
+]???????????????????????????????
+]][[[[[[[[[[[[[[[[[[[[[[[[[[[[??
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[?
+][[[[[[[[[[[[[[[[[[[[[[[[[[[[[??
+]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]?
diff --git a/pixel-client/assets/textures/flour.ta b/pixel-client/assets/textures/flour.ta
new file mode 100644
index 00000000..94ca56e5
--- /dev/null
+++ b/pixel-client/assets/textures/flour.ta
@@ -0,0 +1,16 @@
+ GGGGGGGGGGG
+ GGGGGGGGGGGGGGH
+ GGGHHGGGGGGGGGHG
+ GGHHHGGGGGGGGHHG
+GGHH HHGG]]]]]]GGG
+ HHH HHG]]VV]]]]GGG
+ HHH.]VVV]]]]GG
+ HHHH.]VVV]]]GG
+ HHHH.]]VV]]]]HH
+ HHHH.]]]V]]]GG
+ HHHHH.]]]V]]GG
+ HHHHH...]]GGGG
+ HHHHHHGGGGGGGG
+ HHHHHHHHHHHGGG
+ HHHHHHHHHHHHHH
+ HHHHHHHHHH
diff --git a/pixel-client/assets/textures/flour_foodprocessor.ta b/pixel-client/assets/textures/flour_foodprocessor.ta
new file mode 100644
index 00000000..af9a7c93
--- /dev/null
+++ b/pixel-client/assets/textures/flour_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ hEQ°°°°FQhhh
+[[[hFEFFFFQFh[[h
+[]]hQFEFQFEEh]]h
+[]]hQFFEFFFFh]]h
+]]]hEFQFFEFQh]]h
+]]]hFEFFEFQEhhh]
+]]]hFFQFEFFFh]]]
+]]]hFEFQFFEEh]]]
+]]]hQFFFFQFFh]]]
+]]]]hFFFQFFh]]]]
+]]]]]hFEFEh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/foodprocessor.ta b/pixel-client/assets/textures/foodprocessor.ta
new file mode 100644
index 00000000..ef6fa194
--- /dev/null
+++ b/pixel-client/assets/textures/foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]]]]]]]h[[h
+[]]h]]]]]]]]h]]h
+[]]h]]mmmm]]h]]h
+]]]h]mrrrrm]h]]h
+]]]hmrrrrrrmhhh]
+]]]hrrrrrrrrh]]]
+]]]hrrrrrrrrh]]]
+]]]hrrrrrrrrh]]]
+]]]]hrrrrrrh]]]]
+]]]]]hrrrrh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/freezer.ta b/pixel-client/assets/textures/freezer.ta
new file mode 100644
index 00000000..94c66e46
--- /dev/null
+++ b/pixel-client/assets/textures/freezer.ta
@@ -0,0 +1,42 @@
+¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤''''''''''''''''''''''''''''''¤
+¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
+¤öööööööööööööööööööööööööööööö¤
+¤ööööööööööööööööööööööööööööööö
+¤öööööööööööööööööööööööööööööö¤
+ööööööööööööööööööööööööööööööö¤
+¤öööööööööööööööööööööööööööööö¤
+öööööööööööööööööööööööööööööööö
+ööööööööööööööööööööööööööööööö¤
+öööööööööööööööööööööööööööööööö
+öööööööööööööööööööööööööööööööö
+öööööööööööööööööööööööööööööööö
+öööööööööööööööööööööööööööööööö
+öööööööööööööööööööööööööööööööö
+¤ööööööööööööööööööööööööööööööö
+öööööööööööööööööööööööööööööööö
+¤öööööööööööööööööööööööööööööö¤
+¤öööööööööööööööööööööööööööööö¤
+¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
diff --git a/pixel-client/assets/textures/glass.ta b/pixel-client/assets/textures/glass.ta
new file mode 100644
index 00000000..10306095
--- /dev/null
+++ b/pixel-client/assets/textures/glass.ta
@@ -0,0 +1,19 @@
+ a°°°°°°°°a
+ a°°°°°°°°°°a
+a°°°°°°°°°°°°a
+aa°°°°°°°°°°aa
+a°a°°°°°°°°a°a
+a°°aaaaaaaa°°a
+a°°°°°°°°°°°°a
+a°°°°°°°°°°a°a
+a°°°°°°°°°a°°a
+a°°°°°°°°°a°°a
+a°°°°°°°°°a°°a
+a°°°°°°°a°a°°a
+a°°°°°°°a°a°°a
+a°°°°°°°a°°°°a
+a°°°°°°°a°°°°a
+a°°°°°°°a°°°°a
+a°°°°°°a°°°°°a
+ a°°°°a°°°°°a
+ aaaaaaaaaa
diff --git a/pixel-client/assets/textures/grass.ta b/pixel-client/assets/textures/grass.ta
new file mode 100644
index 00000000..359904f9
--- /dev/null
+++ b/pixel-client/assets/textures/grass.ta
@@ -0,0 +1,30 @@
+ ‹‹‹‹
+ ‹Ø ØØ‹
+ ‹‹ ‹ Ø ‹ØØ
+ ‹‹‹ ‹‹ ‹Ø‹ ‹‹‹‹
+ ‹ØØ ‹‹ ‹‹‹ ‹‹‹‹‹‹‹‹‹
+ ‹‹ØØ ‹‹‹‹‹Ø‹ ‹‹ ‹ ‹ØØØØØ‹ØØ
+Ø‹‹ØØØ‹‹‹ØØØØØ‹‹ØØ‹‹‹‹‹‹‹‹‹‹‹Ø‹‹
+ØØØØØØØØ‹ØØØØØØØØØØØØØØ‹ØØØØ‹ØØØ
+Ø‹ØØØØØØ‹ØØØ‹ØØ‹‹ØØØØØØ‹ØØØ‹‹‹ØØ
+ØØ‹‹ØØØØØØØ‹‹ØØ‹‹‹ØØ‹‹‹Ø‹‹‹‹‹‹ØØ
+ØØ‹‹‹‹‹‹‹‹ØØØØØØ‹‹‹ØØØØØ‹ØØØØ‹‹Ø
+ØØØ‹‹ØØØØ‹‹ØØØØ‹‹‹‹‹ØØØØ‹ØØØØØ‹Ø
+ØØØØ‹ØØØØØ‹‹Ø‹‹‹‹‹Ø‹ØØØØ‹ØØØØ‹ØØ
+ØØØØ‹‹ØØØØ‹‹‹Ø‹ØØØØ‹‹ØØØØØ‹‹‹ØØØ
+Ø‹‹‹‹‹ØØØØ‹‹ØØ‹ØØØØØ‹‹ØØØØ‹‹Ø‹‹Ø
+Ø‹ØØØØØØ‹‹‹ØØØ‹‹ØØØØØ‹ØØØØØ‹ØØ‹Ø
+ØØØØØØØØ‹‹ØØ‹‹‹‹‹ØØØØØØØ‹ØØ‹‹ØØØ
+ØØØØØØ‹‹Ø‹‹Ø‹Ø‹Ø‹‹ØØØØØ‹‹ØØ‹ØØØØ
+Ø‹‹Ø‹‹‹ØØØØØØØØØ‹‹ØØØ‹‹‹‹ØØ‹ØØØØ
+ØØ‹‹‹ØØØØØØØØØ‹‹Ø‹‹ØØ‹‹Ø‹ØØØØØØØ
+ØØØ‹‹‹‹‹‹‹‹‹‹‹‹ØØØ‹ØØ‹ØØ‹‹ØØØ‹ØØ
+ØØØØ‹ØØØØ‹‹Ø‹ØØØØØØØ‹‹ØØØ‹‹ØØ‹‹Ø
+ØØØ‹‹ØØØØØ‹‹‹ØØØØØØØ‹ØØØØØ‹‹‹‹‹Ø
+ØØ‹ØØØØØ‹‹‹ØØØØ‹ØØ‹‹‹ØØØØØ‹‹ØØ‹Ø
+ØØØØØØØØ‹Ø‹‹ØØ‹‹‹ØØØØØØØ‹‹ØØØ‹ØØ
+ØØØ‹‹ØØØ‹ØØ‹‹Ø‹Ø‹‹‹‹‹ØØ‹‹‹ØØØ‹‹Ø
+ØØ‹‹‹ØØØ‹ØØØ‹‹‹ØØØØØ‹Ø‹‹Ø‹ØØØØØ‹
+‹‹‹ØØØØ‹‹ØØØØ‹‹ØØØØØ‹‹‹ØØ‹ØØØØØØ
+‹ØØØØØ‹‹ØØØØØ‹‹ØØØØØØØØØØ‹ØØØØØØ
+ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ
diff --git a/pixel-client/assets/textures/interact_target_thick.ta b/pixel-client/assets/textures/interact_target_thick.ta
new file mode 100644
index 00000000..3ece0dfa
--- /dev/null
+++ b/pixel-client/assets/textures/interact_target_thick.ta
@@ -0,0 +1,24 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aa aa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/pixel-client/assets/textures/interact_target_thin.ta b/pixel-client/assets/textures/interact_target_thin.ta
new file mode 100644
index 00000000..b0cbc90d
--- /dev/null
+++ b/pixel-client/assets/textures/interact_target_thin.ta
@@ -0,0 +1,24 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+a a
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/pixel-client/assets/textures/leek.ta b/pixel-client/assets/textures/leek.ta
new file mode 100644
index 00000000..d77c9c15
--- /dev/null
+++ b/pixel-client/assets/textures/leek.ta
@@ -0,0 +1,18 @@
+ ΩΩßß
+ ΩßΩΩß
+ ΩΩΩΩßß
+ ΩΩΩΩßß
+ ΩΩΩΩßß
+ ŁΩΩΩß ßß
+ ŁŁŁΩΩΩΩΩΩΩΩ
+ ŁŁŁŁßßßßßΩΩ
+ ŁŁŁŁÖ
+ ŁŁŁŁÖ
+ ŁŁŁŁÖ
+ cŁŁŁÖ
+ ccŁÖÖ
+ ccccÖ
+ ccccc
+OcccO
+QcOO
+OQPQ
diff --git a/pixel-client/assets/textures/leek_in_pot.ta b/pixel-client/assets/textures/leek_in_pot.ta
new file mode 100644
index 00000000..301222f0
--- /dev/null
+++ b/pixel-client/assets/textures/leek_in_pot.ta
@@ -0,0 +1,10 @@
+ ΩΩßß
+ ΩßΩΩß
+ ΩΩΩΩßß
+ ΩΩΩΩßß
+ ΩΩΩΩßß
+ ŁΩΩΩß ßß
+ ŁŁŁΩΩΩΩΩΩΩΩ
+ ŁŁŁŁßßßßßΩΩ
+ ŁŁŁŁÖ
+ŁŁŁŁÖ
diff --git a/pixel-client/assets/textures/milk_foodprocessor.ta b/pixel-client/assets/textures/milk_foodprocessor.ta
new file mode 100644
index 00000000..4697ffd7
--- /dev/null
+++ b/pixel-client/assets/textures/milk_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]]]]]]]h[[h
+[]]hebbbbbbeh]]h
+[]]heebbbbeeh]]h
+]]]heeeeeeeeh]]h
+]]]heeeeeeeehhh]
+]]]heeeeeeeeh]]]
+]]]heeeeeeeeh]]]
+]]]heeeeeeeeh]]]
+]]]]heeeeeeh]]]]
+]]]]]heeeeh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/milk_strawberry_foodprocessor.ta b/pixel-client/assets/textures/milk_strawberry_foodprocessor.ta
new file mode 100644
index 00000000..b978a59c
--- /dev/null
+++ b/pixel-client/assets/textures/milk_strawberry_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°Ø°°h
+ h°°°°ÖØÄ°h
+ hh°°°°°Øhh
+ h°hłłŁŁh›h
+ h°°hhhhßłh
+ h°°°CVBŁßhhh
+[[[h]]CCBB›Łh[[h
+[]]hebCVBCß/h]]h
+[]]heebBCVCeh]]h
+]]]heeeeeeeeh]]h
+]]]heeeeeeeehhh]
+]]]heeeeeeeeh]]]
+]]]heeeeeeeeh]]]
+]]]heeeeeeeeh]]]
+]]]]heeeeeeh]]]]
+]]]]]heeeeh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/nigiri_rice.ta b/pixel-client/assets/textures/nigiri_rice.ta
new file mode 100644
index 00000000..5613626d
--- /dev/null
+++ b/pixel-client/assets/textures/nigiri_rice.ta
@@ -0,0 +1,15 @@
+ ))
+ )))
+ E))
+ )))E
+ )))))))
+ )))))E))))
+ )))))))))))E))
+ )))E))))E)))))
+ ))))))))))))))
+ ))))))))))))E)
+ )))))))))))E)))
+E)E))))E))E)))))
+)E))E)))))))))
+ )))))))E)))
+ E))))))
diff --git a/pixel-client/assets/textures/oven.ta b/pixel-client/assets/textures/oven.ta
new file mode 100644
index 00000000..96e3d2a0
--- /dev/null
+++ b/pixel-client/assets/textures/oven.ta
@@ -0,0 +1,40 @@
+MM////MM///MMMMMMMMMMMMMMM//////
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM/
+///MMMMMMMMMMMMMMMMMMMMMMMMM////
+////////////////////////////////
+/555555555555555555555555555555/
+/555555555555555555555555555555/
+/555555555555555555555555555555/
+/5555555555555555555555555555555
+55555555555555555555555555555555
+55555555555555555555555555555555
+55555555555555555555555555555555
+55555555555555555555555555555555
+5555555555555555555555555555555/
+/555555555555555555555555555555/
+5555555555555555555555555555555/
+55555555555555555555555555555555
+55555555555555555555555555555555
+/555555555555555555555555555555/
+////////////////////////////////
diff --git a/pixel-client/assets/textures/particle.ta b/pixel-client/assets/textures/particle.ta
new file mode 100644
index 00000000..0ad4d2e5
--- /dev/null
+++ b/pixel-client/assets/textures/particle.ta
@@ -0,0 +1,2 @@
+cc
+c
diff --git a/pixel-client/assets/textures/path.ta b/pixel-client/assets/textures/path.ta
new file mode 100644
index 00000000..30f94645
--- /dev/null
+++ b/pixel-client/assets/textures/path.ta
@@ -0,0 +1,24 @@
+QPPPPPPPPPPPPPPPHHPPPPPQQPPPPPPP
+QQPPHPQQHPPPPPPHQQQQQQQPHPPPPQPP
+QQHHHPHPHHHHHHQPPHHPPQPPHQQPHHPH
+QPPHHPHHPHHPPPQQQPPPHHQPQQPPQPHP
+QHHHPHPHHHPPQQHQPPPPHHQPPHPQPPPH
+PPQHQHPPQQHHPPPQQPPHHHQPPHQQQPPP
+PPHPPHPPQQHHPPPQPHHQQHPPPHHHPPPP
+HHHPPHPPHQQQPPQHPPPPQHHQQHHHHPQQ
+HPPPHPHQQQPQQPHHPPHHQQQQQQQQQQQP
+QPHQQPPHQPHHHQPPPHHHPPPHQQHHQHPQ
+QPQPHPPPHHPPPHHPHQQQPHPQPPPHQHQP
+QPQPQPHHHPHHPQHPHQPPHPPQPPHHQHQP
+PPPPQPHHPPPHHQQHHHPPHQPQPPPHQQPH
+PHHHHHPPPQHQPHHQHHPQQHHQPHPPQQPH
+HHQHHPPPQPHQPHHHQHPHPPHQHHHQQPPP
+PPHQHQQPQQQHPHQQQHHHHHHPQHPPQHPH
+PHHPPQQPPHPHQQQPQQPQHHHPPQHPHPHH
+PHPHHHPQHHPHQQQQQHQQQHQHHQHHPHHP
+PHPPHPHHQQHHQHHQQQPPHQQQHQQQHPPQ
+QHPHHHHHPPQQQQHPPQQQHHHQPQQHQPPQ
+PQHHHHPPQHQQHHHPQQPPHHQQQQHPQPHQ
+PQQQQQQQQPHHPPPHHQPPPQQHHPHPPPPQ
+PQQQHHQQQPHHHHHHPHPQHHHHHPPQPPQQ
+PPPHHPPQQQHPHPPPPQQQQQPPPHPPHPPQ
diff --git a/pixel-client/assets/textures/plate.ta b/pixel-client/assets/textures/plate.ta
new file mode 100644
index 00000000..15d66e0c
--- /dev/null
+++ b/pixel-client/assets/textures/plate.ta
@@ -0,0 +1,23 @@
+ ffffffffffff
+ fffjjjjjjjjfff
+ fffjjjjjjjjjjjjfff
+ fffjjjjjjjjjjjjjjjff
+ fffjjjffffffffffffjjff
+ fffjjfffffffffffffffjjff
+ ffjjfffffffffffffffffjjff
+ ffjfffffffffffffffffffjff
+ ffffffffffffffffffffffffff
+ fffffffffffffffffffffffffff
+ fffffffffffffffffffffffffff
+ fffffffffffffffffffffffffff
+ fffffffffffffffffffffffffff
+ fffffffffffffffffffffffffff
+ ffffffffffffffffffffffffff
+ fffffffffffffffffffffffjf
+ fjfffffffffffffffffffffj
+ jjfffffffffffffffffffj
+ jjfffffffffffffffffj
+ jjffffffffffffffjj
+ jjjffffffffffjjj
+ jjjjjjjjjjjj
+ jjjjjj
diff --git a/pixel-client/assets/textures/plate_dirty.ta b/pixel-client/assets/textures/plate_dirty.ta
new file mode 100644
index 00000000..50781b21
--- /dev/null
+++ b/pixel-client/assets/textures/plate_dirty.ta
@@ -0,0 +1,23 @@
+ ffffffffffff
+ fffjjjjjjjjfff
+ fffjjjjjjjjjjjjfff
+ fffjjjjjjjjjjjjjjjff
+ fffjjjHHffffffffffjjff
+ fffjjfHHfJHffIffHHffjjff
+ ffjjfHHHHHffffxxIHHffjjff
+ ffjffxxHHHHxffHHxHffxfjff
+ffffffHxHHHHHHfffHHHffffff
+fffffffHHHIHHffffJfffffffff
+fffffxfHHfffxfffJfJHHfxffff
+ffffIfHHJffffxffHHfHHHfffff
+fffffIHHJffffffxHHffHffffff
+fffffHHHHfIfHHHHHHHHJHfffff
+fffffHHxfffIIHHHHHHHJfffff
+ ffffffHffffHHHHxfHJJfffjf
+ fjfffHHfffxfffHHHffffffj
+ jjfffffJffffIfHHfffffj
+ jjffffffffIfHHfffffj
+ jjffffffffffffffjj
+ jjjffffffffffjjj
+ jjjjjjjjjjjj
+ jjjjjj
diff --git a/pixel-client/assets/textures/player.ta b/pixel-client/assets/textures/player.ta
new file mode 100644
index 00000000..065a3255
--- /dev/null
+++ b/pixel-client/assets/textures/player.ta
@@ -0,0 +1,38 @@
+ eeeeeecccee
+ ececcccceaee
+ ecaeeeeccaae
+ eaaaaaaacaae
+ eacaaacaaace
+ eacacacaaace
+ eaceeeeeeeee
+ eeeevvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvvv
+ vvvvvvvvvvv
+ Rvvvvvvvvvv
+ RvvvvvvvvvR
+ RvvvvvvvR
+ RRvvvRR
+ wwwwRRwww
+ wwwwwwwvvvv
+ wwwwvvvvvvvv
+ vvwvvvvvvvvvv
+ vvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvv
+ vvvvvvvvvvvvvvvvvvvvvvvvvv
+ wvvvvvvvvvvvvvvvvvvvvvvvvw
+ wwvvvvvvvvvvvvvvvvvvvvvvww
+ wwwvvvvvvvvvvvvvvvvvvvwww
+ wwwwwvvvvvvvvvvvvvvvwwww
+ wwwwwwwvvvvvvvvvvwwwww
+ wwwwwwwwwwwwwwwwwwww
+ wwwwwwwwwwwwwwww
+ wwwwwwwwwwwwww
+ wwwwwwwwwwww
diff --git a/pixel-client/assets/textures/pot_back.ta b/pixel-client/assets/textures/pot_back.ta
new file mode 100644
index 00000000..85456a40
--- /dev/null
+++ b/pixel-client/assets/textures/pot_back.ta
@@ -0,0 +1,20 @@
+ jjjjjj
+ jjjmmmmmmjjj
+ jmmmmmmmmmmmmj
+ jmmmmmmmmmmmmmmj
+ mmmmmmmmmmmmmmmm
+ mmmmmmmmmmmmmmm
+ mmmmmmmmmmmmm
+ mmmmmm
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/pot_front.ta b/pixel-client/assets/textures/pot_front.ta
new file mode 100644
index 00000000..ccfdf15e
--- /dev/null
+++ b/pixel-client/assets/textures/pot_front.ta
@@ -0,0 +1,20 @@
+
+
+
+
+ j j
+ jj jj
+mmjjj jjjmm
+m mjjjjj jjjhjj j
+mmmjjjjjjjjjjjjjhhjjjj
+ mjjjjjjjjjjjhjhhjj
+ mmjjjjjjjjjjhjhhjj
+ mmmjjjjjjjjjhjhhjj
+ mmmmjjjjjjjjhjhjjm
+ mmmmmmjjjjjjhjhjjm
+ mmmmmmjjjjjhjjmmm
+ mmmmmmmjjjjjjmmm
+ mmmmmmmmmmmmmmm
+ mmmmmmmmmmmmm
+ mmmmmmmmm
+ mmmmm
diff --git a/pixel-client/assets/textures/rice.ta b/pixel-client/assets/textures/rice.ta
new file mode 100644
index 00000000..8b2e6c14
--- /dev/null
+++ b/pixel-client/assets/textures/rice.ta
@@ -0,0 +1,22 @@
+ KKKEEPE)E
+ IKKEEEEEEEEEKKKK
+ IKEEEPEE)E)EEEPEKI
+ IKEEPEEEEEEEPEEEEKI
+ IIIE)EEPEPEEEE)EEII
+ IIIKKKKKEEE)EEIIIII
+ KIIKKKKKKKKIIIIIIII
+ KIIKKKKKKKIIIIIII
+ KKIKKKKKKKIIIIK
+ IKKKKKKKKKKKKK
+ IIKKKKKKKKKKKI
+ IIIKKKKKKKIIIIII
+ IIIKKKKKKKKIIIIII
+ IIKKKKKKKKKIIIIIIK
+ IKEKE)EKKKKKIIIIIKK
+ EEEEEEEEEKKKIIIIIIII
+ EP)EEEPEEPEKKKKIIIIII
+EPEEPEEEEEEEEKKKKKK
+ EEEEEEEPEEEEKKK
+) PEEEEEE)
+ E E
+ P
diff --git a/pixel-client/assets/textures/rice_cooked_in_pot.ta b/pixel-client/assets/textures/rice_cooked_in_pot.ta
new file mode 100644
index 00000000..56b32a2b
--- /dev/null
+++ b/pixel-client/assets/textures/rice_cooked_in_pot.ta
@@ -0,0 +1,6 @@
+ aaEaEa
+ aaaaaaaaa
+aaaEaaEaEaaaEa
+ EaaaaaaaEaaaa
+ aaEaEaaaaEaa
+ aaaEaa
diff --git a/pixel-client/assets/textures/rice_flour.ta b/pixel-client/assets/textures/rice_flour.ta
new file mode 100644
index 00000000..82ab2133
--- /dev/null
+++ b/pixel-client/assets/textures/rice_flour.ta
@@ -0,0 +1,5 @@
+ )E))))))
+ ))))))E))))
+)E))E)))))E))E
+ ))))))))))))
+ )E)))E))
diff --git a/pixel-client/assets/textures/rice_flour_foodprocessor.ta b/pixel-client/assets/textures/rice_flour_foodprocessor.ta
new file mode 100644
index 00000000..06017d8c
--- /dev/null
+++ b/pixel-client/assets/textures/rice_flour_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]]]]]))h[[h
+[]]h]]]]]))Eh]]h
+[]]hE]mm))))h]]h
+]]]h))))))))h]]h
+]]]h)E)))E))hhh]
+]]]h))))))))h]]]
+]]]h))E)))))h]]]
+]]]h)))E))E)h]]]
+]]]]h))))))h]]]]
+]]]]]hE)))h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/rice_foodprocessor.ta b/pixel-client/assets/textures/rice_foodprocessor.ta
new file mode 100644
index 00000000..58d79651
--- /dev/null
+++ b/pixel-client/assets/textures/rice_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[hE]]]])P]h[[h
+[]]h]])EE]]]h]]h
+[]]hP]EEPmE]h]]h
+]]]h]EEEEE)Eh]]h
+]]]hE)EPEErmhhh]
+]]]hEEEEE)EEh]]]
+]]]hEPEEEEE)h]]]
+]]]hEE)EEEEEh]]]
+]]]]hEEPEEPh]]]]
+]]]]]hEEE)h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/rice_in_pot.ta b/pixel-client/assets/textures/rice_in_pot.ta
new file mode 100644
index 00000000..e9f3221c
--- /dev/null
+++ b/pixel-client/assets/textures/rice_in_pot.ta
@@ -0,0 +1,6 @@
+ EEPE)E
+ EEEEEEEEE
+EEEPEE)E)EEEPE
+ PEEEEEEEPEEEE
+ EEPEPEEEE)EE
+ EEE)EE
diff --git a/pixel-client/assets/textures/sink.ta b/pixel-client/assets/textures/sink.ta
new file mode 100644
index 00000000..e76c2af7
--- /dev/null
+++ b/pixel-client/assets/textures/sink.ta
@@ -0,0 +1,36 @@
+
+
+ jjjjj jjjjj
+ jjj ljjl jjj
+ lll ljjl lll
+ ljjl
+ hhhhhhhhhhhhhjjhhhhhhhhhhhhh
+ hhhhhhhhhhhhhjjhhhhhhhhhhhhh
+ hhmmmmmmmmmmmjjmmmmmmmmmmmhh
+ hhmmmmmmmmmmmjjmmmmmmmmmmmhh
+ hhmmmmmmmmmmmmmmmmmmmmmmmmhh
+ hhmmhhhhhhhhhhhhhhhhhhhhmmhh
+ hhmmhhhhhhhhhhhhhhhhhhhhhmhh
+ hhmhhhhhhhhhhmmhhhhhhhhhhmhh
+ hhmhhhhhhhhhmmmmhhhhhhhhhmhh
+ hhmhhhhhhhhhmmmmhhhhhhhhhmhh
+ hhmhhhhhhhhhhmmhhhhhhhhhhmhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhmmmmmmmmmmmmmmmmmmmmhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/solid.ta b/pixel-client/assets/textures/solid.ta
new file mode 100644
index 00000000..78981922
--- /dev/null
+++ b/pixel-client/assets/textures/solid.ta
@@ -0,0 +1 @@
+a
diff --git a/pixel-client/assets/textures/steak.ta b/pixel-client/assets/textures/steak.ta
new file mode 100644
index 00000000..23f31da7
--- /dev/null
+++ b/pixel-client/assets/textures/steak.ta
@@ -0,0 +1,20 @@
+ LLLLL
+ KKKKKKKLLK
+ KKKxKKKKKKLLK
+ KKKKxLKKxKKKNLL
+ LLxKKKxLLLLLxKKNxNK
+ LLLxxxNKKLLLLLKKKxKK
+ LLxNNNLKLLKKxLKKKxKK
+ LLLxLLLKKLLKxLLLxxK
+ LLLxLLLLKLLKxLLNxxK
+ LxLLKKLLLKLKKxNNxK
+ xxLLxKKKLLLLKKxxxK
+ NNLLLLxKLLNNxxxxx
+ NxLKLLLKKKLxxxxxxx
+ NLLLKKLxKKKKxxxxxx
+ LLLLLLKKxKKKKxKxxxx
+NLLLLKKKKKKxKxxxxxxxxx
+NNKKKxxxxxxxxxLxx5xx
+xxxxxxxxxxxxxxxxLxxL
+xxxxxxxxxKxxxLx5xx5
+ Kxxxxx5xLx
diff --git a/pixel-client/assets/textures/steak_in_pot.ta b/pixel-client/assets/textures/steak_in_pot.ta
new file mode 100644
index 00000000..4aec1c5a
--- /dev/null
+++ b/pixel-client/assets/textures/steak_in_pot.ta
@@ -0,0 +1,9 @@
+ LLLLL
+ KKKKKKKL
+ KKKxKKKKKK
+ KKKKxLKKxKKK
+LxKKKxLLLLLxKK
+LLxxxNKKLLLLLK
+LxNNNLKLLKKxL
+LLxLLLKKLLKx
+ LLLLKL
diff --git a/pixel-client/assets/textures/steak_raw.ta b/pixel-client/assets/textures/steak_raw.ta
new file mode 100644
index 00000000..a0bfb0da
--- /dev/null
+++ b/pixel-client/assets/textures/steak_raw.ta
@@ -0,0 +1,20 @@
+ BBBBB
+ &&&&&&&BB&
+ &&&Y&&&&&&BB&
+ &&&&YB&&Y&&&/BB
+ BBY&&&YBBBBBY&&/Y/&
+ BBBYYY/&&BBBBB&&&Y&&
+ BBY///B&BB&&YB&&&Y&&
+ BBBYBBB&&BB&YBBBYY&
+ BBBYBBBB&BB&YBB/YY&
+ BYBB&&BBB&B&&Y//Y&
+ YYBBY&&&BBBB&&YYY&
+ //BBBBY&BB//YYYYY
+ /YB&BBB&&&BYYYYYYY
+ /BBB&&BY&&&&YYYYYY
+ BBBBBB&&Y&&&&Y&YYYY
+/BBBB&&&&&&Y&YYYYYYYYY
+//&&&YYYYYYYYY/YYBYY
+YYYYYYYYYYYYYYYY/YY&
+YYYYYYYYY&YYY/YBYYB
+ &YYYYYBY/Y
diff --git a/pixel-client/assets/textures/steak_raw_in_pot.ta b/pixel-client/assets/textures/steak_raw_in_pot.ta
new file mode 100644
index 00000000..2eb5c53b
--- /dev/null
+++ b/pixel-client/assets/textures/steak_raw_in_pot.ta
@@ -0,0 +1,9 @@
+ BBBB
+ &&&&&&&
+ &&&Y&&&&&
+ &&&&YB&&Y&&
+BBY&&&YBBBBBY&
+BBBYYY/&&BBBBB
+BBY///B&BB&&Y
+BBBYBBB&&BB&
+ YBBBB&
diff --git a/pixel-client/assets/textures/stove.ta b/pixel-client/assets/textures/stove.ta
new file mode 100644
index 00000000..f5010163
--- /dev/null
+++ b/pixel-client/assets/textures/stove.ta
@@ -0,0 +1,36 @@
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ hhhhhhhhhhmmmmmmmmmhhhhhhhhhhh
+ hhhhhhhhmmjjjjjjjjjmmhhhhhhhhh
+ hhhhhhhhmjmmmmmmmmmjjmhhhhhhhh
+ hhhhhhhmjmjjjjjjjjjmmjmhhhhhhh
+ hhhhhhhmjmjmmmmmmmmjmjmhhhhhhh
+ hhhhhhmjmjmjjjjjjjjmjmjmhhhhhh
+ hhhhhhmjmmjmjmmmmmjmjmjmhhhhhh
+ hhhhhhhmjmjmmjjjjjmmjmjmhhhhhh
+ hhhhhhhmjmmjjmmmmjjjmjmhhhhhhh
+ hhhhhhhhmjjmmjjjjmmmjjmhhhhhhh
+ hhhhhhhhhmmjjmmmmjjjmmhhhhhhhh
+ hhhhhhhhhhhmmjjjjmmmhhhhhhhhhh
+ hjjjjhhhhhhhhmmmmhhhhhhhhjjjjh
+ hjjjjhhhhhhhhhhhhhhhhhhhhjjjjh
+ hjjjjhhhhhhhhhhhhhhhhhhhhjjjjh
+ hmmmmhhhhhhhhhhhhhhhhhhhhmmmmh
+ hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+ mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pixel-client/assets/textures/strawberry.ta b/pixel-client/assets/textures/strawberry.ta
new file mode 100644
index 00000000..8c3e0282
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry.ta
@@ -0,0 +1,23 @@
+ Ø›ßŁŁ
+ łłCCCC
+ Ø CłVCBC
+ CCCCVBC
+ Ø› ØØ/ØØCBBC
+ ØłłŁŁŁ›łØłłCBC
+ CCłßłŁ /VCCC
+ CCBVBBߣØ//CCC
+ CBBBBCCߨ//CV
+ CBVBBCC/ Ø /CC
+ C BBBBCVC/ Ø /
+ CC BBCCCC//
+ CCB //VC///// ØØŁ
+ CCVBB /////// ßłłCC
+ CCCBBC////// ŁßCCBBBC
+ CCCCBV/// ›CVCBBBBCC
+ C//CCCC ›ØłCCCBBBVBC
+ //VC/C Øł///CVCBBBC
+ /////C //V/CCCBBC
+ ›///ß/ /////CCVBC
+ ›łß ///////C
+ØłłłØØß
+ łł
diff --git a/pixel-client/assets/textures/strawberry_foodprocessor.ta b/pixel-client/assets/textures/strawberry_foodprocessor.ta
new file mode 100644
index 00000000..419b0b68
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h h
+ h h
+ h h
+ hh Ø hh
+ h h h h
+ h hhhhØŁh
+ h ØłłŁŁŁ›hhh
+[[[h]]]]Cłßłh[[h
+[]]h]]]CVBŁßh]]h
+[]]h]]CCBB›Łh]]h
+]]]h]mCVBCß/h]]h
+]]]hmCBBCVC›hhh]
+]]]hBBCCCC//h]]]
+]]]h/VCCC/V/h]]]
+]]]h//CCC///h]]]
+]]]]h//V///h]]]]
+]]]]]h////h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/strawberry_icecream.ta b/pixel-client/assets/textures/strawberry_icecream.ta
new file mode 100644
index 00000000..d80366c3
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_icecream.ta
@@ -0,0 +1,14 @@
+ §§§§§§§
+ §§YYY§§§§§§
+ §YY§§§§§§§§§
+ §§Y§§§§§§§§§§
+ §Y§§§§§§§§§§Z
+ §Y§§§§§§§§§§ZZ
+ §§§§§§§§§§§§§ZZ
+ §§§§§§§§§§§§§ZZZ
+§§§§§§§§§§§§§ZZZZZ
+ Z§§§§§§§§ZZZZZZZ
+ ZZ§§§ZZZZZZZ
+ ZZZZZZZZZZZZZ
+ ZZZZZZZZZZZZ
+ ZZZ ZZZ
diff --git a/pixel-client/assets/textures/strawberry_icecream_foodprocessor.ta b/pixel-client/assets/textures/strawberry_icecream_foodprocessor.ta
new file mode 100644
index 00000000..af545930
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_icecream_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]]]]]]]h[[h
+[]]h]]§§§§]]h]]h
+[]]h]§Y§§§§]h]]h
+]]]h§Y§§§§§§h]]h
+]]]hY§Y§§§§§hhh]
+]]]h§§§§§§§Zh]]]
+]]]h§§§§§§ZZh]]]
+]]]h§§§§§ZZZh]]]
+]]]]hZZZZZZh]]]]
+]]]]]hZZZZh]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/strawberry_puree_foodprocessor.ta b/pixel-client/assets/textures/strawberry_puree_foodprocessor.ta
new file mode 100644
index 00000000..8be6eb23
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_puree_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]BBBB]]h[[h
+[]]hBBBBBBBBh]]h
+[]]h2BBBBBB2h]]h
+]]]h22222222h]]h
+]]]h22222222hhh]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]]h222222h]]]]
+]]]]]h2222h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/strawberry_shake_foodprocessor.ta b/pixel-client/assets/textures/strawberry_shake_foodprocessor.ta
new file mode 100644
index 00000000..bea21e2c
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_shake_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°°°°°hhh
+[[[h]]]]]]]]h[[h
+[]]h2""""""2h]]h
+[]]h22""""22h]]h
+]]]h22222222h]]h
+]]]h22222222hhh]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]h22222222h]]]
+]]]]h222222h]]]]
+]]]]]h2222h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/strawberry_shake_glass.ta b/pixel-client/assets/textures/strawberry_shake_glass.ta
new file mode 100644
index 00000000..51e32705
--- /dev/null
+++ b/pixel-client/assets/textures/strawberry_shake_glass.ta
@@ -0,0 +1,19 @@
+ a°°°°°°°°a
+ a°°°°°°°°°°a
+a°°°°°°°°°°°°a
+aa°°°°°°°°°°aa
+a°a°°°°°°°°a°a
+a°°aaaaaaaa°°a
+a°°°""""""°°°a
+a°"""""""""a°a
+a22"""""""a22a
+a222222222a22a
+a222222222a22a
+a2222222a2a22a
+a2222222a2a22a
+a2222222a2222a
+a2222222a2222a
+a2222222a2222a
+a222222a22222a
+ a2222a22222a
+ aaaaaaaaaa
diff --git a/pixel-client/assets/textures/table.ta b/pixel-client/assets/textures/table.ta
new file mode 100644
index 00000000..ea05c05e
--- /dev/null
+++ b/pixel-client/assets/textures/table.ta
@@ -0,0 +1,36 @@
+ KKKKKJJJ
+ KKKJJJJJJJJJJ
+ KKJJJJJJJJJJJJJJJ
+ KKJJJJJJJJJJJJJJJJJJJ
+ KKJJJJJJJJJJJJJJJJJJJJJ
+ KJJJJJJJJJJJJJJJJJJJJJJJJ
+ KJJJJJJJJJJJJJJJJJJJJJJJJJJ
+ KJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+ JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+ JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+KJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+LJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJL
+LKJJJJJJJJJJJJJJJJJJJJJJJJJJJJKL
+ KJJJJJJJJJJJJJJJJJJJJJJJJJJJKL
+ LKJJJJJJJJJJJJJJJJJJJJJJJJJKLL
+ LLKJJJJJJJJJJJJJJJJJJJJJJJKLL
+ LLKJJJJJJJJJJJJJJJJJJJJJKLL
+ LLJJJJJJJJJJJJJJJJJJJJKLL
+ LLLJJJJJJJJJJJJJJKKKLLL
+ LLLLJJJJJJJJJKKKKLLLL
+ jLLLLLJJJJKKKLLLLLmm
+ mjjjjLLLLLLLLLLLLLjjjmmm
+ mmjjjjjjjLLLLLLLjjjjjjjmmm
+ mmjjjjjjjjjLLLLjjjjjjjjmmmm
+ mmmjjjjjjjjjLLLLjjjjjjjjmmmm
+ mmmmjjjjjjjjLLLLjjjjjjjmmmmmm
+ mmmjjjjjjjjjjjjjjjjjjjmmmmm
+ mmmmjjjjjjjjjjjjjjjjjmmmmm
+ mmmjjjjjjjjjjjjjjjjjmmmm
+ mjjjjjjjjjjjjjjjjmmm
+ mmmmjjjjjjjjjmmmmm
+ mmmmmmmmmmmmmm
+ mmmmm
diff --git a/pixel-client/assets/textures/tomato.ta b/pixel-client/assets/textures/tomato.ta
new file mode 100644
index 00000000..b6f087d9
--- /dev/null
+++ b/pixel-client/assets/textures/tomato.ta
@@ -0,0 +1,17 @@
+ßßÖÄ
+ßßßßß
+ ۧ ۅ
+ z€ßÄ€z
+ zÖz€¡ß€yzA
+ zzÄ€€€€€yAAA
+zzAyy€AA€AAAAA
+zAAxx€yyy€Azzz
+zAAxxy€xAAzzzzy
+AAAAxyxyAAzzAAy
+zzAAAAAAAAzzAAy
+yzzAAAAAAAzzAy
+yyzzAAAAAAyAAy
+ yyzzAAAAyyAy
+ yyzzAyyyyy
+ yyyyyyyy
+ yyy
diff --git a/pixel-client/assets/textures/tomato_foodprocessor.ta b/pixel-client/assets/textures/tomato_foodprocessor.ta
new file mode 100644
index 00000000..8b2719de
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h°°°°Ω°°°hhh
+[[[hΩ]ßΩΩ]]]h[[h
+[]]h¿Ω€AAzz]h]]h
+[]]h€ß€AVVzzh]]h
+]]]hΩß¡AAVVzh]]h
+]]]hA€AAAAVzhhh]
+]]]h//zAAVVzh]]]
+]]]h//zzAVAAh]]]
+]]]h////zAAAh]]]
+]]]]h//////h]]]]
+]]]]]h////h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/tomato_juice_foodprocessor.ta b/pixel-client/assets/textures/tomato_juice_foodprocessor.ta
new file mode 100644
index 00000000..9c0313f8
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_juice_foodprocessor.ta
@@ -0,0 +1,26 @@
+ hhhh
+ h°°°°h
+ h°°°°°°h
+ h°°°°°°°°h
+ hh°°°°°°hh
+ h°h°°°°h°h
+ h°°hhhh°°h
+ h/AAAAAA/hhh
+[[[h//AAAA//h[[h
+[]]h////////h]]h
+[]]h////////h]]h
+]]]h////////h]]h
+]]]h////////hhh]
+]]]h////////h]]]
+]]]h////////h]]]
+]]]h////////h]]]
+]]]]h//////h]]]]
+]]]]]h////h]]]]]
+[]]]]]hhhh]]]]][
+[]]]]]]]]]]]]]][
+[[[]]]]]]]]]][[[
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{
diff --git a/pixel-client/assets/textures/tomato_juice_in_pot.ta b/pixel-client/assets/textures/tomato_juice_in_pot.ta
new file mode 100644
index 00000000..c8276921
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_juice_in_pot.ta
@@ -0,0 +1,12 @@
+ zzzzzzzz
+ zzzzzzzzzzzz
+ zzzzzzzzzzzzzzz
+ zzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzz
+ zzzzzzzzzzzzzz
+ zzzzzzzzzzz
diff --git a/pixel-client/assets/textures/tomato_slice.ta b/pixel-client/assets/textures/tomato_slice.ta
new file mode 100644
index 00000000..77d257f8
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_slice.ta
@@ -0,0 +1,14 @@
+ AAAJ
+ AAzzAAJHAAAA
+AA///zA/HAAAAAAJ
+A//x//AHHA////AA
+A/////zÆHA/x//AA
+A/////zzÆA/////A
+AA///zAzzA//x//A
+ Ax/zAAzz/////AA
+ A//zA/zz////zA
+ A//A//zz/x/zz
+ A/A//z///zzz
+ AAA///AAAzz
+ AAA//zzzz
+ Azzz
diff --git a/pixel-client/assets/textures/tomato_soup.ta b/pixel-client/assets/textures/tomato_soup.ta
new file mode 100644
index 00000000..36be679e
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_soup.ta
@@ -0,0 +1,18 @@
+ AAAAAAAA
+ AAAAAAAAAAAA
+ AAAA«AAAAßAAAAA
+ AAAAAAAAAAAAAAAAA
+ A«AAAAAΩAAAAAAAA«AA
+AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAΩAAAAA
+AAAΩAAAAßAAAAAAAAAAAA
+AAAAAAAAAAAA«AAAAAAAA
+AAAAAAAAAAAAAAAAAAßAA
+AAAAAAAAAAAAAAAAAAAA
+AA«AAAAAAAAAßAAAAAAA
+AAAAAAAΩAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAA
+ AAAAAAAAA«AAAAAA
+ AAAAAAAAAAAAA
+ AAAAAAAAAA
diff --git a/pixel-client/assets/textures/tomato_soup_in_pot.ta b/pixel-client/assets/textures/tomato_soup_in_pot.ta
new file mode 100644
index 00000000..da39044d
--- /dev/null
+++ b/pixel-client/assets/textures/tomato_soup_in_pot.ta
@@ -0,0 +1,16 @@
+ AAAAAAAA
+ AA«AAAAßAAAA
+ AAAAAAAAAAAAAAA
+«AAAAAΩAAAAAAAA«AA
+AAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAΩAAAA
+AΩAAAAßAAAAAAAAAAA
+AAAAAAAAAA«AAAAAAA
+AAAAAAAAAAAAAAAAßA
+AAAAAAAAAAAAAAAAAA
+«AAAAAAAAAßAAAAAAA
+AAAAAΩAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAA
+ AAAAAAA«AAAAAAA
+ AAAAAAAAAAAAAA
diff --git a/pixel-client/assets/textures/trash.ta b/pixel-client/assets/textures/trash.ta
new file mode 100644
index 00000000..41d05300
--- /dev/null
+++ b/pixel-client/assets/textures/trash.ta
@@ -0,0 +1,36 @@
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡ÖÖ¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+Ö¡¡¡¡¡¡Ö¡¡¡¡¡¡¡Ö¡¡¡¡¡¡¡¡Ö¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
+ÖßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÖ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
+ÖßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÖ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
+Ö¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Ö
+ÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖÖ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
+ÖßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÖ
diff --git a/pixel-client/assets/textures/tree.ta b/pixel-client/assets/textures/tree.ta
new file mode 100644
index 00000000..2d5bee16
--- /dev/null
+++ b/pixel-client/assets/textures/tree.ta
@@ -0,0 +1,72 @@
+
+
+ ΩΩΩΩΩΩ
+ ΩΩΩΩΩΩΩΩ‹‹‹‹‹‹ΩΩ
+ ΩØØØ‹‹‹‹‹‹‹‹‹‹‹‹Ω
+ ΩØØØØØØØØØ‹‹‹‹‹‹‹‹ΩΩΩ
+ Ω‹‹‹‹‹‹ØØØØØØØ‹‹‹‹‹‹‹‹ΩΩΩ
+ ΩØØØØØ‹‹ØØØ‹‹ØØØ‹‹‹‹‹‹‹‹‹ΩΩ
+ ΩØØØØ€ØØ‹‹ØØØ‹‹‹ØØØØØ‹‹‹‹‹‹‹Ω
+ ΩØØØØ€ΩΩ€‹ΩΩΩØØ‹ØØØØØØØ‹‹‹‹‹Ω
+ ΩØØΩΩ€€€Ω€ΩΩΩΩΩ‹ØØØØØØØØ‹‹‹‹Ω
+ ΩΩØΩΩΩ€€ΩΩΩΩΩΩΩΩ‹ΩΩØØØØØØØ‹‹‹Ω
+ ΩΩØΩΩΩΩ€€€ΩΩΩΩΩΩΩ€ΩΩΩØØØØØ‹‹‹Ω
+ €€ΩΩΩΩΩΩΩ€€Ω€ΩΩΩΩ€€ΩΩΩΩ€ØØØ‹Ω
+ €€ΩΩΩΩΩΩΩΩ€€€ΩΩΩΩΩ€€€€€€ØØØ‹Ω
+ €€€€€ΩΩΩΩΩΩΩΩΩΩΩØØ€€€€€€ΩØØ‹‹Ω
+ €€€€€€ΩΩØØΩΩΩØØØØØΩΩΩΩΩΩΩΩØØØΩ
+ €€€€€€ΩØØØΩΩΩØΩΩΩØØΩΩΩΩΩØ‹‹‹ØΩ
+ €€€€€€ΩΩΩØØΩΩΩΩΩΩΩØΩΩ€€Ω‹‹Ø‹ØΩ
+ €€€€€€ΩΩΩΩØØΩΩΩΩΩΩØΩ€€ΩΩΩΩØ‹‹‹Ω
+ €€€€€€€ΩΩΩΩØ€€€€ΩΩΩΩ€€ΩΩΩΩØØ‹‹Ω
+€€€€€€€€ΩΩΩØØ€€€€ΩΩΩΩΩ€€ΩΩØ€Ø€‹‹
+€€€€€€€€€€ØØ€€€€€€ΩΩΩΩΩ€€€€€€€‹‹
+€€€€€€€€€€€€€€€€€€ΩΩΩΩΩΩΩΩΩΩØØØ‹
+€€€€€€€€€€€€€€€€€€€ΩΩΩΩΩΩΩΩΩØØ‹‹
+€€€€€€€€€€€€€€€€€€€€€€€ΩΩΩΩ€ØØ‹‹
+ €€€€€€€€€€€€€€€€€€€€€€€€€€€ØØØ‹
+ €€€€€€€€€€€€€€€€€€€€€€€€€€€€ØØ
+ €€€€€€€€€€€€€€€€€€€€€€ €€€
+ €€€€€€€€€€€€€€€€€€€€ €€€
+ €€€€€€€€€€€€€€€€€€€
+ €€€€€€€XW€€€WX€€€€
+ €€€NXWWWWX€€€
+ NNXWWWWX
+ NNXWWWWXX
+ NNNXWWWWW
+ NNNXWWWWN
+ NNNNXWWWN
+ NNNNXWWNN
+ NNNNXWWWN
+ NNNNXWWWN
+ NNNNXWXWNN
+ NNNNXWXWWN‹
+ NNNNWWXWWNØ‹
+ ‹‹ NNWWWWXWNØØ
+ ‹‹‹ NNWWWWWWN‹Ø‹ ‹‹‹‹
+ ‹ØØ ‹‹ NNWXWWWWW‹‹‹‹‹‹‹‹‹
+ ‹‹ØØ ‹‹‹‹NNWXWWWWW‹ØØØØØ‹ØØ
+Ø‹‹ØØØ‹‹‹ØØØNNWXWWWWX‹‹‹‹‹‹‹‹Ø‹‹
+ØØØØØØØØ‹ØØØNNWXWWWWXØØ‹ØØØØ‹ØØØ
+Ø‹ØØØØØØ‹ØØØNNWXWWWWXØØNNØØ‹‹‹ØØ
+ØØ‹‹ØNNNNØØ‹NNWXWWWWN‹NN‹‹‹‹‹‹ØØ
+ØØ‹‹‹NNNNNØØNNWWWWWWNNNN‹ØØØØ‹‹Ø
+ØØØ‹‹ØØNNNNNNNWWWWWWWNNØ‹ØØØØØ‹Ø
+ØØØØ‹ØØNNNNNNWWXWWWWWNNØWWWØØ‹ØØ
+ØØØØ‹‹ØØNNNNNWXWWWXWWNNWWXXX‹ØØØ
+Ø‹NNNNNNNNWWWWWWWWXWWWNNNX‹‹Ø‹‹Ø
+ØNNNNNNNNNWWWWWWWWWXXXWWWØØ‹ØØ‹Ø
+ØØNNNNNNNNNWWNWWWWWWWNNWWWØ‹‹ØØØ
+ØØØØØNNNNNWWWWNWNNNWWNNNNWW‹ØØØØ
+Ø‹‹Ø‹NNNNNNNXWNNNNNWWNNNNWWXXØØØ
+ØØ‹‹‹ØNNNNNNXWNNNNNWWWWWNNWWXXØØ
+ØØØ‹‹NNN‹‹NXWWWWWNNWWWWWWXØØØ‹ØØ
+ØØØØNNNØØ‹XWWWØØWNNWWXXWWWXØØ‹‹Ø
+ØØØ‹‹ØØØØØXWWWØØWWNWWXØXWWW‹‹‹‹Ø
+ØØ‹ØØØØØ‹‹XWNØØ‹ØWNWWXØØXXXXØØ‹Ø
+ØØØØØØØØ‹ØXNØØ‹‹‹ØNWWXØØ‹‹ØØØ‹ØØ
+ØØØ‹‹ØØØ‹XX‹‹Ø‹ØNNNWWWX‹‹‹ØØØ‹‹Ø
+ØØ‹‹‹ØØØ‹XØØ‹‹‹ØNWWWXXW‹Ø‹ØØØØØ‹
+‹‹‹ØØØØ‹‹ØØØØ‹‹NWØØØ‹XXØØ‹ØØØØØØ
+‹ØØØØØ‹‹ØØØØØ‹‹ØØØØØØØXXØ‹ØØØØØØ
+ØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØØ
diff --git a/pixel-client/assets/textures/wall_ns.ta b/pixel-client/assets/textures/wall_ns.ta
new file mode 100644
index 00000000..c381c712
--- /dev/null
+++ b/pixel-client/assets/textures/wall_ns.ta
@@ -0,0 +1,47 @@
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccffffffccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_we.ta b/pixel-client/assets/textures/wall_we.ta
new file mode 100644
index 00000000..bc5aec79
--- /dev/null
+++ b/pixel-client/assets/textures/wall_we.ta
@@ -0,0 +1,42 @@
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_wen.ta b/pixel-client/assets/textures/wall_wen.ta
new file mode 100644
index 00000000..a53f4b99
--- /dev/null
+++ b/pixel-client/assets/textures/wall_wen.ta
@@ -0,0 +1,54 @@
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_wens.ta b/pixel-client/assets/textures/wall_wens.ta
new file mode 100644
index 00000000..54d6c397
--- /dev/null
+++ b/pixel-client/assets/textures/wall_wens.ta
@@ -0,0 +1,54 @@
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+fffffffffffffjjjjjjfffffffffffff
+cccccccccccccffffffccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_wes.ta b/pixel-client/assets/textures/wall_wes.ta
new file mode 100644
index 00000000..78232ee1
--- /dev/null
+++ b/pixel-client/assets/textures/wall_wes.ta
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+fffffffffffffjjjjjjfffffffffffff
+cccccccccccccffffffccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_wn.ta b/pixel-client/assets/textures/wall_wn.ta
new file mode 100644
index 00000000..274a6172
--- /dev/null
+++ b/pixel-client/assets/textures/wall_wn.ta
@@ -0,0 +1,54 @@
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+ccccccccccccccccccfccccccccccccc
+fffffffffffffffffffccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_wns.ta b/pixel-client/assets/textures/wall_wns.ta
new file mode 100644
index 00000000..de0134f2
--- /dev/null
+++ b/pixel-client/assets/textures/wall_wns.ta
@@ -0,0 +1,54 @@
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+ jjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+fffffffffffffjjjjjjccccccccccccc
+cccccccccccccffffffccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/wall_ws.ta b/pixel-client/assets/textures/wall_ws.ta
new file mode 100644
index 00000000..bbdd75cd
--- /dev/null
+++ b/pixel-client/assets/textures/wall_ws.ta
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjj
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+cccccccccccccjjjjjjccccccccccccc
+fffffffffffffjjjjjjccccccccccccc
+cccccccccccccffffffccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+cccccccccccccfjjjjfccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/textures/water_glass.ta b/pixel-client/assets/textures/water_glass.ta
new file mode 100644
index 00000000..fcdff0f2
--- /dev/null
+++ b/pixel-client/assets/textures/water_glass.ta
@@ -0,0 +1,19 @@
+ a°°°°°°°°a
+ a°°°°°°°°°°a
+a°°°°°°°°°°°°a
+aa°°°°°°°°°°aa
+a°a°°°°°°°°a°a
+a°°aaaaaaaa°°a
+a°°°]]]]]]°°°a
+a°]]]]]]]]]a°a
+a{{]]]]]]]a{{a
+a{{{{{{{{{a{{a
+a{{{{{{{{{a{{a
+a{{{{{{{a{a{{a
+a{{{{{{{a{a{{a
+a{{{{{{{a{{{{a
+a{{{{{{{a{{{{a
+a{{{{{{{a{{{{a
+a{{{{{{a{{{{{a
+ a{{{{a{{{{{a
+ aaaaaaaaaa
diff --git a/pixel-client/assets/textures/window.ta b/pixel-client/assets/textures/window.ta
new file mode 100644
index 00000000..9056295c
--- /dev/null
+++ b/pixel-client/assets/textures/window.ta
@@ -0,0 +1,42 @@
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+°°°°°°°°°°°°°°°°°°°°°°°°° °°°°°°
+°°°°°°°°° °°°°°°°°°° °° °°°°°°
+°°°°°°°°° °°°°°°°°° °° °°°°°°°
+°°°°°°° °°°°°°°°° °°° °°°°°°°°
+°°°°°°° °°°°°°°°° °°°°°°°°°°°°°
+°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+ffffffffffffffffffffffffffffffff
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
+cccccccccccccccccccccccccccccccc
diff --git a/pixel-client/assets/tiles.ini b/pixel-client/assets/tiles.ini
new file mode 100644
index 00000000..87729108
--- /dev/null
+++ b/pixel-client/assets/tiles.ini
@@ -0,0 +1,54 @@
+chair=floor,chair
+table=floor,table
+
+door=floor,door_we
+door=ns:floor,door_ns
+door=we:floor,door_we
+
+wall=:wall_ns
+wall=w:wall_ns
+wall=e:wall_ns
+wall=we:wall_we
+wall=n:wall_ns
+wall=wn:wall_wn
+wall=en:wall_wn~hflip
+wall=wen:wall_wen
+wall=s:wall_ns
+wall=ws:wall_ws
+wall=es:wall_ws~hflip
+wall=wes:wall_wes
+wall=ns:wall_ns
+wall=wns:wall_wns
+wall=ens:wall_wns~hflip
+wall=wens:wall_wens
+
+window=window
+window=ns:wall_ns
+window=we:window
+
+counter-window=we:counter_window_we_bottom,counter_window_we_top
+counter-window=ns:counter_window_ns_bottom,counter_window_ns_top
+counter-window=we:counter_window_we_bottom,counter_window_we_top
+
+floor=floor
+grass=grass
+path=path
+tree=tree
+
+tomato-crate=crate_back,tomato~x8~y6,crate_front
+raw-steak-crate=crate_back,steak_raw~x8~y6,crate_front
+flour-crate=crate_back,flour~x8~y6,crate_front
+leek-crate=crate_back,leek~x8~y6,crate_front
+rice-crate=crate_back,rice~x8~y6,crate_front
+fish-crate=crate_back,fish~x8~y6,crate_front
+coconut-crate=crate_back,coconut~x8~y6,crate_front
+strawberry-crate=crate_back,strawberry~x8~y6,crate_front
+
+counter=counter
+book=counter,book
+cuttingboard=counter,cutting_board
+sink=counter,sink
+stove=counter,stove
+freezer=freezer
+trash=trash
+oven=oven
diff --git a/pixel-client/makefile b/pixel-client/makefile
new file mode 100644
index 00000000..6a56fc62
--- /dev/null
+++ b/pixel-client/makefile
@@ -0,0 +1,37 @@
+
+SPRITES = $(shell find assets/sprites -name '*.ta')
+SPRITES_PNG = $(patsubst %.ta,%.png,$(SPRITES))
+
+TEXTURES = $(shell find assets/textures -name '*.ta')
+TEXTURES_PNG = $(patsubst %.ta,%.png,$(TEXTURES))
+TEXTURES_IMPORT_PNG = $(patsubst %.import.png,%.ta,$(shell find assets/textures -name '*.import.png'))
+
+PNG = $(shell find assets/textures -name '*.png')
+
+.PHONY: tex_pack tex_export tex_import clean
+tex_pack: assets/atlas.ta
+tex_import: $(TEXTURES_IMPORT_PNG)
+tex_export: $(TEXTURES_PNG) $(SPRITES_PNG) assets/atlas.png
+clean:
+ rm -f $(PNG)
+ rm -fr assets/sprites
+ rm -f assets/atlas.ta assets/atlas.meta.csv
+
+
+IMPORT = ../target/release/tex_import
+EXPORT = ../target/release/tex_export
+PACK = ../target/release/tex_pack
+COMPOSE = ../target/release/tex_compose
+
+%.ta: %.import.png
+ $(IMPORT) $< $@
+%.png: %.ta
+ ../target/release/tex_export $< $@
+
+assets/sprites/%/all: assets/%.ini $(TEXTURES)
+ @mkdir -p $(basename $@)
+ ../target/release/tex_compose $< assets/textures $(basename $@)
+ @touch $@
+
+assets/atlas.ta assets/atlas.meta.csv: assets/sprites/items/all assets/sprites/tiles/all assets/sprites/misc/all
+ ../target/release/tex_pack assets/atlas.ta assets/atlas.meta.csv $(SPRITES)
diff --git a/pixel-client/src/game.rs b/pixel-client/src/game.rs
new file mode 100644
index 00000000..7d8e466a
--- /dev/null
+++ b/pixel-client/src/game.rs
@@ -0,0 +1,344 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use crate::{
+ helper::Vec2InterpolateExt,
+ render::{
+ misc::MiscTextures,
+ sprite::{Sprite, SpriteDraw},
+ AtlasLayout, SpriteRenderer,
+ },
+ tilemap::Tilemap,
+};
+use hurrycurry_protocol::{
+ glam::{IVec2, Vec2},
+ movement::MovementBase,
+ ClientGamedata, ItemIndex, ItemLocation, PacketC, PacketS, PlayerID, TileIndex,
+};
+use log::{info, warn};
+use sdl2::{
+ keyboard::{KeyboardState, Scancode},
+ rect::Rect,
+};
+use std::collections::{HashMap, HashSet, VecDeque};
+
+pub struct Game {
+ data: ClientGamedata,
+ tiles: HashMap<IVec2, Tile>,
+ tilemap: Tilemap,
+ collision_map: HashSet<IVec2>,
+ players: HashMap<PlayerID, Player>,
+ my_id: PlayerID,
+
+ camera_center: Vec2,
+ misc_textures: MiscTextures,
+ item_sprites: Vec<Sprite>,
+ movement_send_cooldown: f32,
+ interacting: bool,
+ score: Score,
+}
+
+#[derive(Debug, Default)]
+pub struct Score {
+ points: i64,
+ demands_failed: usize,
+ demands_completed: usize,
+ time_remaining: f32,
+}
+
+pub struct Tile {
+ _kind: TileIndex,
+ item: Option<Item>,
+}
+
+pub struct Player {
+ movement: MovementBase,
+ item: Option<Item>,
+ _name: String,
+ _character: i32,
+}
+
+pub struct Item {
+ position: Vec2,
+ kind: ItemIndex,
+ progress: Option<(f32, bool)>,
+}
+
+impl Game {
+ pub fn new(layout: &AtlasLayout) -> Self {
+ Self {
+ tiles: HashMap::new(),
+ players: HashMap::new(),
+ tilemap: Tilemap::default(),
+ my_id: PlayerID(0),
+ data: ClientGamedata::default(),
+ collision_map: HashSet::new(),
+ movement_send_cooldown: 0.,
+ misc_textures: MiscTextures::init(layout),
+ item_sprites: Vec::new(),
+ interacting: false,
+ score: Score::default(),
+ camera_center: Vec2::ZERO,
+ }
+ }
+
+ pub fn packet_in(&mut self, packet: PacketC, renderer: &mut SpriteRenderer) {
+ match packet {
+ PacketC::Init { id } => self.my_id = id,
+ PacketC::Data { data } => {
+ self.tilemap.init(&data.tile_names, renderer.atlas_layout());
+ self.item_sprites = data
+ .item_names
+ .iter()
+ .map(|name| {
+ Sprite::new(
+ renderer
+ .atlas_layout()
+ .get(&format!("{name}+a"))
+ .copied()
+ .unwrap_or_else(|| {
+ warn!("no sprite for item {name:?}");
+ Rect::new(0, 0, 32, 24)
+ }),
+ Vec2::new(0., 0.0),
+ 0.1,
+ )
+ })
+ .collect();
+ self.data = data;
+ }
+ PacketC::UpdateMap {
+ tile,
+ kind,
+ neighbors,
+ } => {
+ if let Some(kind) = kind {
+ self.tiles.insert(
+ tile,
+ Tile {
+ _kind: kind,
+ item: None,
+ },
+ );
+ if self.data.tile_collide[kind.0] {
+ self.collision_map.remove(&tile);
+ } else {
+ self.collision_map.insert(tile);
+ }
+ } else {
+ self.tiles.remove(&tile);
+ self.collision_map.remove(&tile);
+ }
+ self.tilemap.set(tile, kind, neighbors);
+ }
+ PacketC::AddPlayer {
+ id,
+ position,
+ character,
+ name,
+ } => {
+ info!("add player {} {name:?}", id.0);
+ self.players.insert(
+ id,
+ Player {
+ _character: character,
+ _name: name,
+ item: None,
+ movement: MovementBase {
+ position,
+ facing: Vec2::X,
+ rotation: 0.,
+ velocity: Vec2::ZERO,
+ boosting: false,
+ stamina: 0.,
+ },
+ },
+ );
+ }
+ PacketC::RemovePlayer { id } => {
+ info!("remove player {}", id.0);
+ self.players.remove(&id);
+ }
+ PacketC::Position {
+ player,
+ pos,
+ rot,
+ boosting,
+ } => {
+ if player != self.my_id {
+ if let Some(p) = self.players.get_mut(&player) {
+ p.movement.position = pos;
+ p.movement.rotation = rot;
+ p.movement.boosting = boosting;
+ }
+ }
+ }
+ PacketC::MoveItem { from, to } => *self.get_item(to) = self.get_item(from).take(),
+ PacketC::SetItem { location, item } => {
+ *self.get_item(location) = item.map(|kind| Item {
+ kind,
+ position: Vec2::ZERO,
+ progress: None,
+ })
+ }
+ PacketC::SetProgress {
+ item,
+ progress,
+ warn,
+ } => {
+ self.get_item(item).as_mut().unwrap().progress = progress.map(|s| (s, warn));
+ }
+ PacketC::Collide {
+ player: _,
+ force: _,
+ } => (),
+ PacketC::Communicate { .. } => {
+ // TODO
+ }
+ PacketC::ServerMessage { text: _ } => {
+ // TODO
+ }
+ PacketC::Score {
+ points,
+ demands_failed,
+ demands_completed,
+ time_remaining,
+ } => {
+ self.score.points = points;
+ self.score.demands_completed = demands_completed;
+ self.score.demands_failed = demands_failed;
+ self.score.time_remaining = time_remaining.unwrap_or(-1.);
+ }
+ PacketC::SetIngame { state: _, lobby: _ } => {
+ // TODO
+ }
+ PacketC::Error { message } => {
+ warn!("server error: {message:?}")
+ }
+ _ => (),
+ }
+ }
+
+ pub fn get_item(&mut self, location: ItemLocation) -> &mut Option<Item> {
+ match location {
+ ItemLocation::Tile(pos) => &mut self.tiles.get_mut(&pos).unwrap().item,
+ ItemLocation::Player(pid) => &mut self.players.get_mut(&pid).unwrap().item,
+ }
+ }
+
+ pub fn tick(&mut self, dt: f32, keyboard: &KeyboardState, packet_out: &mut VecDeque<PacketS>) {
+ let mut direction = IVec2::new(
+ keyboard.is_scancode_pressed(Scancode::D) as i32
+ - keyboard.is_scancode_pressed(Scancode::A) as i32,
+ keyboard.is_scancode_pressed(Scancode::S) as i32
+ - keyboard.is_scancode_pressed(Scancode::W) as i32,
+ )
+ .as_vec2();
+ let boost = keyboard.is_scancode_pressed(Scancode::K);
+ let interact = keyboard.is_scancode_pressed(Scancode::Space)
+ | keyboard.is_scancode_pressed(Scancode::J);
+
+ if interact {
+ direction *= 0.;
+ }
+
+ self.movement_send_cooldown -= dt;
+ let send_movement = self.movement_send_cooldown < 0.;
+ if send_movement {
+ self.movement_send_cooldown += 0.04
+ }
+
+ self.score.time_remaining -= dt;
+ self.score.time_remaining -= self.score.time_remaining.max(0.);
+
+ if interact != self.interacting {
+ if interact {
+ packet_out.push_back(PacketS::Interact {
+ pos: Some(self.players[&self.my_id].movement.get_interact_target()),
+ });
+ } else {
+ packet_out.push_back(PacketS::Interact { pos: None });
+ }
+ self.interacting = interact;
+ }
+
+ if let Some(player) = self.players.get_mut(&self.my_id) {
+ let movement_packet = player
+ .movement
+ .update(&self.collision_map, direction, boost, dt);
+ if send_movement {
+ packet_out.push_back(movement_packet);
+ }
+
+ self.camera_center.exp_to(player.movement.position, dt * 5.);
+ }
+
+ for (_pid, player) in &mut self.players {
+ if let Some(item) = &mut player.item {
+ item.position = player.movement.position
+ }
+ }
+ for (pos, tile) in &mut self.tiles {
+ if let Some(item) = &mut tile.item {
+ item.position = pos.as_vec2() + 0.5
+ }
+ }
+ }
+
+ pub fn draw(&self, ctx: &mut SpriteRenderer) {
+ ctx.set_view(-self.camera_center + (ctx.size / ctx.get_scale() / 2.), 1.);
+
+ self.tilemap.draw(ctx);
+
+ for p in self.players.values() {
+ ctx.draw_world(self.misc_textures.player.at(p.movement.position));
+ if let Some(item) = &p.item {
+ item.draw(ctx, &self.item_sprites, &self.misc_textures)
+ }
+ }
+ for tile in self.tiles.values() {
+ if let Some(item) = &tile.item {
+ item.draw(ctx, &self.item_sprites, &self.misc_textures)
+ }
+ }
+ }
+}
+
+impl Item {
+ pub fn draw(&self, ctx: &mut SpriteRenderer, item_sprites: &[Sprite], misc: &MiscTextures) {
+ ctx.draw_world(item_sprites[self.kind.0].at(self.position));
+ if let Some((progress, warn)) = self.progress {
+ let (bg, fg) = if warn {
+ ([100, 0, 0, 200], [255, 0, 0, 200])
+ } else {
+ ([0, 100, 0, 200], [0, 255, 0, 200])
+ };
+ ctx.draw_world(SpriteDraw::overlay(
+ misc.solid,
+ self.position + Vec2::new(-0.5, -1.3),
+ Vec2::new(1., 0.2),
+ Some(bg),
+ ));
+ ctx.draw_world(SpriteDraw::overlay(
+ misc.solid,
+ self.position + Vec2::new(-0.5, -1.3),
+ Vec2::new(progress, 0.2),
+ Some(fg),
+ ))
+ }
+ }
+}
diff --git a/pixel-client/src/helper.rs b/pixel-client/src/helper.rs
new file mode 100644
index 00000000..9654f519
--- /dev/null
+++ b/pixel-client/src/helper.rs
@@ -0,0 +1,11 @@
+use hurrycurry_protocol::glam::Vec2;
+
+pub trait Vec2InterpolateExt {
+ fn exp_to(&mut self, target: Vec2, dt: f32);
+}
+impl Vec2InterpolateExt for Vec2 {
+ fn exp_to(&mut self, target: Vec2, dt: f32) {
+ self.x = target.x + (self.x - target.x) * (-dt).exp();
+ self.y = target.y + (self.y - target.y) * (-dt).exp();
+ }
+}
diff --git a/pixel-client/src/main.rs b/pixel-client/src/main.rs
new file mode 100644
index 00000000..e3aaa5cc
--- /dev/null
+++ b/pixel-client/src/main.rs
@@ -0,0 +1,105 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use game::Game;
+use hurrycurry_protocol::glam::Vec2;
+use network::Network;
+use render::SpriteRenderer;
+use sdl2::{
+ event::Event,
+ keyboard::{KeyboardState, Keycode},
+ pixels::Color,
+};
+use std::time::{Duration, Instant};
+
+pub mod game;
+pub mod helper;
+pub mod network;
+pub mod render;
+pub mod tilemap;
+
+fn main() {
+ env_logger::init_from_env("LOG");
+
+ let sdl_context = sdl2::init().unwrap();
+
+ let video_subsystem = sdl_context.video().unwrap();
+ let window = video_subsystem
+ .window("Hurry Curry! Light Client", 1280, 720)
+ .position_centered()
+ .resizable()
+ .build()
+ .map_err(|e| e.to_string())
+ .unwrap();
+
+ let mut canvas = window
+ .into_canvas()
+ .accelerated()
+ .build()
+ .map_err(|e| e.to_string())
+ .unwrap();
+ let texture_creator = canvas.texture_creator();
+
+ let mut net = Network::connect("ws://127.0.0.1/").unwrap();
+ let mut renderer = SpriteRenderer::init(&texture_creator);
+ let mut game = Game::new(&renderer.atlas_layout());
+
+ net.queue_out.push_back(hurrycurry_protocol::PacketS::Join {
+ name: "light".to_string(),
+ character: 0,
+ });
+
+ let mut events = sdl_context.event_pump().unwrap();
+
+ let mut last_tick = Instant::now();
+
+ canvas.set_logical_size(320, 240).unwrap();
+
+ 'mainloop: loop {
+ net.poll();
+
+ let (width, height) = canvas.logical_size();
+ renderer.size = Vec2::new(width as f32, height as f32);
+
+ for packet in net.queue_in.drain(..) {
+ game.packet_in(packet, &mut renderer);
+ }
+
+ let keyboard = KeyboardState::new(&events);
+ let dt = last_tick.elapsed().min(Duration::from_secs_f32(1. / 30.));
+ game.tick(dt.as_secs_f32(), &keyboard, &mut net.queue_out);
+ last_tick += dt;
+
+ game.draw(&mut renderer);
+
+ canvas.set_draw_color(Color::BLACK);
+ canvas.clear();
+ renderer.submit(&mut canvas);
+ canvas.present();
+
+ for event in events.poll_iter() {
+ match event {
+ Event::Quit { .. }
+ | Event::KeyDown {
+ keycode: Option::Some(Keycode::Escape),
+ ..
+ } => break 'mainloop,
+ _ => {}
+ }
+ }
+ }
+}
diff --git a/pixel-client/src/network.rs b/pixel-client/src/network.rs
new file mode 100644
index 00000000..ed160773
--- /dev/null
+++ b/pixel-client/src/network.rs
@@ -0,0 +1,123 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use anyhow::Result;
+use hurrycurry_protocol::{PacketC, PacketS, BINCODE_CONFIG};
+use log::{debug, warn};
+use std::{collections::VecDeque, net::TcpStream};
+use tungstenite::{
+ client::{uri_mode, IntoClientRequest},
+ client_tls_with_config,
+ handshake::client::Request,
+ stream::{MaybeTlsStream, Mode},
+ util::NonBlockingError,
+ Message, WebSocket,
+};
+
+pub struct Network {
+ sock: WebSocket<MaybeTlsStream<TcpStream>>,
+ pub queue_in: VecDeque<PacketC>,
+ pub queue_out: VecDeque<PacketS>,
+}
+
+impl Network {
+ pub fn connect(addr: &str) -> Result<Self> {
+ let (parts, _) = addr.into_client_request().unwrap().into_parts();
+ let mut builder = Request::builder()
+ .uri(parts.uri.clone().clone())
+ .method(parts.method.clone())
+ .version(parts.version);
+ *builder.headers_mut().unwrap() = parts.headers.clone();
+ let request = builder.body(()).unwrap();
+
+ let host = request.uri().host().unwrap();
+ let host = if host.starts_with('[') {
+ &host[1..host.len() - 1]
+ } else {
+ host
+ };
+ let port = request
+ .uri()
+ .port_u16()
+ .unwrap_or(match uri_mode(request.uri())? {
+ Mode::Plain => 27032,
+ Mode::Tls => 443,
+ });
+ let stream = TcpStream::connect((host, port))?;
+ stream.set_nodelay(true).unwrap();
+
+ let (mut sock, _) = client_tls_with_config(request, stream, None, None).unwrap();
+
+ match sock.get_mut() {
+ MaybeTlsStream::Plain(s) => s.set_nonblocking(true).unwrap(),
+ MaybeTlsStream::Rustls(s) => s.sock.set_nonblocking(true).unwrap(),
+ _ => todo!(),
+ };
+
+ Ok(Self {
+ sock,
+ queue_in: VecDeque::new(),
+ queue_out: VecDeque::new(),
+ })
+ }
+ pub fn poll(&mut self) {
+ loop {
+ self.queue_in.extend(match self.sock.read() {
+ Ok(Message::Text(packet)) => match serde_json::from_str(&packet) {
+ Ok(packet) => {
+ debug!("<- {packet:?}");
+ Some(packet)
+ }
+ Err(e) => {
+ warn!("invalid json packet: {e:?}");
+ None
+ }
+ },
+ Ok(Message::Binary(packet)) => {
+ match bincode::decode_from_slice(&packet, BINCODE_CONFIG) {
+ Ok((packet, _)) => {
+ debug!("<- {packet:?}");
+ Some(packet)
+ }
+ Err(e) => {
+ warn!("invalid bincode packet: {e:?}");
+ None
+ }
+ }
+ }
+ Ok(_) => None,
+ Err(e) => {
+ if let Some(e) = e.into_non_blocking() {
+ warn!("{e:?}");
+ None
+ } else {
+ break;
+ }
+ }
+ });
+ }
+
+ for packet in self.queue_out.drain(..) {
+ debug!("-> {packet:?}");
+ self.sock
+ .write(Message::Text(serde_json::to_string(&packet).unwrap()))
+ .unwrap();
+ }
+
+ self.sock.flush().unwrap();
+ }
+}
diff --git a/pixel-client/src/render/misc.rs b/pixel-client/src/render/misc.rs
new file mode 100644
index 00000000..9f866568
--- /dev/null
+++ b/pixel-client/src/render/misc.rs
@@ -0,0 +1,17 @@
+use super::{sprite::Sprite, AtlasLayout};
+use hurrycurry_protocol::glam::Vec2;
+use sdl2::rect::Rect;
+
+pub struct MiscTextures {
+ pub player: Sprite,
+ pub solid: Rect,
+}
+
+impl MiscTextures {
+ pub fn init(layout: &AtlasLayout) -> Self {
+ MiscTextures {
+ player: Sprite::new(*layout.get("player+a").unwrap(), Vec2::Y * 0.3, 0.5 + 0.3),
+ solid: *layout.get("solid+a").unwrap(),
+ }
+ }
+}
diff --git a/pixel-client/src/render/mod.rs b/pixel-client/src/render/mod.rs
new file mode 100644
index 00000000..a2aea365
--- /dev/null
+++ b/pixel-client/src/render/mod.rs
@@ -0,0 +1,158 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+pub mod misc;
+pub mod sprite;
+
+use hurrycurry_protocol::glam::Vec2;
+use sdl2::{
+ pixels::PixelFormatEnum,
+ rect::{FRect, Rect},
+ render::{BlendMode, Canvas, Texture, TextureAccess, TextureCreator},
+ video::{Window, WindowContext},
+};
+use sprite::SpriteDraw;
+use std::collections::HashMap;
+
+pub struct SpriteRenderer<'a> {
+ metadata: AtlasLayout,
+
+ pub size: Vec2,
+ texture: Texture<'a>,
+
+ view_scale: Vec2,
+ view_offset: Vec2,
+
+ sprites: Vec<SpriteDraw>,
+}
+
+pub type AtlasLayout = HashMap<String, Rect>;
+
+impl<'a> SpriteRenderer<'a> {
+ pub fn init(texture_creator: &'a TextureCreator<WindowContext>) -> Self {
+ let palette = include_str!("../../assets/palette.csv")
+ .split('\n')
+ .filter(|l| !l.is_empty())
+ .map(|s| {
+ let mut toks = s.split(",");
+ (
+ toks.next().unwrap().chars().next().unwrap(),
+ [
+ toks.next().unwrap().parse::<u8>().unwrap(),
+ toks.next().unwrap().parse::<u8>().unwrap(),
+ toks.next().unwrap().parse::<u8>().unwrap(),
+ toks.next().unwrap().parse::<u8>().unwrap(),
+ ],
+ )
+ })
+ .collect::<HashMap<_, _>>();
+
+ let mut texels = vec![255; 1024 * 1024 * 4];
+
+ for (y, line) in include_str!("../../assets/atlas.ta").lines().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ for (x, char) in line.chars().enumerate() {
+ let color = palette.get(&char).unwrap();
+ texels[(y * 1024 + x) * 4 + 0] = color[3];
+ texels[(y * 1024 + x) * 4 + 1] = color[2];
+ texels[(y * 1024 + x) * 4 + 2] = color[1];
+ texels[(y * 1024 + x) * 4 + 3] = color[0];
+ }
+ }
+
+ let mut texture = texture_creator
+ .create_texture(
+ Some(PixelFormatEnum::RGBA8888),
+ TextureAccess::Streaming,
+ 1024,
+ 1024,
+ )
+ .unwrap();
+
+ texture.update(None, &texels, 1024 * 4).unwrap();
+ texture.set_blend_mode(BlendMode::Blend);
+
+ let metadata = include_str!("../../assets/atlas.meta.csv")
+ .lines()
+ .filter(|l| !l.is_empty())
+ .map(|l| {
+ let mut toks = l.split(",");
+ let x: i32 = toks.next().unwrap().parse().unwrap();
+ let y: i32 = toks.next().unwrap().parse().unwrap();
+ let w: u32 = toks.next().unwrap().parse().unwrap();
+ let h: u32 = toks.next().unwrap().parse().unwrap();
+ let name = toks.next().unwrap().to_string();
+ (name, Rect::new(x, y, w, h))
+ })
+ .collect::<HashMap<_, _>>();
+
+ Self {
+ texture,
+ size: Vec2::ONE,
+ metadata,
+ sprites: vec![],
+ view_offset: Vec2::ZERO,
+ view_scale: Vec2::ZERO,
+ }
+ }
+
+ pub fn set_view(&mut self, offset: Vec2, scale: f32) {
+ self.view_offset = offset;
+ self.view_scale = Vec2::new(32., 24.) * scale;
+ }
+ pub fn get_scale(&self) -> Vec2 {
+ self.view_scale
+ }
+
+ #[inline]
+ pub fn atlas_layout(&self) -> &HashMap<String, Rect> {
+ &self.metadata
+ }
+
+ pub fn set_modulation(&mut self, r: u8, g: u8, b: u8, a: u8) {
+ self.texture.set_alpha_mod(a);
+ self.texture.set_color_mod(r, g, b);
+ }
+ pub fn reset_modulation(&mut self) {
+ self.set_modulation(255, 255, 255, 255)
+ }
+
+ pub fn draw_world(&mut self, sprite: SpriteDraw) {
+ self.sprites.push(SpriteDraw {
+ tint: sprite.tint,
+ z_order: sprite.z_order,
+ src: sprite.src,
+ dst: FRect::new(
+ ((sprite.dst.x + self.view_offset.x) * self.view_scale.x).round(),
+ ((sprite.dst.y + self.view_offset.y) * self.view_scale.y).round(),
+ (sprite.dst.w * self.view_scale.x).round(),
+ (sprite.dst.h * self.view_scale.y).round(),
+ ),
+ })
+ }
+
+ pub fn submit(&mut self, canvas: &mut Canvas<Window>) {
+ self.sprites.sort();
+ for SpriteDraw { src, dst, tint, .. } in self.sprites.drain(..) {
+ self.texture.set_color_mod(tint[0], tint[1], tint[2]);
+ self.texture.set_alpha_mod(tint[3]);
+ canvas.copy_f(&self.texture, src, dst).unwrap();
+ }
+ }
+}
diff --git a/pixel-client/src/render/sprite.rs b/pixel-client/src/render/sprite.rs
new file mode 100644
index 00000000..711f45bf
--- /dev/null
+++ b/pixel-client/src/render/sprite.rs
@@ -0,0 +1,76 @@
+use hurrycurry_protocol::glam::Vec2;
+use sdl2::rect::{FRect, Rect};
+
+pub struct Sprite {
+ z_offset: f32,
+ src: Rect,
+ relative_dst: FRect,
+}
+
+impl Sprite {
+ pub fn new(src: Rect, anchor: Vec2, elevation: f32) -> Self {
+ let relative_dst = FRect::new(
+ anchor.x - (src.w as f32) / 32. / 2.,
+ anchor.y - (src.h as f32) / 24.,
+ (src.w as f32) / 32.,
+ (src.h as f32) / 24.,
+ );
+ Self {
+ z_offset: elevation,
+ src,
+ relative_dst,
+ }
+ }
+ pub fn new_tile(src: Rect) -> Self {
+ Self::new(src, Vec2::new(0.5, 1.0), 0.5)
+ }
+ pub fn at(&self, pos: Vec2) -> SpriteDraw {
+ SpriteDraw {
+ z_order: ((self.z_offset + pos.y) * 24.) as i32,
+ src: self.src,
+ dst: FRect::new(
+ self.relative_dst.x + pos.x,
+ self.relative_dst.y + pos.y,
+ self.relative_dst.w,
+ self.relative_dst.h,
+ ),
+ tint: [0xff; 4],
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct SpriteDraw {
+ pub tint: [u8; 4],
+ pub z_order: i32,
+ pub src: Rect,
+ pub dst: FRect,
+}
+
+impl SpriteDraw {
+ pub fn overlay(src: Rect, pos: Vec2, size: Vec2, tint: Option<[u8; 4]>) -> Self {
+ Self {
+ dst: FRect::new(pos.x, pos.y, size.x, size.y),
+ src,
+ tint: tint.unwrap_or([0xff; 4]),
+ z_order: i32::MAX,
+ }
+ }
+}
+
+impl Ord for SpriteDraw {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.z_order.cmp(&other.z_order)
+ }
+}
+impl PartialOrd for SpriteDraw {
+ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+ Some(self.cmp(&other))
+ }
+}
+impl Eq for SpriteDraw {}
+impl PartialEq for SpriteDraw {
+ fn eq(&self, other: &Self) -> bool {
+ self.z_order == other.z_order && self.src == other.src && self.dst == other.dst
+ }
+}
diff --git a/pixel-client/src/tilemap.rs b/pixel-client/src/tilemap.rs
new file mode 100644
index 00000000..768f79ba
--- /dev/null
+++ b/pixel-client/src/tilemap.rs
@@ -0,0 +1,117 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use hurrycurry_protocol::{glam::IVec2, TileIndex};
+use log::warn;
+use sdl2::rect::Rect;
+use std::collections::{HashMap, HashSet};
+
+use crate::render::{
+ sprite::{Sprite, SpriteDraw},
+ SpriteRenderer,
+};
+
+#[derive(Default)]
+pub struct Tilemap {
+ connect_group_by_tile: Vec<Option<usize>>,
+ connect_members_by_group: Vec<HashSet<Option<TileIndex>>>,
+ tile_srcs: Vec<[Rect; 16]>,
+ tiles: HashMap<IVec2, SpriteDraw>,
+}
+
+impl Tilemap {
+ pub fn init(&mut self, tile_names: &[String], sprite_rects: &HashMap<String, Rect>) {
+ let tile_index = tile_names
+ .iter()
+ .enumerate()
+ .map(|(t, i)| (i.to_string(), t))
+ .collect::<HashMap<_, _>>();
+ self.connect_group_by_tile = vec![None; tile_names.len()];
+ self.connect_members_by_group = include_str!("../assets/connect.csv")
+ .lines()
+ .enumerate()
+ .map(|(gid, line)| {
+ line.split(",")
+ .flat_map(|tile| tile_index.get(tile).copied())
+ .map(|ti| {
+ self.connect_group_by_tile[ti] = Some(gid);
+ Some(TileIndex(ti))
+ })
+ .collect::<HashSet<_>>()
+ })
+ .collect::<Vec<_>>();
+
+ self.tile_srcs = tile_names
+ .iter()
+ .map(|name| {
+ let fallback = sprite_rects
+ .get(&format!("{name}+a"))
+ .copied()
+ .unwrap_or_else(|| {
+ warn!("no sprite for tile {name:?}");
+ Rect::new(0, 0, 0, 0)
+ });
+
+ [
+ sprite_rects.get(&format!("{name}+")),
+ sprite_rects.get(&format!("{name}+w")),
+ sprite_rects.get(&format!("{name}+e")),
+ sprite_rects.get(&format!("{name}+we")),
+ sprite_rects.get(&format!("{name}+n")),
+ sprite_rects.get(&format!("{name}+wn")),
+ sprite_rects.get(&format!("{name}+en")),
+ sprite_rects.get(&format!("{name}+wen")),
+ sprite_rects.get(&format!("{name}+s")),
+ sprite_rects.get(&format!("{name}+ws")),
+ sprite_rects.get(&format!("{name}+es")),
+ sprite_rects.get(&format!("{name}+wes")),
+ sprite_rects.get(&format!("{name}+ns")),
+ sprite_rects.get(&format!("{name}+wns")),
+ sprite_rects.get(&format!("{name}+ens")),
+ sprite_rects.get(&format!("{name}+wens")),
+ ]
+ .map(|e| e.copied().unwrap_or(fallback))
+ })
+ .collect();
+ }
+
+ pub fn set(&mut self, pos: IVec2, tile: Option<TileIndex>, neighbors: [Option<TileIndex>; 4]) {
+ let Some(tile) = tile else {
+ self.tiles.remove(&pos);
+ return;
+ };
+
+ let mut idx = 0;
+ if let Some(gid) = self.connect_group_by_tile[tile.0] {
+ let cgroup = &self.connect_members_by_group[gid];
+ idx |= 0b0100 * (cgroup.contains(&neighbors[0])) as usize;
+ idx |= 0b0001 * (cgroup.contains(&neighbors[1])) as usize;
+ idx |= 0b1000 * (cgroup.contains(&neighbors[2])) as usize;
+ idx |= 0b0010 * (cgroup.contains(&neighbors[3])) as usize;
+ }
+
+ let src = self.tile_srcs[tile.0][idx];
+ self.tiles
+ .insert(pos, Sprite::new_tile(src).at(pos.as_vec2()));
+ }
+
+ pub fn draw(&self, ctx: &mut SpriteRenderer) {
+ for &sprite in self.tiles.values() {
+ ctx.draw_world(sprite);
+ }
+ }
+}
diff --git a/pixel-client/tools/Cargo.toml b/pixel-client/tools/Cargo.toml
new file mode 100644
index 00000000..f3075594
--- /dev/null
+++ b/pixel-client/tools/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "tools"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+image = "0.25.1"
+anyhow = "1.0.86"
+log = "0.4.22"
+env_logger = "0.11.3"
+clap = { version = "4.5.9", features = ["derive"] }
+sdl2 = "0.37.0"
diff --git a/pixel-client/tools/src/bin/bunnymark.rs b/pixel-client/tools/src/bin/bunnymark.rs
new file mode 100644
index 00000000..f59fecff
--- /dev/null
+++ b/pixel-client/tools/src/bin/bunnymark.rs
@@ -0,0 +1,104 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use sdl2::{
+ event::Event,
+ image::{InitFlag, LoadTexture},
+ keyboard::Keycode,
+ pixels::Color,
+ rect::Rect,
+};
+use std::time::Instant;
+
+const WIDTH: i32 = 1920;
+const HEIGHT: i32 = 1080;
+
+pub fn main() {
+ let amount = std::env::args().skip(1).next().unwrap().parse().unwrap();
+
+ let sdl_context = sdl2::init().unwrap();
+ let video_subsystem = sdl_context.video().unwrap();
+ let _image_context = sdl2::image::init(InitFlag::WEBP | InitFlag::PNG).unwrap();
+ let window = video_subsystem
+ .window("Hurry Curry! Bunnymark", WIDTH as u32, HEIGHT as u32)
+ .position_centered()
+ .build()
+ .map_err(|e| e.to_string())
+ .unwrap();
+
+ let mut canvas = window
+ .into_canvas()
+ .accelerated()
+ .build()
+ .map_err(|e| e.to_string())
+ .unwrap();
+ let texture_creator = canvas.texture_creator();
+ let texture = texture_creator.load_texture("client/icon.png").unwrap();
+
+ let mut bunnies = vec![((0, 0), (0, 0)); amount];
+
+ for (i, (pos, vel)) in bunnies.iter_mut().enumerate() {
+ let mut r = xorshift(i as i32);
+ pos.0 = r % WIDTH;
+ r = xorshift(r);
+ pos.1 = r % HEIGHT;
+ r = xorshift(r);
+ vel.0 = r % 7 - 3;
+ r = xorshift(r);
+ vel.1 = r % 7 - 3;
+ }
+
+ let mut last = Instant::now();
+ 'mainloop: loop {
+ canvas.set_draw_color(Color::BLACK);
+ canvas.clear();
+ for (pos, vel) in &mut bunnies {
+ pos.0 += vel.0;
+ pos.1 += vel.1;
+ if pos.0 < 0 || pos.0 > WIDTH {
+ vel.0 *= -1
+ }
+ if pos.1 < 0 || pos.1 > HEIGHT {
+ vel.1 *= -1
+ }
+ canvas
+ .copy(&texture, None, Some(Rect::new(pos.0, pos.1, 30, 30)))
+ .unwrap();
+ }
+ canvas.present();
+
+ for event in sdl_context.event_pump().unwrap().poll_iter() {
+ match event {
+ Event::Quit { .. }
+ | Event::KeyDown {
+ keycode: Option::Some(Keycode::Escape),
+ ..
+ } => break 'mainloop,
+ _ => {}
+ }
+ }
+ println!("frame time: {:?}", last.elapsed());
+ last = Instant::now();
+ }
+}
+
+fn xorshift(mut x: i32) -> i32 {
+ x ^= x << 13;
+ x ^= x >> 17;
+ x ^= x << 5;
+ x
+}
diff --git a/pixel-client/tools/src/bin/tex_compose.rs b/pixel-client/tools/src/bin/tex_compose.rs
new file mode 100644
index 00000000..19c9ed7c
--- /dev/null
+++ b/pixel-client/tools/src/bin/tex_compose.rs
@@ -0,0 +1,135 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use clap::Parser;
+use std::{
+ collections::HashMap,
+ fs::{read_to_string, File},
+ io::{BufRead, BufReader, BufWriter, Write},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ catalogue: PathBuf,
+ texture_dir: PathBuf,
+ output_dir: PathBuf,
+}
+
+fn main() {
+ let Args {
+ catalogue,
+ texture_dir,
+ output_dir,
+ } = Args::parse();
+
+ for line in read_to_string(catalogue).unwrap().lines() {
+ let (line, _) = line.split_once(";").unwrap_or((line, ""));
+ let line = line.trim();
+ if line.is_empty() {
+ continue;
+ }
+
+ let (name, rest) = line.split_once("=").unwrap();
+ let (connects, rest) = rest.split_once(":").unwrap_or(("a", rest));
+ eprintln!(" compose {name:?} ({connects})");
+
+ let mut texels = HashMap::new();
+
+ for part in rest.split(",") {
+ let mut mods = part.split("~");
+ let texname = mods.next().unwrap();
+
+ let mut hflip = false;
+ let mut vflip = true;
+ let mut xoff = 0;
+ let mut yoff = 0;
+
+ for m in mods {
+ if m == "hflip" {
+ hflip = !hflip
+ }
+ if m == "vflip" {
+ vflip = !vflip
+ }
+ if let Some(m) = m.strip_prefix("x") {
+ xoff += m.parse::<i32>().unwrap();
+ }
+ if let Some(m) = m.strip_prefix("y") {
+ yoff += m.parse::<i32>().unwrap();
+ }
+ }
+
+ let texpath = texture_dir.join(texname).with_extension("ta");
+ eprintln!(" + {texpath:?}");
+ let file = BufReader::new(File::open(&texpath).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let (width, height) = (tex[0].chars().count(), tex.len());
+
+ for (mut y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ if vflip {
+ y = height - y - 1
+ }
+ for (mut x, char) in line.chars().enumerate() {
+ if hflip {
+ x = width - x - 1
+ }
+ let e = texels
+ .entry((x as i32 + xoff, y as i32 + yoff))
+ .or_insert(' ');
+ if char != ' ' {
+ *e = char
+ }
+ }
+ }
+ }
+
+ let mut min_x = 0;
+ let mut min_y = 0;
+ let mut max_x = 0;
+ let mut max_y = 0;
+ for (x, y) in texels.keys() {
+ min_x = min_x.min(*x);
+ min_y = min_y.min(*y);
+ max_x = max_x.max(*x + 1);
+ max_y = max_y.max(*y + 1);
+ }
+
+ let width = max_x - min_x;
+ let height = max_y - min_y;
+
+ let outpath = output_dir
+ .join(format!("{name}+{connects}"))
+ .with_extension("ta");
+ let mut output = BufWriter::new(File::create(outpath).unwrap());
+
+ for y in 0..height {
+ for x in 0..width {
+ write!(
+ output,
+ "{}",
+ texels.get(&(x + min_x, max_y - y - 1)).unwrap_or(&' ')
+ )
+ .unwrap();
+ }
+ writeln!(output).unwrap();
+ }
+ }
+}
diff --git a/pixel-client/tools/src/bin/tex_export.rs b/pixel-client/tools/src/bin/tex_export.rs
new file mode 100644
index 00000000..248990e6
--- /dev/null
+++ b/pixel-client/tools/src/bin/tex_export.rs
@@ -0,0 +1,75 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use clap::Parser;
+use image::Rgba;
+use std::{
+ collections::HashMap,
+ fs::File,
+ io::{BufRead, BufReader},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ input: PathBuf,
+ output: PathBuf,
+}
+
+fn main() {
+ let Args {
+ input,
+ output: out_path,
+ } = Args::parse();
+
+ let palette = include_str!("../../../assets/palette.csv")
+ .split('\n')
+ .filter(|l| !l.is_empty())
+ .map(|s| {
+ let (c, s) = s.split_once(",").unwrap();
+ let (r, s) = s.split_once(",").unwrap();
+ let (g, s) = s.split_once(",").unwrap();
+ let (b, a) = s.split_once(",").unwrap();
+ (
+ c.chars().next().unwrap(),
+ [
+ r.parse().unwrap(),
+ g.parse().unwrap(),
+ b.parse().unwrap(),
+ a.parse().unwrap(),
+ ],
+ )
+ })
+ .collect::<HashMap<_, _>>();
+
+ let file = BufReader::new(File::open(&input).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let (width, height) = (tex[0].chars().count(), tex.len());
+
+ let mut output = image::ImageBuffer::<Rgba<u8>, Vec<_>>::new(width as u32, height as u32);
+
+ for (y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ for (x, char) in line.chars().enumerate() {
+ output.put_pixel(x as u32, y as u32, Rgba(*palette.get(&char).unwrap()));
+ }
+ }
+
+ output.save(out_path).unwrap();
+}
diff --git a/pixel-client/tools/src/bin/tex_import.rs b/pixel-client/tools/src/bin/tex_import.rs
new file mode 100644
index 00000000..a5dad499
--- /dev/null
+++ b/pixel-client/tools/src/bin/tex_import.rs
@@ -0,0 +1,75 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use clap::Parser;
+use std::{
+ collections::HashMap,
+ fs::File,
+ io::{BufWriter, Write},
+ path::PathBuf,
+ process::exit,
+};
+
+#[derive(Parser)]
+struct Args {
+ input: PathBuf,
+ output: PathBuf,
+}
+
+fn main() {
+ let Args { input, output } = Args::parse();
+
+ let palette = include_str!("../../../assets/palette.csv")
+ .split('\n')
+ .filter(|l| !l.is_empty())
+ .map(|s| {
+ let (c, s) = s.split_once(",").unwrap();
+ let (r, s) = s.split_once(",").unwrap();
+ let (g, s) = s.split_once(",").unwrap();
+ let (b, a) = s.split_once(",").unwrap();
+ (
+ [
+ r.parse().unwrap(),
+ g.parse().unwrap(),
+ b.parse().unwrap(),
+ a.parse().unwrap(),
+ ],
+ c.chars().next().unwrap(),
+ )
+ })
+ .collect::<HashMap<_, _>>();
+
+ let input = image::open(input).unwrap().to_rgba8();
+ let mut output = BufWriter::new(File::create(output).unwrap());
+
+ for y in 0..input.height() {
+ for x in 0..input.width() {
+ let mut c = input.get_pixel(x, y).0;
+ if c[3] == 0 {
+ c = [0, 0, 0, 0];
+ }
+ let Some(char) = palette.get(&c) else {
+ eprintln!("color at {x},{y} not in palette: {c:?}");
+ exit(1);
+ };
+ write!(output, "{char}").unwrap();
+ }
+ writeln!(output).unwrap();
+ }
+ output.flush().unwrap();
+ output.into_inner().unwrap().flush().unwrap()
+}
diff --git a/pixel-client/tools/src/bin/tex_pack.rs b/pixel-client/tools/src/bin/tex_pack.rs
new file mode 100644
index 00000000..5022d561
--- /dev/null
+++ b/pixel-client/tools/src/bin/tex_pack.rs
@@ -0,0 +1,95 @@
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2024 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use clap::Parser;
+use std::{
+ fs::File,
+ io::{BufRead, BufReader, BufWriter, Write},
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+struct Args {
+ atlas_out: PathBuf,
+ atlas_meta_out: PathBuf,
+ inputs: Vec<PathBuf>,
+}
+
+fn main() {
+ let Args {
+ inputs,
+ atlas_meta_out,
+ atlas_out,
+ } = Args::parse();
+
+ let atlas_size = 1024;
+
+ let mut cursor_x = 0;
+ let mut cursor_y = 0;
+ let mut row_height = 0;
+
+ let mut texels = vec![vec![' '; atlas_size]; atlas_size];
+ let mut metadata = Vec::new();
+
+ println!(" savepack {atlas_out:?}");
+ for path in inputs {
+ let file = BufReader::new(File::open(&path).unwrap());
+ let tex = file.lines().map(Result::unwrap).collect::<Vec<String>>();
+ let name = path.file_stem().unwrap().to_str().unwrap().to_string();
+ let (width, height) = (tex[0].chars().count(), tex.len());
+
+ println!(" + {width}x{height} {name}");
+
+ if cursor_x + width > atlas_size {
+ cursor_y += row_height;
+ row_height = 0;
+ cursor_x = 0;
+ }
+ if cursor_y + height > atlas_size {
+ panic!("texture too big or atlas full");
+ }
+ row_height = row_height.max(height);
+ let texcoord = [cursor_x, cursor_y, width, height];
+
+ for (y, line) in tex.iter().enumerate() {
+ if line.is_empty() {
+ continue;
+ }
+ for (x, char) in line.chars().enumerate() {
+ texels[cursor_y + y][cursor_x + x] = char;
+ }
+ }
+
+ metadata.push((texcoord, name));
+
+ cursor_x += width;
+ }
+
+ let mut atlas_out = BufWriter::new(File::create(atlas_out).unwrap());
+ let mut atlas_meta_out = BufWriter::new(File::create(atlas_meta_out).unwrap());
+
+ for line in texels {
+ for char in line {
+ write!(atlas_out, "{char}").unwrap()
+ }
+ writeln!(atlas_out).unwrap();
+ }
+
+ for ([x, y, w, h], name) in metadata {
+ writeln!(atlas_meta_out, "{x},{y},{w},{h},{name}").unwrap();
+ }
+}
diff --git a/pixel-client/tools/src/lib.rs b/pixel-client/tools/src/lib.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/pixel-client/tools/src/lib.rs