Renpy의 버전이 7.x로 넘어간지 오래되었다. 하지만 여전히 Python특유의 성능은 발목을 잡기는 하지만 2D 게임 특성상 기기의 성능이 좋아지면 당연히 요구치가 낮아지니까 크게 문제 되지 않을 수도 있다. (하지만 일부 효과가 가득한 게임은 스마트폰에서 문제가 많이 일어난다. 심지어 무한루프에 빠지는 경험도 했다.)
그리고 일부 게임은 여전히 6.xx를 사용하고 있고 이 버전은 안드로이드 포팅이 상당히 힘들다.
우선 필요한 것. OpenJDK-8 이전버전도 안 되고 이후 버전도 안 된다. 이것을 사용해야 한다. 왜냐하면 android-sdk-23을 사용하기 때문인데 이건 자그마치 안드로이드 6.0이 나오면서 나온 SDK다. 당시 Java는 8버전이 LTS로 지원되고 있었기에 해당 버전을 써야한다.
우분투에서는 openjdk-8-jdk 패키지로 설치가 가능하다. 필요하다면 oracle에서 받아서써도 되지만 굳이 그럴 필요는 없다. (라이센스 문제가 복잡해진다.)
그다음 Google관련 툴에서 에러가 엄청나게 나온다.
처음 안드로이드 빌드에 들어온 사람은 Install SDK & Create Keys에서 처음 보는 에러를 경험하게 된다.
원래는 렌파이에서 SDK설치가 원할했지만 구글에서 SDK들을 정리하다보니 조금 복잡해져버렸다. 그래서 Android Studio를 설치해서 SDK복사를 해와야 한다.
우선 Android Studio를 설치하고 SDK Manager를 실행한다.
More Actions를 누르면 SDKManager가 있다. 이것을 실행하자
SDK Platforms 탭에선 23버전 (Android 6.0)을 설치하고 그리고 제일 중요한 SDK Tools 탭에서 Google Play APK Expansion library 와 Google Play licensing Library 두가지를 체크한뒤에 Apply를 누르자.
그리고 SDK가 설치된 곳으로 가자 SDK Manager에서 위에보면 Android SDK Location이라고 있다. 이것을 보면 된다.
그다음 extras 폴더를 복사해서 Renpy가 설치된 곳/rapt/android-sdk-r23 에 복사한다.
저 extras 폴더 안에 구글 라이브러리들이 들어있어야 한다.
그리고 또 수정을 해야 한다. 복사된 extras 폴더 안에 google로 들어가면
market_licensing market_apk_expansion 이렇게 되어있다. 이것을
play_licensing play_apk_expansion 으로 바꿔준다.
이제 Renpy를 다시 켜면 활성화가 안 되어있던 Configure가 활성화 되어있다. 빌드까지 하고 나면 rapt/bin안에 설정한이름-release.apk가 짠하고 있을 것이다. 원래는 Build & Install 하면 디버깅설정된 휴대폰에 설치까지 되어야 하는데 가끔 안 되는 경우가 있다. 그때는 이 apk를 가지고 사이드로딩을 시도하면 될 것이다. 의외로 ADB관련 오류도 잦은 편이다. (특히 케이블이 불량인 경우)
왜 이딴 작업을 했냐고 물어보면... 의뢰가 들어와서 한창 삽질을 했다. 자바 버전으로인해 오류가 날때는 정말....
그리고 지속적인 구버전 오류가 날 때는 .android.json파일을 수정해서 target과 minsdk를 수정할 필요가 있다. 특히 이제는 사용되지 않는 4.0 아이스크림 샌드위치용 코드가 문제를 일으킬 수 있으니 애초에 지원 안 됨을 못 박는게 더 나을 수 있다.
하지만 제일 좋은건 호환성에 전혀 문제가 없다면 렌파이 버전도 함께 올리는 것. 그래야 최신 폰 대응이 쉬워진다.
추가로 안드로이드는 rpa포맷 지원이 안 되는듯. rpa를 풀어서 game폴더에 위치해야 정상 구동이 가능하다. 이것 때문에 이틀동안 밤샘한거 생각하면 어휴...
요즘은 하도 버추얼 유튜버라는게 많아서 버추얼 유튜버가 되기위한 도구들이 많이 개발되었는데 (주로 일본에서) 이 버추얼 유튜버라는게 워낙 준비비용이 많이 들다보니 어떻게든 저렴하게 만들고자 많은 것들이 개발되었습니다.
그중 하나가 바로 웹캠으로 모션을 인식하는 것.
보통은 모션캡처 장비를 이용하거나 더 저렴하게 이용하고자 키넥트 여러개와 조합하거나 아니면 가속도센서를 부착한 팔과 머리만을 IK로 구현하거나 하는 방식이 주를 이루었는데 구글에서 Mediapipe라는 것을 공개하면서 2D 이미지만으로 사람의 모션을 그대로 인식하는 것이 만들어지게 되었습니다.
자세히 보면 Mediapipe뿐만 아니라 tfjs도 사용합니다. 얼굴 표정은 Blendshape형태로 쓸수있게 - 눈을 감았다 떴다 여부와 입모양 아에이오우 정도)로 간략하게 인식하고 손가락은 따로 인식해서 각 손가락의 관절이 돌아간 각도를 리턴합니다.
일단 장점이라면 사용하기 편하다는것이랑 JS형태이므로 웹브라우저로 그냥 처리가 가능하다는점.
그리고 웹브라우저를 쓰는게 마음에 안 들면 JSON형태이니 그걸 그대로 뿌려버리면 된다는 것.
대충 예제코드를 살펴보면
import * as Kalidokit from 'kalidokit' import '@mediapipe/holistic/holistic'; import '@mediapipe/camera_utils/camera_utils';
let holistic = new Holistic({locateFile: (file) => { return `https://cdn.jsdelivr.net/npm/@mediapipe/holistic@0.4.1633559476/${file}`; }});
holistic.onResults(results=>{ // do something with prediction results // landmark names may change depending on TFJS/Mediapipe model version let facelm = results.faceLandmarks; let poselm = results.poseLandmarks; let poselm3D = results.ea; let rightHandlm = results.rightHandLandmarks; let leftHandlm = results.leftHandLandmarks;
let faceRig = Kalidokit.Face.solve(facelm,{runtime:'mediapipe',video:HTMLVideoElement}) let poseRig = Kalidokit.Pose.solve(poselm3d,poselm,{runtime:'mediapipe',video:HTMLVideoElement}) let rightHandRig = Kalidokit.Hand.solve(rightHandlm,"Right") let leftHandRig = Kalidokit.Hand.solve(leftHandlm,"Left")
}; });
// use Mediapipe's webcam utils to send video to holistic every frame const camera = new Camera(HTMLVideoElement, { onFrame: async () => { await holistic.send({image: HTMLVideoElement}); }, width: 640, height: 480 }); camera.start();
여기서 faceRig ,poseRig, rightHandRig, leftHandRig는 각각 JSON형태로 되어있는 객체이며
이런 구조이니 다른 프로그램에서 JSON을 파싱해서 쓰면 되는 것이지요. 자바스크립트로 만들면 JSON파싱하고 자시고도 필요없지만 특정 프로그램을 위해 Unity에서 사용한다거나 다른 프로그램에서 쓰겠다면 JSON파싱을 해주면 읽어낼수 있습니다. 저기있는 x,y,z가 LocalEulerRotation의 RADIAN이라는 것만 안 잊어버려도 충분히 쓸 수 있습니다.
Unity에선 그냥 Quarterninon으로 써주는게 가장 최적의 시나리오지만 일단 느리긴 하지만 Euler각도도 쓸 수는 있으니 이런 방식도 나쁘지는 않은 듯 합니다. Unity가 아닌 godot엔진을 쓴다고 해도 Python은 Json파서가 기본적으로 갖추어져 있으니 더더욱 편리하게 쓸 수 있을 겁니다. 혹은 blender도 쓸 수 있고요.
그리고 안드로이드와 리눅스는 분명 호환되는 부분이 많습니다. 그렇기에 Termux(https://termux.com/) 같은 앱도 존재합니다.
하지만 새삼스럽게도 리눅스에서 안드로이드 모바일 게임을 위한 앱플레이어는 마땅한게 없다는 이야기를 많이 들었습니다.
사실 당연하다면 당연한건데 리눅스에서 게임을 별로 잘 안 하거든요. 앱플레이어 같은거 만드는 곳이 주로 중국인데 중국에서 제대로 만들리가... (소위 채굴이 숨어있다던지 많은 일들이 있었습니다.)
아주 없지는 않았습니다. Genymotion이 꽤 괜찮은 그래픽 가속을 보여주는 안드로이드 가상머신이었으니까요. (https://www.genymotion.com/)지금도 상당히 괜찮고 꽤나 편리한 모습을 보여줍니다.
그런데 OpenGL의 버전은 계속 올라가는데 Genymotion의 OpenGL지원은 딱 OpenGL ES2.0까지인것 같습니다.
최신 게임에서는 텍스처가 많이 깨지더군요. (제 옵티머스 시스템 문제일수도 있습니다.)
사실 윈도우에서도 그렇지만 앱플레이어라는게 별게 아닙니다.
그냥 Android-x86(https://www.android-x86.org/)을 기반으로 x86, amd64 CPU에서 ARM혹은 AARCH64를 호환하는 libhoudini를 가상머신에 설치해서 돌아가게 만든 것에 불과합니다. 그리고 이러한 가상머신은 VMware, Virtualbox, Qemu등이 있지요.
그래서 처음에는 VMware를 써봤는데 그래픽가속이 되는데 역시 OpenGL ES 2.0이 한계였습니다. 옛날게임은 문제가 없지만 요즘 게임은 OpenGL ES 3.0을 넘어서 Vulkan으로 나오니 대응이 안 되는 겁니다.
Virtualbox는 그냥 화면이 안 뜹니다. 3D 가속을 넣으면 화면이 안 뜨는것으로 봐서 Virtualbox의 가상 그래픽카드는 지원이 안 되는 것 같습니다.
남은건... Qemu하나네요.
정확히 말하자면 Qemu/KVM입니다. KVM이라는게 커널기반 가상화라는건데 이거 하나만 써도 왠만한 리눅스 기반 가상화는 다 해먹을 수 있습니다. 그리고 레드햇의 전폭적인 지지를 지원을 받고 있기에 요즘의 가상화 서버는 이걸로 돌아간다고 보시면 됩니다.
Nvidia Optimus란 기술은 노트북과 같은 모바일 기기에서 배터리를 효율적으로 쓰기 위해 만들어진 기술입니다.
인터넷같이 가벼운 작업은 성능낮은 내장 그래픽으로 돌리고 게임같은 그래픽카드 팍팍 돌리는 프로그램에서는 자사의 Nvidia그래픽카드를 이용해 돌리는 기술입니다.
이렇게 하면 필요할때만 고성능을 요하게 되고 꽤나 이상적인 노트북 환경이 됩니다만...
현실은 그리 녹록치 않았습니다.
윈도우에서도 옵티머스 기술로 인해 버벅임이 심해졌다는 평이 잦고 MS, 인텔, Nvidia 어느누구 하나 손발이 맞지 않는 모습이 보이면서 진짜 고성능을 요하는 사람은 옵티머스가 적용되지 않은 노트북을 찾습니다.
문제는...리눅스에서도 만만치 않은 문제를 일으킨다는 겁니다. 불행인지 다행인지 근 10년이 넘는 기간이 지나면서 많이 해결되어 왔지만 리눅스에서의 옵티머스는 그냥 기본옵션이 Performance모드 즉, 윈도에서 고성능전용 모드가 기본값입니다. 얘네도 실제 옵티머스 동작이 그렇게 썩 좋지 않다는 것을 알고 있는 겁니다.
그리고 이 옵티머스 동작이 바로 리누즈 토발즈 형님이 Nvidia에게 뻑유!!를 날리게 된 결정적인 이유였습니다.
정확히 말하면 누군가가 리눅스에서 옵티머스가 고통스럽다고 질문했고 이에 대한 토발즈의 답변이 바로 이거였습니다.
그런데 또 생각해보면 Nvidia만한 안정적인 드라이버를 만드는 곳도 드물다는걸 생각해보면...
어쨌건 이런 상황을 보던 캐노니컬도 눈뜨고 보고 있지만은 않았고 Prime이라는 기술을 만들어냅니다. (둘이 합치면 옵티머스 프라임 - 트랜스포머에 나오는 그 로봇이지요.) 일반 커뮤니티에서는 VirtualGL기술을 사용한 Bumblebee (네, 마찬가지로 트랜스포머에 나오는 범블비 맞습니다.)라는 것으로 대체 했습니다.
지금은 Bumblebee는 사실상 도태된 상황이고 Nvidia드라이버를 설치하면 PRIME을 기본적으로 사용하는데 기본 모드가 Performance 모드입니다. 사실상 옵티머스 동작이 아닙니다. 그냥 모든 순간 Nvidia카드 가속입니다.
nvidia-config을 실행해서 PRIME Profile을 보면 3가지 모드가 있는데 Intel은 비싼 노트북 사서 돌릴 사람은 아무도 없을 것 같고 Nvidia On-Demand와 Nvidia(Performance Mode) 둘중 하나가 가장 이상적인 환경인 것이지요.
그중 가장 이상적인 환경은 Nvidia On-Demand입니다만... Vulkan이나 OpenGL환경이 들어가면 자연스럽게 Nvidia카드로 가속을 하는 모드입니다.
Blender쯤 되면 알아서 넘어가야하는거 아닌가 싶은데 nvidia-config에도 무언가 프로파일 설정을 해서 넘기는게 있겠거니 했는데..
뭔가 되게 복잡합니다.procname을 적고 그에 따라 프로파일을 맞춰서 돌아가게 한다는건 좋은 생각인데 그래픽카드 쓰는 프로그램이 어디 한둘이어야죠. 그냥 메뉴에 붙은 바로가기를 수정해서 스크립트로 처리하면 안 될까 싶더군요. 예전에 Bumblebee때는 opti-run이라는 것으로 처리했었는데 이런 것처럼 말이죠.
스크립트를 하나 만들었습니다. nvidia-run 이라는 스크립트인데 위 첨부파일을 다운로드 받아 압축을 풀어서 나온 스크립트를 /bin 혹은 /usr/bin에 넣어두고 NVidia On-Demand 상태에서 고성능이 필요할때마다 opti-run때처럼
nvidia-run 사용할 프로그램
이런식으로 사용하면 됩니다.
예를 들면..
스팀을 Nvidia 카드 없이 그냥 실행하면
이렇게 nvidia-smi에 아무것도 안 뜨지만
nvidia-run steam 이라고 실행하면
이렇게 뜹니다. 즉, Nvidia카드를 쓰는 것이지요.
이렇게 고성능이 필요한 프로그램이 있다면 메뉴편집기를 사용해서
Menulibre. 내가 가장 편하게 쓰는 메뉴 편집기이다.
이렇게 명령부분 앞에 nvidia-run 을 적는 것으로 고성능모드를 쓰게 됩니다. PlayonLinux나 Steam 같이 게임같이 고성능을 요구할 경우에는 nvidia-run을 붙여주면 끝이 납니다. (딱 opti-run 사용방법 그대로라고 생각하면 됩니다.)
어차피 명령줄로 실행하는 경우는 GUI에선 드무니까 이런식으로 쓸 수 있다면 엄청 편리하겠지요! 귀찮기는 하지만 이게 진짜 Optimus 기능이 아닐까 싶습니다.
P.S 사실 이렇게 쓰게된 계기가 가상머신에서 GPU가속쪽에 문제가 생겨서 보니 옵티머스 문제였고 가상머신에서 옵티머스를 끄니까 아주 잘 돌아가더군요. 그렇다고 아주 끄니 3D가 너무 느리고요. 중간인 On-Demand를 켜고 이런식으로 쓰니까 시스템이 상당히 안정적이게 되어서 그냥 이렇게 쓰기로 했습니다.
pc_tools에서 text_export.py를 분석하니 오프셋값이 3바이트에 하나씩 쓰여서 0x4+0xC *i +0x4형태로 오프셋을 만드는 것이 확인 되었다.
하지만 이건 요마와리1의 경우고 신 요마와리는 오프셋값이 4바이트에 하나씩 쓰여있는 것이 확인 0x4+0x10*i+0x4로 고쳐주니 텍스트 뽑기가 무사히 된다. 단, 구조가 약간 다르므로 마지막줄에 0x00을 하나 더 삭제하면 된다. 그래도 역시 파이썬이 소스 읽기는 참 편하다.