1. 글레바 너무 혐오스럽다.




팩토리오의 DLC에서 추가된 행성들 중 '글레바'라는 행성에서는 기존의 팩토리오의 시스템과는 상당히 다른 이질적인 시스템이 개입을 한다. 다른 행성에서는 금속을 녹이고 가공해서 재료를 만들지만 글레바에서는 유기물들을 이용해서 재료를 만들고 제작을 하는데, 유기물이라는 재료의 특징 때문에 각 아이템마다 '신선도'라는 별개의 특성이 추가로 붙는다. 각 아이템들은 아이템 별로 일정 시간이 지나면 부패하게 되는데, 시간이 지날 때마다 이 신선도라는 수치가 점점 감소하다가 신선도가 0이 되면 완전히 썩어서 부패물질로 바뀌는 방식이다.


이 부패라는 시스템은 글레바의 가장 큰 특징이자 생산라인 설계에서 골머리를 썩게 만드는 뉴비들의 폐사용 진입장벽이다. 글레바에서는 생산 건물들조차 전기가 아니라 '영양소'라는 별도 유기물로 가동시켜야 한다는 점은 둘째치고, 그렇게 만들어낸 결과물조차 재료로 쓰인 유기물들의 신선도에 영향을 받는다는 점은 재료 투입공정 설계를 몇 배나 고민하게 만든다. 쉽게 말해 신선도가 50%인 재료들로 물품을 만들면 신선도가 50%인 결과물이 만들어지고, 썩기 직전의 재료들로 만들면 만들자마자 썩어갈랑말랑한 상태가 메롱인 결과물이 만들어진다는 거다.


때문에 만들어지는 최종 물품의 신선도를 위해서든, 아니면 단순히 썩느냐 마느냐만을 확인하기 위해서든 물품들의 신선도를 관리해줘야하는데, 더 빡치는 점은 자동화 회로로는 신선도를 확인할 방법이 없다는 거다. 신선도가 몇 % 남았는지 부패까지 몇 분 몇 초 남았는지 자동화 회로가 감지를 못하니 '신선도가 몇 % 이상 남은 물품은 제작 재료로 사용하고 부패까지 n분 이하로 남은 물품은 폐기한다' 같은 정밀한 관리는 불가능하고, 재료 생산량을 재료 소비량보다 작게 해서 쌓이지 않게 하거나 썩은 물품을 따로 빼내는 공정을 추가하는 식으로 생산라인을 설계하게 된다. 그러다 어딘가 공정 하나가 막히면 컨베이어에서 똥내날 때까지 썩은 똥덩어리들이 쌓이는 거고.


여기까지만 들어도 아직 글레바에 가본 적 없는 팩붕이들은 세상 막막하게 느껴질텐데, 놀랍게도 여기서 끝이 아니다! 글레바에서 과학팩을 만들기 위해 반드시 생산해야하는 핵심 재료인 '펜타포드 알'은 신선도가 다 떨어지면 얌전하게 부패물질로 바뀌는 게 아니라 그 자리에서 부화되서 깽판을 치기 시작한다. 나우비스에서 나오던 바이터 스피터 같은 애들이 저 멀리 바깥에서 다가오는 게 아니라 공장 한복판에 소환되서 다 때려부순다는 거다. 이런 공장 게임에서 물품을 한두개만 만드는 것도 아니고 몇백 개 단위로 찍어내던 와중에 그 몇백 개 알들이 우르르 부화한다고 생각해보자. 각자 어떤 생각을 했든 대재앙이라는 건 다들 동의할 거다.


그런 대재앙을 불러일으킬 수 있는 아이템이라도 특별취급 같은 건 없이 신선도를 감지할 수 없다는 점은 똑같다. 그러니 다른 아이템들과 동일한 방식으로, 하지만 훨씬 위험한 아이템이라는 걸 고려하면 더 빡세게 공정을 짜야한다. 소비는 10개 이상 할 수 있지만 생산은 7~8개 정도만 하는 식으로 생산량에서 손해를 보거나, 아니면 만들어진 즉시 사용되지 않을 경우 바로 폐기하는 방식으로 만들면 아깝긴 해도 안전하게 생산할 수 있을 것이다. 별 수 있나 부패시간 감지가 안 되는데 좀 손해를 보더라도 이런 식으로라도 만들어야지.



...근데 좀 살펴보니까, 펜타포트 알은 부패시간 측정이 가능할 것도 같은데...?





2. ??? ?? : "수학하는 놈들... 저리 꺼저라! 꺼저!"




윗 문단에서 '결과물은 재료로 쓰인 유기물들의 신선도에 영향을 받는다'라고 썼는데, 몇 개는 예외적으로 다르게 적용되는 생산품이 있다.


보통 재료들을 조합해서 완전히 새로운 결과물을 만드는 조합법의 경우, 즉, 'A + B = C'가 나오는 조합법의 경우 결과물인 C는 재료인 A와 B의 신선도에 영향을 받는다. 그러나 새로운 결과물이 아닌 기존의 재료의 수량을 늘리는 조합법의 경우, 즉 'A + B = 더 많은 A'가 나오는 조합법의 경우 결과물로 나오는 '더 많은 A'는 재료로 쓰인 물품의 신선도와는 전혀 상관 없이 무조건 신선도 100%인 상태로 나온다. 신선한 재료를 쓰든 신선도 절반 남은 재료를 쓰든 수명이 몇 초 안 남은 재료를 쓰든 고정적으로 신선도 100%로 결과물이 나온다는 건데, 기존 재료의 신선도를 고려할 필요가 없고 제작이 완료되는 시점은 회로로 읽어낼 수 있으며 결과물의 신선도가 정확하게 고정되어 나온다면, 이거 계산 회로만 잘 짜면 남은 시간 측정이 가능할 것 같다.




신선도가 다른 아이템들끼리 합쳐지면 해당 아이템들의 신선도의 평균값이 합쳐진 아이템들의 신선도가 된다. 예를 들어 상자 안에 이미 펜타포트 알이 들어있는 상태에서 새로운 팬타포트 알을 집어넣는 상황을 가정해보자. 부패시간이 9분 남은 알이 하나 남아있을 때 신선한 15분 짜리 알을 하나 넣는다면 부패시간이 12분 남은 알 두 개가 될 것이다. 여기에 다시 15분 짜리 알을 하나 넣으면 부패시간이 13분 남은 알 세 개가 될 거다.


위의 식은 나무위키에서 긁어온 평균값을 구하는 공식이다. 저 식에서 n은 평균값을 구하려는 항목들의 총 갯수를 말하는 거고 a는 각 항목들의 값이다. 방금 말한 상황을 위 식에 대입시켜 보면 9분 짜리 알과 15분 짜리 알의 평균값은 a1 = 9분, a2 = 15분, n = 2개이므로 (9 + 15)/2 = 12분이 되는 거고 12분 2개와 15분 1개의 평균값은 a1 = 12, a2 = 12, a3 = 15, n = 3이므로 (12 + 12 + 15)/3 = 13분이 되는 거다.


그럼 여기서 알 갯수가 4개 5개 6개 점점 늘어날 때마다 계속 a4 a5 a6을 하나씩 구해야 하는가? 아니다. 방금 3개짜리 예시에서 a1과 a2가 같은 값이라는 걸 봤을 거다. 상자에 들어간 다음엔 어차피 전부 다 동일한 신선도로 통합되므로 기존에 상자에 남아있던 물품들인 a1부터 an-1까지는 전부 다 동일한 값으로 놓으면 계산이 훨씬 간편해질 것이다. 따라서 위의 식은 아래와 같이 나타낼 수 있다.




음 좋다. 역시 한글이 읽기 편하다. 근데 읽기는 편해졌는데, 아직 회로로 만들기에는 적합하지 않아 조금 더 변환을 해줘야한다.


부패시간(기존)은 고정된 값이 아니라 타이머를 응용해서 실시간으로 계속 값을 변화시키며 상자 안에 있는 실제 알의 부패시간과 최대한 비슷하게 만들어줘야 하는데, 지금 저 공식대로 구현하려면 부패시간(기존)의 값을 완전히 소멸시킨 뒤 새로 계산된 값으로 완전히 변화시켜야 한다. 말로만 들으면 그냥 하면 되지 않나 싶을 텐데, 저 식이 계산되는 4틱~5틱 정도의 시간까지만 값을 계속 유지시키다 계산이 끝나면 새로 계산된 값과 간섭되지 않도록 완전히 초기화시킨 뒤 신규 계산값을 그 자리에 넣는 과정을 회로로 구현하려면 회로구성이 쓸데없이 복잡해진다. 조금 더 쉽게 구현되도록 식을 바꿔보자.


저 식에서 펜타포드 알의 총 수량인 '알 갯수'는 정확히 표현하면 (기존 상자에 들어있던 알 갯수 + 새로 투입되는 알 갯수)로 쓸 수 있다. 기존 식에서는 새로 넣는 알 갯수를 1로 두고 n에서 뺄셈을 했는데 저렇게 별도 항으로 표현하면 뺄셈이 필요없어진다. 이걸 식으로 표현하면




어차피 순수 문과들은 맨 첫 번째 수식의 시그마와 아랫첨자를 보고 문끼야악하면서 다 도망쳤을 테니, 여기 남아있는 사람들은 사칙연산과 분수의 계산법 정도는 전부 알고 있다고 가정하겠다. 혹시 본인이 이과인데 저 수식이 이해가 안 간다면 명예 예체능과 정도로 전직하고 주딱한테 물어보러 가라. 아무튼 주딱은 다 이해함ㅇㅇ.


자, 저렇게 나뉜 식에서 부패시간(기존)을 조금 더 변형해주자.




최종 공식이 나왔다. 변형시키기 전의 공식은 부패시간(기존)과 새로 계산된 값이 완전히 별개였기 때문에 앞서 말했듯 회로로 구현하기 위해서는 유지/초기화/대체를 위해 연산기를 덕지덕지 붙여야했다. 그러나 이번 공식은 부패시간(기존)에 새로 계산된 값을 더하기만 하면 되기 때문에 산술 연산기 하나로 1틱 동안 +연산만 하면 된다.


회로로 구현하기 적합한 수준까지 이론을 세웠으니, 이제 이 이론이 맞는지 확인해보자.





3. 이론 검증하기




우선 적당한 부지에 바이오 챔버를 놓고 펜타포드 알을 제작한다. 투입기와 컨베이어는 사진과 같이 배치했다. 알이 만들어지면 컨베이어를 타고 나오면서 그대로 투입기에 잡혀서 다시 들어가서 제작을 유지시키는 구조다. 남는 알은 컨베이어를 따라 상자에 담길 것이다.




https://gall.dcinside.com/mgallery/board/view/?id=factorio&no=10938


여기에 부패시간(기존)을 계산할 타이머를 설치한다. 타이머가 뭔지 모르는 사람이나 기억이 잘 안 나는 사람은 위에 링크를 참조하자. 원래는 그냥 1을 더하겠지만 이번엔 점점 줄어드는 부패시간을 측정하는 게 목적이므로 타이머 신호를 -1로 맞춰서 타이머가 계속 감소하도록 세팅해준다. 수량 비교기는 t가 0보다 클 때로 맞춰서 시간이 남아있으면 타이머가 작동하고 시간이 전부 떨어져 0이 되면 멈추도록 해준다.


그리고 아직까지 안 도망가고 남아있는 문과든 방금 전직하고 온 명예 예체능과든, 타이머 신호는 t로 맞춰라. 시간 관련된 신호는 t로 설정 안 하면 이과형들이 맴매하러 갈 거다.




타이머 앞에 '부패시간(신규) - 부패시간(기존)'을 계산할 산술 연산기를 추가해준다. 팩토리오에서 1초는 60틱, 새로 만들어지는 펜타포드 알은 부패시간 15분(900초) 고정, 따라서 부패시간(신규)는 900 * 60 = 54000이라는 고정된 상수값을 가진다. 즉, 54000에 타이머의 t신호를 빼주면 '부패시간(신규) - 부패시간(기존)'이라는 공식이 나오게 된다.




알을 만드는 바이오 챔버에서는 '제작법 완료 읽기' 항목에 체크를 해준다. 체크할 경우 설명 그대로 제작이 완료되면 딱 1틱만 신호를 보내준다. 나는 초록색 체크 표시로 신호를 보내도록 설정했는데 저건 그냥 각자 마음에 드는 신호로 설정하면 된다. 그리고 '부패시간(신규) - 부패시간(기존)'을 계산한 산술 연산기와 바이오 챔버를 다른 산술 연산기에 연결해준 뒤 위와 같이 설정해준다. 제작 완료 신호는 각자가 설정한 신호로 1이라는 값을 딱 1틱만 보내준다. 생성되는 펜타포드 알은 2개지만 그 중 하나는 제작 유지를 위해 다시 바이오 챔버로 들어가야 하니 순수 산출량은 1개가 되서 신호와 일치하게 된다.



참고로 바이오 챔버에는 기본적으로 '생산량 +50%' 옵션이 붙어있어 2번 제작할 때마다 1번의 결과물이 추가로 나온다. 이 경우 제작 완료 신호는 2라는 값을 보내준다. 즉, 첫 번째 생산에서는 신호값 1과 함께 알이 2개가 나오고, 두 번째 생산에서는 결과물이 한 번 더 출력되서 신호값 2와 함께 알이 4개가 나와야하는데... 이유는 모르겠는데 2번째 생산에서는 알이 4개가 아니라 3개만 나오더라.


이론상으로는 제작품이 2배가 되서 4개가 나와야하고, 비슷한 조합법을 쓰는 박테리아나 물고기도 정상적으로 각각 8개, 6개로 2배가 되서 나오는데, 왜 펜타포드 알만 2배가 아니라 1.5배가 되는지는 모르겠다. 이게 의도된 건지 버그인지는 모르겠지만, 어쨌든 덕분에 회로작업 하기에는 더 쉬워졌다. 신호값이 1일 때 순수 산출량은 2 - 1 = 1. 신호값이 2일 때 순수 산출량은 3 - 1 = 2. 신호값과 산출량이 일치하므로 별다른 회로 조건을 추가할 필요 없이 그대로 선만 연결해주면 된다. 이렇게 하면 (부패시간 * 새로 넣는 알 수량)을 계산할 수 있다.




산술 연산기를 두 개 추가해주고 그 중 하나에는 '상자의 알 수량 + 새로 넣는 알 수량'을 계산해준 뒤 그 값을 다른 산술 연산기로 보내준다. 다른 산술 연산기에서는 (부패시간 * 새로 넣는 알 수량)의 값도 같이 받은 뒤 그 값을 방금 받은 알 갯수로 나누고 결과값을 타이머에 보내도록 만들면 회로 완성이다. 이제 이 회로가 잘 돌아가는지 결과를 확인해보자.




총 15개의 알을 제작하였으며 이 때의 남은 시간은 13분 59초, 회로의 신호는 50371틱이다. 이를 60으로 나누면 13분 59.516초가 된다. 거의 맞는 것 같긴 한데, 정확한 값이 맞는지는 아직 확인이 안 된다.


조금 더 정밀하게 측정하기 위해 시간을 쭉 당겨서 부패하기 직전인 상태로 만들었다. 부패시간이 1초 단위까지만 표시되므로 오차율은 최대 플마 30틱. 이 30틱 이내의 오차율을 확인하기 위해 실제 부패가 터지는 과정을 촬영하였다.




와오. 완벽하다. 타이머의 값이 0으로 떨어지자마자 바로 알들이 부화하는 장면이다. 이정도면 오차없이 완벽하게 이론 검증에 성공했다고 봐도 될 것이다. 그럼 이론은 맞다는 걸 확인했으니 이제 이걸 실전에서 써먹을 수 있을 정도로 다듬어보자.





4. 방금 건 첫 번째 레슨




그래 뭐 일단 이론이 맞았다는 걸 확인했다는 건 좋은 일이다. 그러나 저 방식은 어디까지나 이론 검증용으로 철저하게 통제된 변인 하에 실험된 거였고, 실제로 적용하기엔 무리가 있다. 일단 이런 공장류 게임에서 누가 공장 하나만 돌리고 누가 상자에 넣기만 하고 빼지는 않을까. 메가베이스까지 갈 것도 없이 평범하게 플레이를 하더라도 기본적으로 10개는 넘는 공장을 돌릴 테고 그 정도로 공장이 많아진다면 상자까지 끌고 오는 경로도 한참 길어질 것이며 무엇보다 쓸려고 만드는 건데 상자에 쌓아두기만 하는 게 아니라 당연히 상자에서 빼기도 할 것이다.


방금 전에 만든 회로는 '공장에서 만들어지자마자' 바로 회로에 해당 사실을 반영시켜 남은 시간을 계산하였다. 이렇게하면 결과값의 신뢰도는 끝장나게 올라가겠지만, 이건 실제로는 '공장에서 만들어진 즉시 1틱 만에 상자로 들어가는' 상황에서나 적합한 회로다. 방금 전 상황에서는 상자에서 알이 빠지는 경우도 없고 상자에 넣어지기까지 충분한 시간 동안 기다릴 수 있었기 때문에 이런 식으로 만들어도 아무 문제가 없었지만, 실제로는 공장에서 신호를 보내 회로에 반영된 후 기나긴 컨베이어를 타고 오는 도중에 상자에서 물품이 빠져나가 회로 상의 수량과 실제 수량 간의 차이를 만들어 오차값을 크게 만들어낼 것이다. 만약 분배기를 써서 만든 걸 다른 라인으로 보내기라도 한다면 아예 회로의 의미 자체가 없어지는 수준이 될 수도 있다.


따라서 실제 게임에서 발생할 이런저런 상황을 고려해서 적용시키려면 어쩔 수 없이 결과값의 신뢰도는 약간 낮아지더라도 '만들어진 시점'이 아니라 '상자에 넣어진 시점'에 회로에 해당 사실을 반영시켜야 한다.




우선 상자 옆에 저런 식으로 산술 연산기와 수량 비교기를 설치한다. 팩토리오에서 각 조합기들은 결과값을 계산하는데 1틱의 시간이 걸리는데, 그 틱차이를 이용헤서 상자에 내용물이 감소했을 때는 무시하고 증가했을 때만 딱 1틱만 신호를 보내주게 만들 수 있다. 어떻게 저런 게 가능한지는 예전에 쓴 글에 설명해놨으니 링크로 대체한다. 4번 문단의 벨트 위에서 뱅글뱅글 도는 짤 밑에 써놨다,


https://gall.dcinside.com/mgallery/board/view?id=factorio&no=82687


저렇게 배치하면 펜타포드 알이 상자에 들어가는 바로 그 순간을 포착해서 신호를 보낼 수 있게 된다. 이 때 결과값으로 보내는 신호는 아까 전에 바이오 챔버의 생산 완료 신호와 같은 신호를 써서 기존 회로를 그대로 사용할 수 있도록 했다.




그리고 기존의 '상자의 알 수량 + 새로 넣는 알 수량'을 계산하던 산술 연산기는 덧셈을 곱셈으로 바꿔준다. 왜냐하면 알이 이미 상자에 들어가서 합쳐진 이후에 신호를 받도록 바뀌었기 때문에 상자 안의 알 갯수는 이미 '새로 넣는 알 수량'이 합쳐진 값이기 때문이다. 그러므로 상자 안의 알 수량을 1틱 동안 신호값 1과 곱해주는 방식으로 변경해야 한다.



만들어진 직후의 알의 부패시간은 54000틱인데, 상자에 넣어지는 시점의 알의 부패시간은 얼마인가? 알이 만들어진 직후부터 상자에 들어가기까지 시간을 측정한 결과 사진과 같은 형태에서 각각 392, 440, 488, 536, 584틱이 나왔다. 어떻게 시간을 측정했는가에 대해서는 별도 글로 작성할테니 참고하고, 결과값을 보면 빨간 컨베이어 기준 3칸이 떨어질 때마다 48틱씩 시간이 증가하는 형태가 나왔다. 저 값들에서 평균값이자 중간값인 488틱을 기준으로 계산하면 상자에 넣어지는 시점 기준 알의 부패시간은 평균적으로 54000 - 488 = 53512틱일 것이다.




그러므로 아까 부패시간(신규)의 값으로 설정한 54000틱을 53512틱으로 설정해준다. 이 값은 고정된 값이 아니라 사람따라 시설따라 각자 다 값이 다르게 나온다는 점을 잊지 말자. 이번 문단에서 나온 형태의 시설에서는 알이 도착하기까지 평균적으로 488틱이 걸리기 때문에 값을 53512틱으로 설정한 것이다.




여기서 잠시 회로에서 벗어나 투입기 쪽으로 눈을 돌려보자. 아까 이론 검증하던 시절에 '새로 넣는 알 수량'은 생산 건물에서 회로로 정확한 값을 직통으로 쏴줬기에 회로값만 받아서 계산하면 됐었다. 그러나 실제 상황에서는 '이론상 정확한 값' 같은 건 없고 투입기로 넣는 실제 수량을 반영해야 한다.


투입기에서 '손 내용물 읽기'를 체크한 후 적당한 곳에 수량 비교기를 추가해 회로로 연결해준다. 그리고 그 수량 비교기의 출력과 입력을 연결시켜 메모리 셀로 만들어준다. 메모리 셀이 뭐냐면 출력된 값을 그대로 입력으로 전송해 한 번 입력된 값을 유지시키는 회로라고 생각하면 된다. 이 때 기존 회로와 합선되서 오류를 발생시킬 수 있으므로 입력과 출력을 연결해주는 선은 투입기와 연결된 선과 다른 색을 써주자.


다음으로 메모리 셀 초기화 조건으로 처음에 만들었던 1틱 차이 상자 내용물 증가 감지 회로와 메모리 셀의 입력 칸을 연결해주고 증가 감지 회로에서 신호를 보내면 회로가 초기화되도록 설정해준다. 이렇게 하면 투입기가 물건을 집고-놓은 직후 사이에만 신호가 유지되어 다음 물건을 집을 때 다시 새로운 신호를 받을 수 있다.




그렇게 유지한 신호를 아까 바이오 챔버에서 신호를 받아 곱해주던 부분에서 제작 완료 신호가 들어가던 부분에 입력해주자.




마지막으로 타이머와 상자를 연결한 후 내용물이 전부 소모되었을 때를 대비한 AND 조건문을 하나 추가해주면 회로 조정 완료다. 이제 다시 결과를 보자.




펜타포드 알을 소모할 농업과학팩 생산용 바이오 챔버를 추가해주었다. 이렇게하면 지속적으로 소모가 되기는 하는데 생산량이 소비량보다 많아 결국 상자 안에 쌓이게 될 것이다.



(만드는 중...)




적당히 시간이 지난 후 결과물이다. 상자 안의 알의 부패시간은 14분 46초이며 회로의 신호는 53174틱이다. 이를 60으로 나누면 14분 46.233초이다. 정확도가 떨어질 것을 염려하였으나 여전히 미친 수준의 정확도를 확인할 수 있었다. 이 정도면 '상자에 넣어진 시점'에 회로값을 반영시켜도 전혀 문제가 없을 것이다.



자, 그러면 충분히 쓸만한 결과를 확보했으니 이렇게 만들어 둔 회로를 그대로 쓰면 되는가 하면...





5. 저 그냥 문과할래요




아직 남았다. 방금 니들 머릿 속에서 떠오른 문과스러운 나약한 생각은 버리고 다음 단계로 나아가자.



펜타포드 알은 아이템 칸 하나에 20개까지 담긴다. 그 이상 넣으려 하면 다른 칸에 담기게 되는데, 이렇게 다른 아이템 칸에 담긴 아이템들은 부패시간도 별도로 진행이 된다. 여태까지 20개 미만의 갯수로만 실험을 진행했기 때문에 이런 것까진 고려하지 않았는데, 실제로는 20개만으로는 한참 모자르고 당연히 훨씬 더 많은 칸을 써야한다. 겨우 20개 가지고 회로 붙여가며 타이머 돌릴 바엔 그냥 포탑 몇 개 세우고 알 터진 거 잡아가면서 진행하지, 실용적으로 쓸 수 있을 정도로 만드려면 칸이 나뉘고 부패시간이 따로 돌아가는 것도 반영을 해야 할 것이다.




맨 처음에 만들었던 타이머에선 일정신호기에서 -t라는 신호 하나만 보내게 만들었지만, 이번에는 하나가 아니라 48개의 신호를 보내게 하자. 그렇다. 상자칸 하나당 신호 하나씩 보내는 거다. 혹시 벌써부터 품질작을 짱짱하게 해서 상자칸이 60개 70개가 넘어가는 사람은 사용을 원하는 칸만큼 신호를 추가해주자. 아니면 48칸조차 많다고 생각하는 사람들은 사용을 원하는 칸까지만 상자의 공간을 막아준 뒤 해당 칸까지만 신호를 추가해줘도 된다. 혹시 120칸짜리 전설 품질 상자로 따라해보려는 사람들은.... 뭐.... 힘내라.




https://gall.dcinside.com/mgallery/board/view/?id=factorio&no=87544&exception_mode=recommend&search_head=20&page=2


그리고 이젠 t신호 하나만 쓰는 게 아니라 여러 신호를 계속 바꿔가며 써야하니, 여태까지 단일 신호로 설정한 부분을 전부 와일드카드 '각각'으로 바꿔주자. 와일드카드가 뭔지 모른다면 끝내주게 설명 잘 해놓은 설명 글이 위에 있으니 한 번 읽고 오자.


이 때, 산술 연산기에서 양 변 모두 와일드카드를 쓸 때는 초록선과 붉은 선의 순서를 주의해서 설정해주자. 덧셈이나 곱셈은 순서 상관 없이 그냥 아무렇게나 해도 되지만 뺄셈이나 나눗셈은 뭐를 뭐에서 연산하는지 순서가 중요하므로 선의 색과 연산 순서를 신경써서 봐야한다.




그리고 기존 회로와 좀 떨어진 곳에 일정 신호기를 또 추가한 뒤 역시 사용을 원하는 칸만큼 신호를 추가해주자. 방금 마이너스 신호로 설치한 건 타이머 용도였고, 이번 건 상자 내용물 계산용 회로이므로 양수로 설정을 해준다. 48칸 전부 쓸 거면 48개 신호를 설정하고 20칸만 쓸 거면 20개만 설정하고 60개 70개 쓸 거면 그만큼 설정하고 전설 상자 120칸 쓸 거면 힘내고.


상자에 직접적으로 회로를 연결하면 상자 안의 아이템의 '총 수량'만 읽어낼 수 있고 아이템들이 몇 칸을 차지하는지, 각 칸 별로 부패시간이 얼마나 남았는지는 감지를 못하기 때문에 상자에서 아이템 수량을 직접적으로 읽어내는 게 아니라 회로 계산으로 지금쯤 상자 안에 아이템이 몇 개가 있겠거니 하고 간접적으로 계산을 한 뒤 그 아이템들의 신선도가 각 칸 별로 얼마쯤 남았을 지를 계산하는 방식을 써야 한다.


방금 만든 타이머용 일정 신호기에서 * -1 하는 식으로 기존 신호기를 써도 되긴 한데, 그러면 산술 연산기를 하나 더 써야하고 무엇보다 회로 연결을 기이이일쭉하게 연결해줘야 하므로 그냥 나는 새로 신호기 하나 더 만들어서 연결해줬다.




거기다 수량 비교기 두 개를 연결해 다음과 같이 설정해준다. 저 출력값에 있는 초록색 와일드카드는 '조건을 만족하는 신호 중 가장 첫 번째의 신호'를 출력해주는 와일드카드다. 상자에 물품을 집어넣으면 당연하게도 맨 첫 번째 칸부터 차례대로 쭉쭉 채워져가므로 첫 번째 칸이 전부 꽉 차면 두 번째 칸의 신호를, 두 번째 칸이 꽉 차면 세 번째 칸의 신호를 차례대로 보내준다.


그럼 신호기를 하나만 써도 될 것 같은데 왜 굳이 다른 설정으로 하나 더 넣었냐면, 아예 비어있는 새로운 칸들 중에서 아이템을 넣을 때는 무조건 그 중 맨 앞의 칸에 물품을 집어넣지만, 아직 내용물이 덜 찬 칸이 하나라도 남아있다면 그 앞에 얼마나 많은 빈 칸이 남아있던 상관 없이 덜 찬 칸에 내용물을 채우는 걸 우선하기 때문에 '아직 용량이 남은 칸이 있는 지 확인하고' → '없으면 빈 칸들 중 가장 앞의 칸에 넣기 위해' 신호기를 두 개 써서 각각의 신호를 감지해주는 것이다.




그리고 여기서 여태까지 한 번도 사용해본 적 없는 새로운 조합기인 선택 선별기를 소개한다. 2.0버전 이전부터 있던 기존의 다른 조합기들과는 다르게 이놈은 2.0버전 이후에 새로 추가된 조합기인데, 기존 조합기들로는 불가능했던 여러 기능들을 구현할 수 있게 해준다.


'작동 모드'에서 여러 기능들 중 어떤 기능들을 쓸 지 선택할 수 있는데, 첫 번째 기능인 '입력 선택' 모드는 입력된 신호들을 크기 순서대로 정렬해주는 기능이며 인덱스는 그 신호들 중 '몇 번째로 큰/작은 신호를 출력해줄지' 선택해주는 숫자다. 내림차순은 큰 순서대로, 오름차순은 작은 순서대로 정렬해주며 인덱스가 0이면 정렬된 신호들 중 가장 첫 번째 신호를 출력해준다. 왜 1이 아니라 0이 첫 번째 신호를 출력해주냐면 컴퓨터 프로그래밍에서 배열이나 인덱스를 나열할 때 '0번째'부터 인식하기 때문에 그런 거라고 생각하면 된다.


이를 통해서 위의 수량 비교기 두 개에서 내려온 신호들 중 우선 순위를 정해서 출력할 수 있게 된다. 48개의 칸들 중에서 비어있는 칸은 1, 내용물이 들어있는 칸은 1+들어있는 수량 만큼의 신호를 발생시키는데, 내용물이 들어있는 칸은 당연히 1보다는 큰 신호를 출력하므로 크기순 정렬에서 '0순위'가 되어 해당 신호가 출력된다. 만약 모든 칸들이 비어있거나 꽉 차있다면 신호를 아예 발생시키지 않아 비어있는 칸들 중 가장 첫 번째 칸의 신호만 유일하게 받게 되므로 그 신호를 그대로 출력한다. 이를 통해 어떤 칸의 신호를 주고 받을지 우선 순위를 정해 출력할 수 있게 된다.




선택 선별기의 출력부를 산술 연산기와 수량 비교기에 각각 연결해준다. 산술 연산기는 21 - '각각' = (아이템 칸에 할당한 48개의 신호와 겹치지 않는 신호 아무거나) 라는 식으로 설정해준다. 펜타포드 알은 한 칸 당 20개까지 쌓이는데, 맨 위에 일정 신호기에서 각 칸 별로 1의 신호를 계속 출력하고 있으므로 빈 칸은 1, 꽉 찬 칸은 21로 실제 수량보다 +1 시킨 값을 출력할 것이다. 위의 21 - '각각'은 각 칸에서 얼마나 더 아이템을 채울 수 있는지 계산한 값이다. 이 출력값을 상자에 채워넣는 쪽 투입기에 연결시킨다.


투입기에서는 '묶음 크기 설정'을 체크한 뒤 방금 위에서 설정한 신호로 맞춰준다. 이렇게 하면 물품이 18개 19개 쌓여있을 때 3개식 더 넣어서 20개+다른 칸에 1~2개 삐져나오는 일 없이 정확하게 한 칸에 20개까지만 딱 넣고 다음 칸으로 넘어갈 수 있게 된다. 한두개 삐져나오는 것까지 다 감안해서 반영하도록 회로를 짜면 안 그래도 더럽게 복잡한 회로가 한층 더 복잡해지므로 회로 단순화를 위해 이렇게 설정했다.


수량 비교기는 입력된 값의 크기만 1로 바꿔서 출력해주는 역할이다. 이건 뭐 별도로 설명할 게 없으니 넘어간다.




선택 선별기의 신호 크기를 1로 맞춰주는 회로와 기존에 만들었던 메모리 셀을 산술 연산기에 연결해준 뒤 곱셈 연산을 해준다. 이렇게 하면 '새로 넣는 알 수량'을 각 신호 별로(각 칸 별로) 분리시켜서 계산할 수 있다. 이 회로를 처음에 만들었던 (신규 시간 - 기존 시간) * 새로 넣는 알 수량 계산 회로에 연결해준다.




또한 산술 연산기를 하나 더 추가해준 뒤 여기에도 연결해준다. 그리고 1틱 차이로 상자 내용물 증가를 감지하던 회로도 여기 연결해주고 곱셈 연산을 시켜준다. 이러면 상자에 물품이 추가될 때마다 '얼마나 추가됐는지' 신호를 보내주는 회로가 된다.


그리고 그 위에 메모리 셀을 하나 더 만든 뒤 입력 값은 방금 만든 회로에, 출력 값은 두 번째 일정 신호기와 연결된 회로들에 연결해준다. 이번 메모리 셀은 상자의 아이템 칸 별로 아이템이 얼마나 들어있는지 감지하고 기억해주는 역할이고 여기에 상자에 아이템이 들어갈 때마다 몇 번째 칸에 얼마나 들어갔는지 입력해주면 상자의 아이템 수량과 일치시킬 수 있다. 이번 메모리 셀은 앞으로 부를 일이 많을 테니 '인벤토리 메모리 셀'이라고 별도로 이름을 붙여주도록 하겠다. 그리고 출력을 상자에 빈 칸/용량이 남은 칸을 감지해주는 회로에 연결시켜주면 위의 회로들도 정상작동을 시킬 수 있게 된다.




인벤토리 메모리 셀과 선택 선별기에서 크기 1짜리 신호만 뽑아내도록 만든 회로를 연결해서 곱셈 연산을 시켜주면, 해당 신호(해당 아이템 칸)의 '현재 수량'만 뽑아낼 수 있는 회로가 된다. 곱하는 것도 '각각', 곱해지는 것도 '각각'인 '각각' X '각각' 연산은 출력이 인식되지 않는 신호는 크기를 0으로 간주하고 계산한다. 예를 들어 녹색 선에서 A = 3, B = 5, C = 7, D = 9라는 신호가 들어오고 빨간 선에서 C = 1이라는 신호만 들어온다고 가정하자. 둘을 '각각' 연산으로 곱할 경우 빨간 선에서의 신호는 A = 0, B = 0, C = 1, D = 0이라는 신호로 인식한 뒤 녹색 선에서의 각 신호들과 곱해서 C = 7이라는 신호만 남겨놓는다. 해당 방식으로 수많은 신호들 중 출력을 원하는 신호만 뽑아낼 수 있다.


그리고 이 값과 '새로 넣는 알 수량'의 값을 더해주면 해당 신호의 현재 수량 + 새로 넣는 수량 = 총 수량이 계산되어 남은 시간을 계산하는 수식의 분모 값이 된다. 그 값을 기존에 분모를 계산하던 회로에 연결해주고 기존의 알 신호를 '각각'으로 바꿔주면, 이걸로 상자에 알을 넣을 때의 값을 계산해주는 회로는 완성된 거다. 잠깐 한 숨 돌리고, 이제 상자에 알을 뺄 때 값을 계산해주는 회로로 넘어가자. 걱정마라. 빼는 거 계산하는 회로는 넣는 거 계산하는 회로보다 훨씬 간단하다. 




선택 선별기 두 개를 설치해준 뒤 타이머의 출력 신호와 연결해준다. 작동 모드는 둘 다 똑같이 '입력 선택' 모드로, 하나는 오름차순 하나는 내림차순으로 설정해준다. '입력 선택' 모드는 신호들을 크기 순으로 정렬해주는 모드라고 했는데, 이렇게 하면 타이머의 남은 시간이 가장 큰(=가장 신선한) 신호와 가장 작은(=가장 부패한) 신호를 찾아서 뽑아낼 수 있게 해준다.




그 신호들의 크기를 -1로 바꿔준다. 이번에는 상자에 넣는 게 아니라 빼는 거니 인벤토리 메모리 셀에서 값을 빼기 위해 처음부터 음수로 설정해주었다. 그 값을 산술 연산기에 연결해주고 위와 같이 설정해준다.




투입기들에는 '부패 우선순위'라는 별도의 옵션이 붙어있다. 이름 그대로 '신선한 것부터'를 선택하면 집어들 수 있는 물품들 중 가장 신선도가 높은 아이템들을 우선적으로 집어들고 '부패한 것부터'는 그 반대로 집어든다. 아이템 제작용 재료들은 신선한 물품들을 사용하는 게 좋으니 '신선한 것부터'를 체크하고 방금 선택 선별기에서 '내림차순 정렬'로 설정한 신호를 받는 산술 연산기와 연결해준다. 그리고 산술 연산기의 출력값은 인벤토리 메모리 셀에 연결해주면 투입기가 집어든 만큼 메모리 셀에서 값이 빠져나갈 것이다. 손 내용물 읽기도 체크하는 거 잊지 말자.


옵션 중 '활성화/비활성화'와 '묶음 크기 설정'도 체크되어 있는데, 이건 아직 설명 안 한 거고 아래에서 설명할 거다. 니들이 멍 때리다가 안 읽고 넘어간 게 아니니 괜히 스크롤 위로 올리려서 확인하지 말고 그대로 읽으면 된다.




여기서도 한 칸에 물품이 1~2개 밖에 안 남았는데 3개씩 빼서 다른 칸 물품까지 집어들어 회로 아작나는 일이 없도록, 넣는 쪽 투입기와 똑같이 '묶음 크기 설정'을 체크해준 뒤 회로로 값을 보내줘야 한다. 이 때 인벤토리 메모리 셀에서 해당되는 신호만 뽑아줘야 하는데, 밑에 회로에서는 그냥 1이 아니라 -1을 보내도록 설정했기 때문에 ''각각' X '각각' 연산을 하면 음수가 나와서 묶음 크기 신호로 쓸 수가 없게 된다.


산술 연산기를 하나 더 추가한 뒤 -1을 다시 곱하게 해서 양수로 만들 수도 있지만, 굳이 회로를 하나 더 추가할 필요 없이 그냥 곱셈 말고 AND 연산을 해버리면 -1과 곱해도 양수로 신호를 뽑아낼 수 있다. 팩토리오의 산술 연산기로는 일반적인 사칙연산 말고도 AND, OR, XOR 연산을 할 수 있는데 해당 연산이 어떻게 이뤄지는지는 별도로 이미지로 표시했다. 잘 모르겠으면 주딱한테 물어봐라. 아무튼 주딱은 다 알고 있음ㅅㄱ.


중요한 건 -1과 AND 연산을 하면 그냥 1과 곱셈 연산을 한 것과 같은 결과를 얻을 수 있다는 거다. 이렇게 인벤토리 메모리 셀에서 '가장 신선한' 신호를 뽑아낸 뒤 투입기에 묶음 크기 신호로 보내주자.




그리고 별도로 타이머를 하나 더 추가해준 뒤 상자에 넣는 쪽 투입기와 1틱 차이로 상자 내용물 증가를 감지하던 회로를 입력에 연결하고 출력을 빼는 쪽 투입기에 연결해준다. 상자에 넣어졌다는 신호가 한 번이라도 오면 t가 2가 되고, t가 1보다 커졌으므로 상자 신호와는 상관없이 타이머가 계속 돌아가다가, 투입기가 알을 집으면 다시 초기화되는 구조다. 팩토리오의 각 회로들은 결과값을 계산하는데 1틱의 시간이 걸리는데, 상자에 펜타포드 알이 넣어진 후 인벤토리 메모리 셀에 해당 수량이 반영될 때까지 각 회로들을 지나오느라 대충 4~5틱 정도 걸린다. 그 사이에 투입기가 상자에서 내용물을 빼가면 회로에 반영되기 전에 상자의 수량이 달라져 오류를 일으킬 수 있으므로 알이 상자에 넣어진 후 약간 시간이 지난 후에 물품을 빼도록 설정한 것이다.




마지막으로 상자에서 오래된 알들을 빼는 투입기를 추가해준다. 타이머와 투입기들을 연결한 뒤 타이머 신호들 중 남은 시간이 5분(18000틱) 미만인 신호가 하나라도 있으면 '부패한 것부터' 빼도록 설정해준다. 이 때, 괜히 한두개씩 빼다가 새로 투입되는 신선한 알들과 섞이면 5분 몇십초짜리 쓰기도 버리기도 애매한 알들이 양산될 수 있으므로 묶음 크기를 10개로 설정한 초록 투입기 2개를 동시에 써서 부패하기 직전의 알들을 한 번에 뺄 수 있도록 해준다. 손 내용물 읽기도 체크하는 거 잊지 말자.


자, 이걸로 모든 회로가 완성되었다.




해당 회로들의 전체적인ㅋ 모습잌ㅋㅋ닼ㅋㅋㅋㅋㅋㅋㅋ엌ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ시밬ㅋㅋ배선 꼬라지 봐랔ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ


모습을 보니 멘탈 나갈 거 같다. 니들 멘탈 말고 내 멘탈이 나갈 거 같다. 난 분명 조합기 10개 이하로 쓰는 누구나 따라할 수 있는 실용적인 회로를 목표로 글을 쓰기 시작했는데 완성해보니 이건 실용적이 아니라 '팩토리오에서는 회로를 이용해서 이딴 짓도 가능하답니다!'하는 진기명기 차력쇼 같은 느낌이 난다. 2번 문단에서 굳이 복잡한 수식 줄줄이 적어가면서 설명하고 굳이 적을 필요 없는 3번4번 문단 자세히 적은 것도 원리를 이해하고 따라해보라는 의도였는데 이건 문과 이과 떠나서 공과를 데려와도 더럽다고 뱉을 거 같다. 에이 맛없어.




https://factoriobin.com/post/8irzyn


나름대로 깔끔하게 정리해봤다. 여전히 더럽다. 멘탈 아프다. 슬프다. 힝힝.


오래된 알들을 배출하는 부분에 컨베이어를 깔아준 뒤 난방 탑과 연결하여 소각되도록 하였다. 알을 소비할 과학팩 생산시설을 3개로 늘리고 사진에선 보이지 않는데 알 생산시설도 5개에서 10개로 늘렸다. 그리고 여태까지 만든 회로들도 한쪽에 몰아서 정리를 해줬다. 정리한 회로들은 청사진으로 만들어서 올려놨으니 써 볼 사람들은 복사해서 가져가면 된다. 솔직히 만든 내가 보기에도 제작한 당사자 아니면 따라하기 빡셀 거 같아서 그냥 청사진으로 한 방에 올려놨다.


위 사이트에서 문자열을 카피한 뒤 게임 하단부의 '문자열 가져오기'를 누르고 문자열을 붙여넣으면 청사진을 사용할 수 있다. 다만 로보포트와 건설로봇이 있어야 정상적으로 붙여넣을 수 있으니 나우비스에서 건설로봇들을 가져오는 걸 추천한다. 글레바에선 만들기 빡세다.




Ctrl + X 를 누르면 회로 설정과 배선 연결을 그대로 유지한 채로 위치만 옮길 수 있다. 각자의 공장 상황에 맞춰 형태를 옮길 수 있으니 참고하자. 물론 당연히 이것도 로보포트와 건설로봇이 있어야 한다. 옮길 때 각 요소들이 너무 멀어져서 선이 끊어지지 않게 조심하자. 선 끊어놓고 작동 안 된다 그러면 나도 할 말이 없다.


그럼 이 정도면 설명은 충분히 다 한 것 같으니 마침내 결과를 보도록 하자.



(으아아아아아 64배소오오오오옥)


원래는 상자를 꽉 채운 모습을 보여주고 싶었는데 펜타포드 알 생산시설이 10개 밖에 안 되다보니 상자가 다 차기도 전에 처음에 들어간 알의 부패시간이 5분 미만으로 떨어져서 소각로로 빠져서 일정 갯수 이상으로는 차오르지 않는 모습이다. 조금 아쉽긴 한데, 부패 직전의 알들을 빼내는 과정이 잘 작동한다는 뜻이니 오히려 이 모습이 보여주기는 더 좋겠다 싶어서 별도로 조정은 안 하고 그대로 가져왔다.


중요한 건 상자가 꽉 차냐 안 차냐가 아니라 시간 측정이 제대로 되는지 안 되는지다. 상자를 꽉 채우더라도 실제 부패시간과 회로의 부패시간이 차이가 엄청나게 난다면 그건 개판났다는 뜻이고 상자를 반도 못 채우더라도 시간 오차율이 작다면 제대로 동작하는 회로라는 뜻이다. 그럼 실제 시간과 회로 시간은 얼마나 차이가 나는가 하면...




아주 좋다. 총 16칸의 아이템 칸에서 모두 1초 미만의 오차율을 보이며 거의 완벽하게 측정에 성공했다. '실제 남은 시간'은 1초 단위까지만 나와서 소수점 시간까지는 측정을 못했지만 모든 측정 시간이 1초 미만의 오차율이라는 걸로 추측했을 때 전부 플마 0.5초 이내의 오차로 회로가 성공적으로 동작한다는 뜻이니 드디어 이 빌어먹을 회로의 완성을 선언할 수 있게 되었다. 여기까지 읽은 모두들 수고했다. 물론 내가 제일 수고했다. 나한테 박수 한 번 처줘라. 짝짝짝





6. 마치며



일주일 동안 게임 진도도 안 나가고 생활 패턴도 망가트려 가면서 이 글만 붙잡고 있었다. 여태까지 쓴 글 중에 역대급으로 오래 걸린 글이었다. 어우 빌어먹을 이제야 좀 개운하게 자겠네.



보통 이런 글을 쓸 때는 완성된 회로를 며칠 동안 쓰면서 검증한 다음에 글을 쓰는 게 아니라 '이런 기능을 가진 회로가 있으면 게임 편하겠는데?' 하는 생각이 든 시점부터 회로 작성과 동시에 공략글을 쓰면서 글과 회로를 동시에 완성한 뒤 게임하면서 회로가 필요한 부분이 있으면 내가 쓴 글을 참고하면서 진행하곤 했다. 무슨 뜻이냐면 나도 이 글을 처음 쓰기 시작할 시점에는 완성본이 저따위로 복잡하게 나올 거라는 예상을 못했다는 뜻이다.


4번 문단까지는 머릿속에서 예상한 대로 착착 진행됐는데, 5번 문단부터는 뭐가 계속 안 되고 삑사리나고 인식을 못하고 에러 터지고 하면서 멘탈에 금이 가더니, 고쳐나가면서 점점 복잡해지는 꼴을 실시간으로 보면서 멘탈이 야금야금 갉아먹히더라. 일주일이라는 시간은 멘탈 나가서 가만히 누워있던 시간도 포함된 시간이다. 아직도 예상과 다르게 너무 지저분하게 나와서 슬프다. 힝힝힝.


자기가 팩토리오에서 회로 좀 만진다 하는 사람들은 혹시 저 회로 최적화가 가능하다면 손 좀 봐주길 바란다. 저작권 같은 거 따질 생각 없으니까 문과든 이과든 아무나 달라붙어서 간단하게 만들어주면 내가 하루만에 개추 버튼 657184587번 눌러준다. 물론 얼마나 많이 누르든 개추는 하루에 한 번만 가능하다. ㅋ.


마지막으로 저렇게 회로 덕지덕지 붙여가면서 게임하는 게 더 불편하다면 그냥 기존의 방식대로 생산량과 소비량을 적절히 조절해서 회로 없이 그냥 사용해도 된다. 늘 그렇듯 저런 회로를 써가면서 진행하는 게 필수는 아니다. 어떤 방식이든 본인이 즐기면서 할 수 있는 방식이 가장 좋은 공략이니, 이번 글은 그냥 회로로 차력쇼 한 번 봤다고 치고 넘어가도 된다. 모두 즐거운 팩토리오 해라.