Binary Tetris in tweets
Python 3, Score of 5 Tweets (242 spare, counting P0)



-19 bytes thanks to Jonathan Allan!

The spare count does not take into account newlines from between tweets.

Tweet 1 (Declaration, 12 bytes)

python3 t.py


Tweet 2 (70 bytes)

import msvcrt as m,os;f=c=s=0;a=34636833;r=range;p=1&lt;&lt;32;t=30
while 1:


Tweet 3 (129 bytes)

 if m.kbhit()and b"\xe0"==m.getch():p=[p&gt;&gt;(not(a|f&lt;&lt;1)&amp;p),p,p&lt;&lt;(not(a&lt;&lt;4|f&gt;&gt;1)&amp;p),p&gt;&gt;5-5*(bool(f&amp;p&gt;&gt;5)or p&lt;t)][ord(m.getch())-77]


Tweet 4 (113 bytes)

 c+=1;print("\n".join("".join(".#"[1&amp;(f|p)&gt;&gt;i*5+j]for j in r(5))for i in r(6))[::-1]);os.system("cls")
 if c%t&lt;1:


Tweet 5 (134 bytes)

  if f&amp;p&gt;&gt;5or p&lt;t:s=~s;f|=p;p=2-s&lt;&lt;26
  else:p&gt;&gt;=5
 for i in r(0,t,5):
  if f|31&lt;&lt;i==f:b=bin(f)[2:].zfill(t);f=int(b[:-i-5]+b[t-i:],2)


Full Program (449 bytes)

import msvcrt as m,os;f=c=s=0;a=34636833;r=range;p=1&lt;&lt;32;t=30
while 1:
 if m.kbhit()and b"\xe0"==m.getch():p=[p&gt;&gt;(not(a|f&lt;&lt;1)&amp;p),p,p&lt;&lt;(not(a&lt;&lt;4|f&gt;&gt;1)&amp;p),p&gt;&gt;5-5*(bool(f&amp;p&gt;&gt;5)or p&lt;t)][ord(m.getch())-77]
 c+=1;print("\n".join("".join(".#"[1&amp;(f|p)&gt;&gt;i*5+j]for j in r(5))for i in r(6))[::-1]);os.system("cls")
 if c%t&lt;1:
  if f&amp;p&gt;&gt;5or p&lt;t:s=~s;f|=p;p=2-s&lt;&lt;26
  else:p&gt;&gt;=5
 for i in r(0,t,5):
  if f|31&lt;&lt;i==f:b=bin(f)[2:].zfill(t);f=int(b[:-i-5]+b[t-i:],2)


Does some evil bit point hacking and stores the field and piece in two integers. I'll try and post an explanation soon.

Note: This only runs on Windows, but it could be switched to Linux through msvcrt → getch and "cls" → "clear". Additionally, character input doesn't work on Python's IDLE, so I'd recommend running it elsewhere.