diff --git a/core/assets/baseparts/1605279968000.msch b/core/assets/baseparts/1605279968000.msch
new file mode 100644
index 0000000000..7eb0cd3b7e
Binary files /dev/null and b/core/assets/baseparts/1605279968000.msch differ
diff --git a/core/assets/baseparts/1605280014089.msch b/core/assets/baseparts/1605280014089.msch
new file mode 100644
index 0000000000..127bf95450
--- /dev/null
+++ b/core/assets/baseparts/1605280014089.msch
@@ -0,0 +1,2 @@
+mschxœ-�ÑŠ!EouÔÙ�BÛÇ~„/ý#™†EptˆN¡_mÁã¹		ˆW…)‡�0×�ÖÆôÀò¤ºrÜ[,ppÿÜZl!ÇcókÉ/z†år4bÜjI�ý2%ß_„%…JìŸSÂm¾–ƒW‚©!½
+€;pêG�k�…VNf	¿Jjª›ÒÐ8�PK¨G8&~m3bfØÔçŸqk¾¡•'æÄæa¦ãbú/(Û×[¨=[)»
\ No newline at end of file
diff --git a/core/assets/baseparts/1605280470180.msch b/core/assets/baseparts/1605280470180.msch
new file mode 100644
index 0000000000..0936a4a315
--- /dev/null
+++ b/core/assets/baseparts/1605280470180.msch
@@ -0,0 +1 @@
+mschxœM‘Ûn„ E7^ÆëŒ1ý�¾ö��"JƒØi?¾µçÀKCd�ëÞ$â�—•S›Æp(·¾³ï–’UÅÑxŒ˜oU�»rÚJŠ>hÄD½ÉÃŸaÑ˜ž*ê õWj‰>àî�ý—N»Óç¦¢YäŒµäv’ˆŒþ©©»xeå¢]æý$í9š¨œ97¹x÷©¿IáüIèw^‘Î¯šjùµÓa¬¡IylÚòðT¾J”5¨RPDu¾ˆ*ÏÔÜh‹�¸QÞA4©‘P3n,ÇEF	Ñ‚WŠŽP·Õõ‹‚¾êú¹.žMSÐ“åŒäŒ²lè$¶’>g-JF—qÏÅGÆÄhé$t}Æ�1ò«ZÚ+XãÎF}ÆÀèù¯r6fé1K�,ý%†Tž
\ No newline at end of file
diff --git a/core/assets/baseparts/1605280548230.msch b/core/assets/baseparts/1605280548230.msch
new file mode 100644
index 0000000000..a21848a1f2
--- /dev/null
+++ b/core/assets/baseparts/1605280548230.msch
@@ -0,0 +1,2 @@
+mschxœ-�[nÃ E¯ñ;nÓ8ûà«+Bö(BÂ`i”½'qã¯3sï!pÁU ²j!ta¥)zúÅ0S˜¼^£vhÑ
Æ¨£²ú¾ÈÉÙ?z:�18£¼\•%#yºët[ÈF\V÷ /­›é¨£'³×Æ`Ð‘ÜÝO`
+|C¨p†hxßQ¥°NaÁÛŽ6+}Vú¤”èpJ]—•>ã”1$TøBÓ•Û{ûl/¾a·¬ùÍ3Š?kþ­øƒ”4A
\ No newline at end of file
diff --git a/core/assets/baseparts/1605281022715.msch b/core/assets/baseparts/1605281022715.msch
new file mode 100644
index 0000000000..5ea7a4b570
Binary files /dev/null and b/core/assets/baseparts/1605281022715.msch differ
diff --git a/core/assets/baseparts/1605281081581.msch b/core/assets/baseparts/1605281081581.msch
new file mode 100644
index 0000000000..ad93878cf2
Binary files /dev/null and b/core/assets/baseparts/1605281081581.msch differ
diff --git a/core/assets/baseparts/1605281121912.msch b/core/assets/baseparts/1605281121912.msch
new file mode 100644
index 0000000000..4c3235757c
--- /dev/null
+++ b/core/assets/baseparts/1605281121912.msch
@@ -0,0 +1,2 @@
+mschxœM�ÍÂ „géÄj¢'Ÿ¢ß[bL*4c|{gCB`vg?áÚè_vñq
+ù†aÛ”Ÿky¦8[Z|WÃ‚¾R8Ý})!GŽç5}BcšÃî4>O°;ÅŒ7Í±(…Ë_àNW4Ü\m•®J�F ¬ÅÀ°“†"®btk!ÂÊho:v]5ùBëNÉ¾æÒC¬=Nôw–6‡¶;í,tŒJóÁ,;
\ No newline at end of file
diff --git a/core/assets/baseparts/1605281215706.msch b/core/assets/baseparts/1605281215706.msch
new file mode 100644
index 0000000000..27c39cfdf1
Binary files /dev/null and b/core/assets/baseparts/1605281215706.msch differ
diff --git a/core/assets/baseparts/1605281306347.msch b/core/assets/baseparts/1605281306347.msch
new file mode 100644
index 0000000000..a200060661
Binary files /dev/null and b/core/assets/baseparts/1605281306347.msch differ
diff --git a/core/assets/baseparts/1605283900306.msch b/core/assets/baseparts/1605283900306.msch
new file mode 100644
index 0000000000..687c52017e
Binary files /dev/null and b/core/assets/baseparts/1605283900306.msch differ
diff --git a/core/assets/baseparts/1605284013998.msch b/core/assets/baseparts/1605284013998.msch
new file mode 100644
index 0000000000..31c282985c
Binary files /dev/null and b/core/assets/baseparts/1605284013998.msch differ
diff --git a/core/assets/baseparts/1605284595866.msch b/core/assets/baseparts/1605284595866.msch
new file mode 100644
index 0000000000..704fe6ed9c
Binary files /dev/null and b/core/assets/baseparts/1605284595866.msch differ
diff --git a/core/assets/baseparts/1605284660452.msch b/core/assets/baseparts/1605284660452.msch
new file mode 100644
index 0000000000..be36f1bc5b
Binary files /dev/null and b/core/assets/baseparts/1605284660452.msch differ
diff --git a/core/assets/baseparts/1605285080497.msch b/core/assets/baseparts/1605285080497.msch
new file mode 100644
index 0000000000..da0da93d56
Binary files /dev/null and b/core/assets/baseparts/1605285080497.msch differ
diff --git a/core/assets/baseparts/752927009641857205.msch b/core/assets/baseparts/752927009641857205.msch
deleted file mode 100644
index 7943fb1481..0000000000
Binary files a/core/assets/baseparts/752927009641857205.msch and /dev/null differ
diff --git a/core/assets/baseparts/752944648628076745.msch b/core/assets/baseparts/752944648628076745.msch
deleted file mode 100644
index 090ffe0155..0000000000
--- a/core/assets/baseparts/752944648628076745.msch
+++ /dev/null
@@ -1,2 +0,0 @@
-mschxœMŽan„ …Š®ºmMÿöŠètC‚`ºí‰{Š]:àŸ&ïñ˜=Þ¤Óázh·ª`öÝÒWiS‡Oa!Ìw)(úŽA/Ñ¼zcÿÉyw”6Í¢Ö`¬å^)ÜHE'¾]¼¶j!ƒùL7Â{4Q;“6µx÷E?Ü¡>ñL{y¢œ_‰½úÌ‡±†“êØÈ–ðÁ…¶$ÊŽ†ˆ¶êj7CÃn‹6ÿŠŽõÑ³!Ot-G+Ä‰æëoíÀè†.?ó£dò
—Ì�œkr/‰Ô8N4@Ï¨ƒd41úSqÃ‚± c%
-ÆÄÉ�M
\ No newline at end of file
diff --git a/core/assets/baseparts/752955880965799966.msch b/core/assets/baseparts/752955880965799966.msch
index 4cda9322ea..d96fc42c38 100644
Binary files a/core/assets/baseparts/752955880965799966.msch and b/core/assets/baseparts/752955880965799966.msch differ
diff --git a/core/assets/baseparts/752965444419453010.msch b/core/assets/baseparts/752965444419453010.msch
deleted file mode 100644
index 008b1f015b..0000000000
Binary files a/core/assets/baseparts/752965444419453010.msch and /dev/null differ
diff --git a/core/assets/baseparts/753005578997071974.msch b/core/assets/baseparts/753005578997071974.msch
index 747c61f453..c7dd6dceaa 100644
Binary files a/core/assets/baseparts/753005578997071974.msch and b/core/assets/baseparts/753005578997071974.msch differ
diff --git a/core/assets/baseparts/753035709576642631.msch b/core/assets/baseparts/753035709576642631.msch
deleted file mode 100644
index c1955436b5..0000000000
Binary files a/core/assets/baseparts/753035709576642631.msch and /dev/null differ
diff --git a/core/assets/baseparts/753653426667257906.msch b/core/assets/baseparts/753653426667257906.msch
deleted file mode 100644
index a5b60b4c99..0000000000
Binary files a/core/assets/baseparts/753653426667257906.msch and /dev/null differ
diff --git a/core/assets/baseparts/754024880747315332.msch b/core/assets/baseparts/754024880747315332.msch
new file mode 100644
index 0000000000..4bb358263a
--- /dev/null
+++ b/core/assets/baseparts/754024880747315332.msch
@@ -0,0 +1 @@
+mschxœM�kNì0…OÓ6íL�‰°�üa)ì ´Ö©MJšòX;‚Á®ï•Hä|Ž}l'8à¶@ú™põä—e¢‡üâÃù„vˆá�>cÂi	´Í}öƒ“Ÿ&Ü­qê“[ú@“cïL°3…‘î‡8?okö1¸3J}æÍsŸ3¥O—øNÉ…8ºy›²wK¢u…MûpfÜX‰Ó{Ïpô‘S?ì-ø9ãæ3º?ÃÑùL³[ã–Âõä_7?º-€Gè*v+%o^5`8Ô¢tÿE;j�Qßh�Ñ:£¹R•¥Ü$nQVŒEÍh!ÚæraûBÅ†ËÛwÙ ’y-ãF:U:ºâc‡Q”ŠJQ+,Š£‘é•<^p@qd÷é¸b4ŠVƒ,¹æŒ©åã{»ÊªÊªÊ²Ê´êPÑh¿F•�üMÀ#%ÈÊŽ}+7)ÙÁ¹>8÷ÚßWI
\ No newline at end of file
diff --git a/core/assets/baseparts/755588030362026104.msch b/core/assets/baseparts/755588030362026104.msch
new file mode 100644
index 0000000000..3603ec105e
--- /dev/null
+++ b/core/assets/baseparts/755588030362026104.msch
@@ -0,0 +1 @@
+mschxœ%�]!„öOã³gØC$‘DÀ°`âím)ý˜a†âŠMÁd—¶Ó¿Br-z‹åô®µPqo±¹{:|Éßð+·O}äŽg�ï7.±…tœ¥W0×Ò¹<0Žâa 4Ý5Ã@kL¤câ7#Q2VâJ†e_FØJØ²­0Kgµ°`(�L#ß-TÑ´Bz›˜;%ÉÜIiVù
\ No newline at end of file
diff --git a/core/assets/baseparts/759634196280508416.msch b/core/assets/baseparts/759634196280508416.msch
new file mode 100644
index 0000000000..cb0ff78983
--- /dev/null
+++ b/core/assets/baseparts/759634196280508416.msch
@@ -0,0 +1 @@
+mschxœ=ÑÍŽ›0†áƒã�ÃßÊt™à:ºêªWàÉX£¨DàÌÏ�w×Ú¼RÅâáû��à µ|ÏDOîÍËÓO·®×wþ¼{;ÿðÓù6º))Ÿ]~ùF·¼z9®s¼nnò£Ô.>ügXÜ%Ì‹”·û¸úá2O/÷k{¹�áúîÒ£zM“‡W?ùe+šÛüOó‹ÿ?ûBêEä·H¯]BÃ,”ÐÀ	zÙmgd;š‰¨ˆ"iØSæ$”–T@IY‘x¤lI|£ìyY�4ìÁÀPB�ÐÁ6zŸf¦WW°£Ô¤”†dáHY�*¨)R'ÊŽÔÃ“l«R°ƒ`áÔÐÂ	zˆ3u:qo	MÊI†dI©"5¤–ÔA/jŸ–*YB�†X( ‚Zè —L¥Ïr0`ÓêŽif¢‚Zè ® �¿Û˜ìïŸxèïm’ºÞˆúµÏ?è
\ No newline at end of file
diff --git a/core/assets/baseparts/759638168080351252.msch b/core/assets/baseparts/759638168080351252.msch
new file mode 100644
index 0000000000..7ebed705a8
Binary files /dev/null and b/core/assets/baseparts/759638168080351252.msch differ
diff --git a/core/assets/baseparts/772638841168461854.msch b/core/assets/baseparts/772638841168461854.msch
new file mode 100644
index 0000000000..b6af5101d8
Binary files /dev/null and b/core/assets/baseparts/772638841168461854.msch differ
diff --git a/core/assets/baseparts/772642175838191616.msch b/core/assets/baseparts/772642175838191616.msch
new file mode 100644
index 0000000000..a9d0084d20
Binary files /dev/null and b/core/assets/baseparts/772642175838191616.msch differ
diff --git a/core/assets/baseparts/772642264635670528.msch b/core/assets/baseparts/772642264635670528.msch
new file mode 100644
index 0000000000..a49b98f067
Binary files /dev/null and b/core/assets/baseparts/772642264635670528.msch differ
diff --git a/core/assets/baseparts/772642357136719872.msch b/core/assets/baseparts/772642357136719872.msch
new file mode 100644
index 0000000000..4b2bc355e2
Binary files /dev/null and b/core/assets/baseparts/772642357136719872.msch differ
diff --git a/core/assets/baseparts/772642606227390504.msch b/core/assets/baseparts/772642606227390504.msch
new file mode 100644
index 0000000000..c54d37f5ba
Binary files /dev/null and b/core/assets/baseparts/772642606227390504.msch differ
diff --git a/core/assets/baseparts/772642700713000960.msch b/core/assets/baseparts/772642700713000960.msch
new file mode 100644
index 0000000000..2fe878bddf
Binary files /dev/null and b/core/assets/baseparts/772642700713000960.msch differ
diff --git a/core/assets/baseparts/772754117604409344.msch b/core/assets/baseparts/772754117604409344.msch
new file mode 100644
index 0000000000..6b8699479c
Binary files /dev/null and b/core/assets/baseparts/772754117604409344.msch differ
diff --git a/core/assets/baseparts/772833439719489546.msch b/core/assets/baseparts/772833439719489546.msch
new file mode 100644
index 0000000000..8a5af23761
Binary files /dev/null and b/core/assets/baseparts/772833439719489546.msch differ
diff --git a/core/assets/baseparts/772833740053020682.msch b/core/assets/baseparts/772833740053020682.msch
new file mode 100644
index 0000000000..eb1fb26d3b
Binary files /dev/null and b/core/assets/baseparts/772833740053020682.msch differ
diff --git a/core/assets/baseparts/772836684403834920.msch b/core/assets/baseparts/772836684403834920.msch
new file mode 100644
index 0000000000..5d9f41d58f
Binary files /dev/null and b/core/assets/baseparts/772836684403834920.msch differ
diff --git a/core/assets/baseparts/772859800051908639.msch b/core/assets/baseparts/772859800051908639.msch
new file mode 100644
index 0000000000..175d05b796
Binary files /dev/null and b/core/assets/baseparts/772859800051908639.msch differ
diff --git a/core/assets/baseparts/772860007561166868.msch b/core/assets/baseparts/772860007561166868.msch
new file mode 100644
index 0000000000..27267597ad
--- /dev/null
+++ b/core/assets/baseparts/772860007561166868.msch
@@ -0,0 +1,2 @@
+mschxœMPÛnë |IâKëæáüÄ‘øŠJçú!›VH,Œ›æÛ›w­�w–™�ÝÅ8â±@åÔYãÏéÅ™xú§ÆèÃõôÔÅê€nÒËÌ�wÀ:«äŒµèLÔg¹ø5ŒÃEE*ú#†{‹±fôN.gm)áMTÎ¬gIö]_YÓŽ«�æ]¥ún™}ÐrzY0Œ^Y9jƒy]ß4ÚÙ_ØÞùIãñ-øÕMò5/K§·*ÈY9mqüu‘Ìè}šÕÕz5ýÌþ{‚ùC
T¢ !P–
ï(Ð�¡dAY˜V„
+"A
±#ìPì	‰ì’/�âÀPšmÛ¾ ¶¯mCÉ¬`v#÷Iî“Ì�\U&Ã}T�GÕyT�ûÔØªíFïzÀ�ô]nÒ&5Zˆ†{ôé%‚Ö}zEË•Ê\¬Cª@>­gèA_“%(3T	ÚL¶™l³½O¿!Á¢»7=Ò!9dmÈÚ�µ!ißŒTys
\ No newline at end of file
diff --git a/core/assets/baseparts/772860344174772254.msch b/core/assets/baseparts/772860344174772254.msch
new file mode 100644
index 0000000000..781cd94d46
Binary files /dev/null and b/core/assets/baseparts/772860344174772254.msch differ
diff --git a/core/assets/baseparts/772861253630165084.msch b/core/assets/baseparts/772861253630165084.msch
new file mode 100644
index 0000000000..e73ded4e03
--- /dev/null
+++ b/core/assets/baseparts/772861253630165084.msch
@@ -0,0 +1,3 @@
+mschxœ%ŽknÃ „ÇØIü¨äV9×È
ú;¢xS!a@€“úîMÝ%F¬¾Ñ>fz�Æ©™p¾~:“¯¥}ŽëõbU$%MÈÆ;à
ãCeŠ’~rT:ûˆ^/6›»*ú#y’A9²’Õ7Ï§à#É)%ŒÚ++5¹Ímáê˜Œ5Ú;™f²ì‹18Zf•�–S4Öb0™f™ü5áô¥2w­èƒðÎO„÷ VëÕ$ÙçN+Ÿ1(åíuÞ
+àŒýU¢ü
+‡mIŠR«uÃ¢�80ŽGF‹úÄ©2Ñˆ–U…º€›;FÝÖÛßöÜ~·'§ÇbØ3xb`´ÕË_ ÛÝ¾¼+Ëÿ©•UÊ
\ No newline at end of file
diff --git a/core/assets/baseparts/772861891516301334.msch b/core/assets/baseparts/772861891516301334.msch
new file mode 100644
index 0000000000..6e69e6b51a
Binary files /dev/null and b/core/assets/baseparts/772861891516301334.msch differ
diff --git a/core/assets/baseparts/772862221297909760.msch b/core/assets/baseparts/772862221297909760.msch
new file mode 100644
index 0000000000..83f138819d
Binary files /dev/null and b/core/assets/baseparts/772862221297909760.msch differ
diff --git a/core/assets/baseparts/772880624582787112.msch b/core/assets/baseparts/772880624582787112.msch
new file mode 100644
index 0000000000..0c260e50d1
Binary files /dev/null and b/core/assets/baseparts/772880624582787112.msch differ
diff --git a/core/assets/baseparts/772880838392152095.msch b/core/assets/baseparts/772880838392152095.msch
new file mode 100644
index 0000000000..5923b9dfe9
Binary files /dev/null and b/core/assets/baseparts/772880838392152095.msch differ
diff --git a/core/assets/baseparts/773972917637611530.msch b/core/assets/baseparts/773972917637611530.msch
new file mode 100644
index 0000000000..9c9c4778d6
Binary files /dev/null and b/core/assets/baseparts/773972917637611530.msch differ
diff --git a/core/assets/baseparts/773972978551226368.msch b/core/assets/baseparts/773972978551226368.msch
new file mode 100644
index 0000000000..7b74ef5219
--- /dev/null
+++ b/core/assets/baseparts/773972978551226368.msch
@@ -0,0 +1 @@
+mschxœ%�]Â „‡ŸÖ³øàm|3U‰i¢­ÁãíevJš�&»1zÄezVŒó}9¿×ÇÔNØßêûÚæ×6¯�/Ó¶ÕöÃÞ‡×´ÔGŸv¯‡mýÖà}N?Qäì¨Ìv¶1x™Y(„%½"ž"ÈLBfÒ³´ë'	}"Ï!	vCd•Þ*b‘LðŽAªA*éM‰õˆ(BâIÕ²Ì|¤’�™Ìz!''x™Y(L–Þµ³!Á&`Íï8šÝþ	Ú
\ No newline at end of file
diff --git a/core/assets/baseparts/773973064429993996.msch b/core/assets/baseparts/773973064429993996.msch
new file mode 100644
index 0000000000..c383e58c3f
--- /dev/null
+++ b/core/assets/baseparts/773973064429993996.msch
@@ -0,0 +1 @@
+mschxœEÏmjÃ0à×ùtÚ´ìù»ÓF–˜Î�ØÅi»ÑnÙIcóX‘,ËxA¯aã¸zœÃ-¾oa½/~ÞÓ7ûmÊáþ)5ýE=¥øå¿SF™ÓþðnKË˜‡ûý‚þ#‡ùæ‡ÿªÕÇ™«ÂÃ¯Ã–ö<y\V?}Ž1Lã2Ì9,€WZh¡'tPŠv-´&G´�F#PNN8ñ9�3HÎ*ÆV(„R¨ ,QW�Ï®§ÞA½9éªçóùFëÇðJ'jOWYÚk¾¡Ž¡,
uäŽ¡¬T\É´<g!sÔ“r%ç@´Ô—pBÇÏ®ä\-4B+8¡NÂ™)	[ð³*ôŒ"è?G†¯¼Ht•Üõ/¢Ü/ÐG6‹
\ No newline at end of file
diff --git a/core/assets/baseparts/773973230179319858.msch b/core/assets/baseparts/773973230179319858.msch
new file mode 100644
index 0000000000..59840f8023
Binary files /dev/null and b/core/assets/baseparts/773973230179319858.msch differ
diff --git a/core/assets/baseparts/773973383956135957.msch b/core/assets/baseparts/773973383956135957.msch
new file mode 100644
index 0000000000..ea8db498d2
Binary files /dev/null and b/core/assets/baseparts/773973383956135957.msch differ
diff --git a/core/assets/baseparts/773973810848333844.msch b/core/assets/baseparts/773973810848333844.msch
new file mode 100644
index 0000000000..888507a6ba
--- /dev/null
+++ b/core/assets/baseparts/773973810848333844.msch
@@ -0,0 +1,2 @@
+mschxœ%ÎÝ‚0à³EÑK_‚;ßÇhp	lËFßÞÎ^,_Û%§Eƒ›†õÃJ¸¹Ù?_ƒ[>�ìÖ¸Ú‰ò˜\Ü\ð@
[~q�žöuØÜØOÉ-êö�š1ø7}CB7§!¾ÜF}L”3Z.×>‡=�àÎ”‚âBk¦ƒs…2\qg`¸W-Á
+•P¡ŽÂIh…3”e.e�-k+Î0Pé’Öñ„ÓþwÔåp(ßøžx&�
\ No newline at end of file
diff --git a/core/assets/baseparts/773974064850272309.msch b/core/assets/baseparts/773974064850272309.msch
new file mode 100644
index 0000000000..b9109ca782
Binary files /dev/null and b/core/assets/baseparts/773974064850272309.msch differ
diff --git a/core/assets/baseparts/773974140545531924.msch b/core/assets/baseparts/773974140545531924.msch
new file mode 100644
index 0000000000..5a1570cd07
Binary files /dev/null and b/core/assets/baseparts/773974140545531924.msch differ
diff --git a/core/assets/baseparts/773976628883619840.msch b/core/assets/baseparts/773976628883619840.msch
new file mode 100644
index 0000000000..3536999ddf
Binary files /dev/null and b/core/assets/baseparts/773976628883619840.msch differ
diff --git a/core/assets/baseparts/774001709088505867.msch b/core/assets/baseparts/774001709088505867.msch
new file mode 100644
index 0000000000..432907e211
Binary files /dev/null and b/core/assets/baseparts/774001709088505867.msch differ
diff --git a/core/assets/baseparts/774002215428816936.msch b/core/assets/baseparts/774002215428816936.msch
new file mode 100644
index 0000000000..8c301a217d
Binary files /dev/null and b/core/assets/baseparts/774002215428816936.msch differ
diff --git a/core/assets/baseparts/774013552553754635.msch b/core/assets/baseparts/774013552553754635.msch
new file mode 100644
index 0000000000..cb900f4073
Binary files /dev/null and b/core/assets/baseparts/774013552553754635.msch differ
diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties
index f2a89e8508..465d83a44c 100644
--- a/core/assets/bundles/bundle.properties
+++ b/core/assets/bundles/bundle.properties
@@ -537,6 +537,12 @@ sectors.nonelaunch = [lightgray]none (sun)
 sectors.rename = Rename Sector
 sector.missingresources = [scarlet]Insufficient Core Resources
 
+threat.low = Low
+threat.medium = Medium
+threat.high = High
+threat.extreme = Extreme
+threat.eradication = Eradication
+
 planet.serpulo.name = Serpulo
 #TODO better name
 planet.sun.name = Sun
@@ -554,6 +560,7 @@ sector.overgrowth.name = Overgrowth
 sector.tarFields.name = Tar Fields
 sector.saltFlats.name = Salt Flats
 sector.fungalPass.name = Fungal Pass
+sector.biomassResearchFacility.name = Biomass Research Facility
 
 #unused
 #sector.crags.name = Crags
diff --git a/core/assets/maps/biomassResearchFacility.msav b/core/assets/maps/biomassResearchFacility.msav
new file mode 100644
index 0000000000..b9faa4a7f4
Binary files /dev/null and b/core/assets/maps/biomassResearchFacility.msav differ
diff --git a/core/assets/sounds/place.ogg b/core/assets/sounds/place.ogg
index ff1d05c211..29bcec7a9b 100644
Binary files a/core/assets/sounds/place.ogg and b/core/assets/sounds/place.ogg differ
diff --git a/core/assets/sounds/spark.ogg b/core/assets/sounds/spark.ogg
index ac61a476de..352e98c743 100644
Binary files a/core/assets/sounds/spark.ogg and b/core/assets/sounds/spark.ogg differ
diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java
index 30ed08a97f..90a8ed0f0e 100644
--- a/core/src/mindustry/content/Blocks.java
+++ b/core/src/mindustry/content/Blocks.java
@@ -1179,7 +1179,7 @@ public class Blocks implements ContentList{
             size = 2;
             floating = true;
             ambientSound = Sounds.hum;
-            ambientSoundVolume = 0.04f;
+            ambientSoundVolume = 0.06f;
         }};
 
         steamGenerator = new BurnerGenerator("steam-generator"){{
@@ -1217,13 +1217,13 @@ public class Blocks implements ContentList{
 
         solarPanel = new SolarGenerator("solar-panel"){{
             requirements(Category.power, with(Items.lead, 10, Items.silicon, 15));
-            powerProduction = 0.07f;
+            powerProduction = 0.08f;
         }};
 
         largeSolarPanel = new SolarGenerator("solar-panel-large"){{
             requirements(Category.power, with(Items.lead, 100, Items.silicon, 145, Items.phaseFabric, 15));
             size = 3;
-            powerProduction = 0.95f;
+            powerProduction = 1f;
         }};
 
         thoriumReactor = new NuclearReactor("thorium-reactor"){{
diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java
index 87f042ed13..c7509d06d7 100644
--- a/core/src/mindustry/content/Bullets.java
+++ b/core/src/mindustry/content/Bullets.java
@@ -358,6 +358,7 @@ public class Bullets implements ContentList{
             shootEffect = Fx.shootBig;
             pierceCap = 2;
             pierceBuilding = true;
+            knockback = 0.7f;
         }};
 
         standardIncendiaryBig = new BasicBulletType(7f, 60, "bullet"){{
diff --git a/core/src/mindustry/content/SectorPresets.java b/core/src/mindustry/content/SectorPresets.java
index 96107d7ca3..804c6769da 100644
--- a/core/src/mindustry/content/SectorPresets.java
+++ b/core/src/mindustry/content/SectorPresets.java
@@ -8,7 +8,7 @@ import static mindustry.content.Planets.*;
 public class SectorPresets implements ContentList{
     public static SectorPreset
     groundZero,
-    craters, frozenForest, ruinousShores, stainedMountains, tarFields, fungalPass,
+    craters, biomassFacility, frozenForest, ruinousShores, stainedMountains, tarFields, fungalPass,
     saltFlats, overgrowth,
     impact0078, desolateRift, nuclearComplex;
 
@@ -31,6 +31,11 @@ public class SectorPresets implements ContentList{
             difficulty = 2;
         }};
 
+        biomassFacility = new SectorPreset("biomassResearchFacility", serpulo, 81){{
+            captureWave = 20;
+            difficulty = 3;
+        }};
+
         craters = new SectorPreset("craters", serpulo, 18){{
             captureWave = 20;
             difficulty = 2;
@@ -50,7 +55,7 @@ public class SectorPresets implements ContentList{
             difficulty = 4;
         }};
 
-        overgrowth = new SectorPreset("overgrowth", serpulo, 22){{
+        overgrowth = new SectorPreset("overgrowth", serpulo, 134){{
             difficulty = 5;
         }};
 
diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java
index b7eb855703..559611fb69 100644
--- a/core/src/mindustry/content/TechTree.java
+++ b/core/src/mindustry/content/TechTree.java
@@ -115,7 +115,7 @@ public class TechTree implements ContentList{
                             node(Items.titanium, with(Items.graphite, 3000, Items.copper, 7000, Items.lead, 7000), () -> {
                                 node(pneumaticDrill, () -> {
                                     node(Items.sporePod, with(Items.coal, 4000, Items.graphite, 4000, Items.lead, 4000), () -> {
-                                        node(cultivator, () -> {
+                                        node(cultivator, Seq.with(new SectorComplete(biomassFacility)), () -> {
 
                                         });
                                     });
@@ -524,24 +524,31 @@ public class TechTree implements ContentList{
                         });
                     });
 
-                    node(stainedMountains, Seq.with(
+                    node(biomassFacility, Seq.with(
                         new SectorComplete(frozenForest),
-                        new Research(pneumaticDrill),
                         new Research(powerNode),
-                        new Research(steamGenerator)
+                        new Research(steamGenerator),
+                        new Research(scatter),
+                        new Research(graphitePress)
                     ), () -> {
-                        node(fungalPass, Seq.with(
-                            new SectorComplete(stainedMountains),
-                            new Research(groundFactory),
-                            new Research(door),
+                        node(stainedMountains, Seq.with(
+                            new SectorComplete(biomassFacility),
+                            new Research(pneumaticDrill),
                             new Research(siliconSmelter)
                         ), () -> {
-                            node(nuclearComplex, Seq.with(
-                                new SectorComplete(fungalPass),
-                                new Research(thermalGenerator),
-                                new Research(laserDrill)
+                            node(fungalPass, Seq.with(
+                                new SectorComplete(stainedMountains),
+                                new Research(groundFactory),
+                                new Research(door),
+                                new Research(siliconSmelter)
                             ), () -> {
+                                node(nuclearComplex, Seq.with(
+                                    new SectorComplete(fungalPass),
+                                    new Research(thermalGenerator),
+                                    new Research(laserDrill)
+                                ), () -> {
 
+                                });
                             });
                         });
                     });
diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java
index 05c9da481b..646d0732a6 100644
--- a/core/src/mindustry/core/Logic.java
+++ b/core/src/mindustry/core/Logic.java
@@ -80,6 +80,13 @@ public class Logic implements ApplicationListener{
                     state.wavetime = state.rules.waveSpacing;
 
                     SectorDamage.applyCalculatedDamage();
+
+                    //make sure damaged buildings are counted
+                    for(Tile tile : world.tiles){
+                        if(tile.build != null && tile.build.damaged()){
+                            indexer.notifyTileDamaged(tile.build);
+                        }
+                    }
                 }
 
                 //reset values
diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java
index 12c00b10d2..992a40e955 100644
--- a/core/src/mindustry/entities/comp/UnitComp.java
+++ b/core/src/mindustry/entities/comp/UnitComp.java
@@ -381,7 +381,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
         }
 
         //remove units spawned by the core
-        if(spawnedByCore && !isPlayer()){
+        if(spawnedByCore && !isPlayer() && !dead){
             Call.unitDespawn(self());
         }
     }
diff --git a/core/src/mindustry/game/SectorInfo.java b/core/src/mindustry/game/SectorInfo.java
index 90e70a9521..9d1de8042b 100644
--- a/core/src/mindustry/game/SectorInfo.java
+++ b/core/src/mindustry/game/SectorInfo.java
@@ -124,7 +124,7 @@ public class SectorInfo{
 
         //assign new wave patterns when the version changes
         if(waveVersion != Waves.waveVersion && state.rules.sector.preset == null){
-            state.rules.spawns = Waves.generate(state.rules.sector.baseCoverage);
+            state.rules.spawns = Waves.generate(state.rules.sector.threat);
         }
 
         CoreBuild entity = state.rules.defaultTeam.core();
diff --git a/core/src/mindustry/game/Waves.java b/core/src/mindustry/game/Waves.java
index 44b557ae1b..7b8c12c6ef 100644
--- a/core/src/mindustry/game/Waves.java
+++ b/core/src/mindustry/game/Waves.java
@@ -285,7 +285,7 @@ public class Waves{
 
             for(int i = start; i < cap;){
                 int f = i;
-                int next = rand.random(8, 16) + curTier * 4;
+                int next = rand.random(8, 16) + (int)Mathf.lerp(4f, 0f, difficulty) + curTier * 4;
 
                 float shieldAmount = Math.max((i - shieldStart) * shieldsPerWave, 0);
                 int space = start == 0 ? 1 : rand.random(1, 2);
@@ -296,8 +296,8 @@ public class Waves{
                     unitAmount = f == start ? 1 : 6 / (int)scaling[ctier];
                     begin = f;
                     end = f + next >= cap ? never : f + next;
-                    max = 14;
-                    unitScaling = (difficulty < 0.4f ? rand.random(2f, 4f) : rand.random(1f, 3f)) * scaling[ctier];
+                    max = 13;
+                    unitScaling = (difficulty < 0.4f ? rand.random(2.5f, 4f) : rand.random(1f, 4f)) * scaling[ctier];
                     shields = shieldAmount;
                     shieldScaling = shieldsPerWave;
                     spacing = space;
diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java
index c11728be47..50bcf839e3 100644
--- a/core/src/mindustry/input/DesktopInput.java
+++ b/core/src/mindustry/input/DesktopInput.java
@@ -401,7 +401,6 @@ public class DesktopInput extends InputHandler{
                 ui.schematics.hide();
             }else{
                 ui.schematics.show();
-                ui.schematics.focusSearchField();
             }
         }
 
diff --git a/core/src/mindustry/maps/generators/BaseGenerator.java b/core/src/mindustry/maps/generators/BaseGenerator.java
index c0f4e2e705..d33b8709ba 100644
--- a/core/src/mindustry/maps/generators/BaseGenerator.java
+++ b/core/src/mindustry/maps/generators/BaseGenerator.java
@@ -13,6 +13,7 @@ import mindustry.gen.*;
 import mindustry.type.*;
 import mindustry.world.*;
 import mindustry.world.blocks.defense.*;
+import mindustry.world.blocks.distribution.*;
 import mindustry.world.blocks.power.*;
 import mindustry.world.blocks.production.*;
 import mindustry.world.meta.*;
@@ -38,9 +39,6 @@ public class BaseGenerator{
 
         Mathf.rand.setSeed(sector.id);
 
-        //TODO limit base size
-        float costBudget = 1000;
-
         Seq<Block> wallsSmall = content.blocks().select(b -> b instanceof Wall && b.size == 1 && b.buildVisibility == BuildVisibility.shown && !(b instanceof Door));
         Seq<Block> wallsLarge = content.blocks().select(b -> b instanceof Wall && b.size == 2 && b.buildVisibility == BuildVisibility.shown && !(b instanceof Door));
 
@@ -51,10 +49,12 @@ public class BaseGenerator{
         //TODO proper difficulty selection
         float bracket = difficulty;
         float bracketRange = 0.2f;
+        float baseChance = Mathf.lerp(0.7f, 1.9f, difficulty);
         int wallAngle = 70; //180 for full coverage
-        double resourceChance = 0.5;
-        double nonResourceChance = 0.0005;
+        double resourceChance = 0.5 * baseChance;
+        double nonResourceChance = 0.0005 * baseChance;
         BasePart coreschem = bases.cores.getFrac(bracket);
+        int passes = difficulty < 0.4 ? 1 : difficulty < 0.8 ? 2 : 3;
 
         Block wall = wallsSmall.getFrac(bracket), wallLarge = wallsLarge.getFrac(bracket);
 
@@ -69,20 +69,22 @@ public class BaseGenerator{
             }
         }
 
-        //random schematics
-        pass(tile -> {
-            if(!tile.block().alwaysReplace) return;
+        for(int i = 0; i < passes; i++){
+            //random schematics
+            pass(tile -> {
+                if(!tile.block().alwaysReplace) return;
 
-            if(((tile.overlay().asFloor().itemDrop != null || (tile.drop() != null && Mathf.chance(nonResourceChance)))
+                if(((tile.overlay().asFloor().itemDrop != null || (tile.drop() != null && Mathf.chance(nonResourceChance)))
                 || (tile.floor().liquidDrop != null && Mathf.chance(nonResourceChance * 2))) && Mathf.chance(resourceChance)){
-                Seq<BasePart> parts = bases.forResource(tile.drop() != null ? tile.drop() : tile.floor().liquidDrop);
-                if(!parts.isEmpty()){
-                    tryPlace(parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team);
+                    Seq<BasePart> parts = bases.forResource(tile.drop() != null ? tile.drop() : tile.floor().liquidDrop);
+                    if(!parts.isEmpty()){
+                        tryPlace(parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team);
+                    }
+                }else if(Mathf.chance(nonResourceChance)){
+                    tryPlace(bases.parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team);
                 }
-            }else if(Mathf.chance(nonResourceChance)){
-                tryPlace(bases.parts.getFrac(bracket + Mathf.range(bracketRange)), tile.x, tile.y, team);
-            }
-        });
+            });
+        }
 
         //replace walls with the correct type (disabled)
         if(false)
@@ -100,6 +102,15 @@ public class BaseGenerator{
                 if(tile.block().alwaysReplace){
                     boolean any = false;
 
+                    for(Point2 p : Geometry.d4){
+                        Tile o = tiles.get(tile.x + p.x, tile.y + p.y);
+
+                        //do not block payloads
+                        if(o != null && (o.block() instanceof PayloadConveyor || o.block() instanceof PayloadAcceptor)){
+                            return;
+                        }
+                    }
+
                     for(Point2 p : Geometry.d8){
                         if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(tile)) > wallAngle){
                             continue;
diff --git a/core/src/mindustry/maps/generators/PlanetGenerator.java b/core/src/mindustry/maps/generators/PlanetGenerator.java
index 4b5884014b..d6a37e2767 100644
--- a/core/src/mindustry/maps/generators/PlanetGenerator.java
+++ b/core/src/mindustry/maps/generators/PlanetGenerator.java
@@ -19,7 +19,7 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe
         boolean any = false;
         float noise = Noise.snoise3(tile.v.x, tile.v.y, tile.v.z, 0.001f, 0.5f);
 
-        if(noise > 0.028){
+        if(noise > 0.027){
             any = true;
         }
 
diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java
index 4b878d3dd2..5fc443d82a 100644
--- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java
+++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java
@@ -232,6 +232,10 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
             ores.add(Blocks.oreThorium);
         }
 
+        if(rand.chance(0.25)){
+            ores.add(Blocks.oreScrap);
+        }
+
         FloatSeq frequencies = new FloatSeq();
         for(int i = 0; i < ores.size; i++){
             frequencies.add(rand.random(-0.09f, 0.01f) - i * 0.01f);
@@ -250,6 +254,10 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
                     break;
                 }
             }
+
+            if(ore == Blocks.oreScrap && rand.chance(0.33)){
+                floor = Blocks.metalFloorDamaged;
+            }
         });
 
         trimDark();
@@ -326,7 +334,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
             }
         });
 
-        float difficulty = sector.baseCoverage;
+        float difficulty = sector.threat;
         ints.clear();
         ints.ensureCapacity(width * height / 4);
 
@@ -417,7 +425,11 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
             state.rules.winWave = sector.info.winWave = 10 + 5 * (int)Math.max(difficulty * 10, 1);
         }
 
+        float waveTimeDec = 0.4f;
+
+        state.rules.waveSpacing = Mathf.lerp(60 * 65 * 2, 60f * 60f * 1f, Math.max(difficulty - waveTimeDec, 0f) / 0.8f);
         state.rules.waves = sector.info.waves = true;
+        state.rules.enemyCoreBuildRadius = 600f;
 
         //TODO better waves
         state.rules.spawns = Waves.generate(difficulty);
diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java
index 200fa9ef6a..a9e6764078 100644
--- a/core/src/mindustry/type/Planet.java
+++ b/core/src/mindustry/type/Planet.java
@@ -186,7 +186,7 @@ public class Planet extends UnlockableContent{
                 sum += 2f;
             }
 
-            sector.baseCoverage = sector.preset == null ? Mathf.clamp(sum / 5f) : Mathf.clamp(sector.preset.difficulty / 10f);
+            sector.threat = sector.preset == null ? Mathf.clamp(sum / 5f) : Mathf.clamp(sector.preset.difficulty / 10f);
         }
     }
 
diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java
index fe1d861f0f..dd44b1d74d 100644
--- a/core/src/mindustry/type/Sector.java
+++ b/core/src/mindustry/type/Sector.java
@@ -2,6 +2,8 @@ package mindustry.type;
 
 import arc.*;
 import arc.func.*;
+import arc.graphics.*;
+import arc.math.*;
 import arc.math.geom.*;
 import arc.struct.*;
 import arc.util.*;
@@ -28,7 +30,7 @@ public class Sector{
     public SectorInfo info = new SectorInfo();
 
     /** Number 0-1 indicating the difficulty based on nearby bases. */
-    public float baseCoverage;
+    public float threat;
     public boolean generateEnemyBase;
 
     public Sector(Planet planet, Ptile tile){
@@ -54,6 +56,15 @@ public class Sector{
         }
     }
 
+    /** Displays threat as a formatted string. */
+    public String displayThreat(){
+        float step = 0.25f;
+        String color = Tmp.c1.set(Color.white).lerp(Color.scarlet, Mathf.round(threat, step)).toString();
+        String[] threats = {"low", "medium", "high", "extreme", "eradication"};
+        int index = Math.min((int)(threat / step), threats.length - 1);
+        return "[#" + color + "]" + Core.bundle.get("threat." + threats[index]);
+    }
+
     /** @return whether this sector can be landed on at all.
      * Only sectors adjacent to non-wave sectors can be landed on. */
     public boolean unlocked(){
diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java
index 87c304e624..c5b1fd9b9c 100644
--- a/core/src/mindustry/ui/dialogs/PlanetDialog.java
+++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java
@@ -153,9 +153,9 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
     public void renderSectors(Planet planet){
 
         //draw all sector stuff
-        if(!debugSelect && selectAlpha > 0.01f){
+        if(selectAlpha > 0.01f){
             for(Sector sec : planet.sectors){
-                if(canSelect(sec) || sec.unlocked()){
+                if(canSelect(sec) || sec.unlocked() || debugSelect){
 
                     Color color =
                     sec.hasBase() ? Tmp.c2.set(Team.sharded.color).lerp(Team.crux.color, sec.hasEnemyBase() ? 0.5f : 0f) :
@@ -389,7 +389,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
         stable.add(sector.save != null ? sector.save.getPlayTime() : "@sectors.unexplored").row();
 
         if(sector.isAttacked() || !sector.hasBase()){
-            stable.add("[accent]Difficulty: " + (int)(sector.baseCoverage * 10)).row();
+            stable.add("[accent]Threat: " + sector.displayThreat()).row();
         }
 
         //TODO put most info in submenu
diff --git a/core/src/mindustry/ui/dialogs/SchematicsDialog.java b/core/src/mindustry/ui/dialogs/SchematicsDialog.java
index 8c99272e89..52f59a190e 100644
--- a/core/src/mindustry/ui/dialogs/SchematicsDialog.java
+++ b/core/src/mindustry/ui/dialogs/SchematicsDialog.java
@@ -283,6 +283,17 @@ public class SchematicsDialog extends BaseDialog{
         Core.scene.setKeyboardFocus(searchField);
     }
 
+    @Override
+    public Dialog show(){
+        super.show();
+
+        if(Core.app.isDesktop()){
+            focusSearchField();
+        }
+
+        return this;
+    }
+
     public static class SchematicImage extends Image{
         public float scaling = 16f;
         public float thickness = 4f;
diff --git a/core/src/mindustry/world/blocks/production/GenericSmelter.java b/core/src/mindustry/world/blocks/production/GenericSmelter.java
index aa61408d67..c96e1018dc 100644
--- a/core/src/mindustry/world/blocks/production/GenericSmelter.java
+++ b/core/src/mindustry/world/blocks/production/GenericSmelter.java
@@ -16,7 +16,7 @@ public class GenericSmelter extends GenericCrafter{
     public GenericSmelter(String name){
         super(name);
         ambientSound = Sounds.smelter;
-        ambientSoundVolume = 0.06f;
+        ambientSoundVolume = 0.07f;
     }
 
     public class SmelterBuild extends GenericCrafterBuild{
