본문 바로가기
개발일지/ChopChop

[ChopChop] 4. 게임 출시하기

by heydotory 2025. 2. 16.

[2024-12-29]

스팀덱에 넣어서 돌려봤다. 언리얼 특징인지 프레임이 매우 잘 안 나왔다… 60프레임도 될까 말까 했다.

다른 유니티 3D게임이나 둠을 돌려보면 90프레임은 가볍게 찍던데 내 게임은 왜 그럴까?

테스트를 하고 ScreenPercentage옵션을 넣었다. 렌더링 해상도를 낮추고 TSR이나 스팀덱의 FSR을 사용하게 하려고 한 것이다. 나중에 알게 되었지만 TSR 자체가 프레임을 많이 잡아먹는 원흉이었다

 

업적 관련한 문제가 있어 해결했다.

내 게임은 나무 1000개를 패면 업적이 달성된다. 그리고 일정 시간이 지날 때마다 통계를 저장하고 있다. 통계를 저장해야 업적이 달성되었는지 확인이 된다.

그런데 만약 통계 저장 시간이 지나기 전에 1000개를 팬다면? 게임상에서는 1000개 팼다고 하지만 업적 달성이 안 되는 것이다.

이 문제를 해결하기 위해 게임 시작 시 GetStat을 하고 장작을 하나 팰 때마다 업적달성이 되는지 계산, 된다고 판단하면 SetStat을 하도록 했다.
플랫폼 Init이 끝난 뒤 GetStat을 해야 했다. 스팀은 적용이 간단했지만 에픽은 콜백의 존재로 인해 델리게이트를 활용해야 했다. 로그인 성공 -> GetStat 과정을 추가해줬다.

 

[2024-12-30]

전체 게임플레이 테스트를 해봤다.
시작부터 엔딩까지 문제없을까? 당연히 문제가 있었다.

 

장작 인스턴스를 만들었을 때 최적화를 위해 보이지 않는 나무를 찾아 삭제하게 했다.

LineTrace 방식을 써서 보이는지를 탐색했는데 이 Trace가 이상하게 되어서 쌓인 장작 뒷부분에 구멍이 뚫리는 것이었다. 나무 수천 개를 팼는데 틈사이로 나무가 떨어져 나무가 잘 안 쌓이게 되었다.

 

확인 결과 라인트레이스 방향이 잘못되었던 것이었다.
카메라 기준으로 Ray를 쏴서 앞에서 안 보이는 나무는 사라지는 게 했는데 장작이 많이 쌓이게 되면 뒷부분이 평평해지면서 이게 안 보인다고 인식하게 되는 것이다.

카메라 방향 & 대각선 위에서 보는 방향 2곳에서 Ray를 쏘게 했었는데 부족했나 보다.

위에서 Ray를 쏠 때 대각선으로 쏘지 말고 장작에서 수직인 방향에서 Ray 를 쏘게 해서 해결했다.

 

[2024-01-01]

프롬프트 예/아니오 위치와 텍스트 색을 바꿨다.
아무리 생각해도 중요한 버튼이 오른쪽에 가야 할 것 같다고 생각했다. 다음 글을 보고 확신을 가졌다.
https://brunch.co.kr/@chulhochoiucj0/23

 

모바일 UI 디자인 기본 요소 - 버튼

가장 본질 적인 모바일 UI 컨트롤 | 버튼 Button은 사용자가 데이터를 전송하거나 기능을 실행하도록 하는 명령 컨트롤 imperative control이다. <About Face 4>에서 엘런 쿠퍼는 “컨트롤의 세계에서 가장

brunch.co.kr

https://brunch.co.kr/@august9/262

 

UI 디자인 가이드 : Buttons

UI구성 시 주요 인터랙티브 요소 중 하나인 버튼 디자인에 대해 알아야 할 내용들을 정리한 글입니다. 올바른 인터랙션을 설계하기 위해서는 현재 모든 디지털 제품에 많이 사용되는 UI 구성 요

brunch.co.kr

 

그리고 나이아가라 파티클을 수정했다.
콜리전에 충돌하면 비가 튀는 스플래쉬가 보이게 했는데, GPUSim으로 되어있어서 장작 인스턴스에 비 파티클이 안 생겼다. 그래서 CPUSim으로 바꿨다.
한 가지
더, 빌드 후 테스트하는데 비 파티클이 프레임 설정에 따라 커졌다 작아졌다 한다.
Fixed Tick Delta Time
을 체크하여 해결했다. 60fps에 맞도록 0.0166초로 설정했다.

후술 하겠지만 이와 관련된 문제가 아직 남아 있었고 그때는 144fps, 0.006944초로 설정해서 해결했다.

 

눈이 쌓였을 때 나무가 내려오는데 빠른 속도로 충돌한 곳에 눈이 자국이 안 생기니까 어색했다.

데칼 넣어서 해결했다.

눈이 없을 때에도 데칼이 생기는데 없애야 하나 고민했지만 나무가 닿았다는 걸 표시하는 역할을 해서 나쁘지 않았다.

그대로 두었다.

 

이런 디테일은 다른 일을 하다 문득 떠오르는 경우가 있다.
아이디어가 떠오르면 일이 늘어난다는 생각에 고통스럽기도 하지만 디테일을 추가하면 완성도가 높아지기 때문에 외면할 수도 없다.
꾹 참고 추가하면 대부분 만족스러운 결과를 주었고 나 자신을 더 움직이게 하는 원동력이 되기도 한다.

 

[2025-01-02]

로고를 만들었다. 글자만 있는 것보다 로고를 디자인하는 게 나아 보였고, P가 도끼와 닮았서 만들었다.

 

[2025-01-04]

모든 단어를 표현할 수 있도록 폰트를 추가했다.
지금 까지는 NotoSansKR 폰트를 사용하고 있었다.
이 폰트가 다양한 언어를 지원하고 있었지만, 한자 표현에 있어서는 일부 누락된 글자가 있었다.
누락된 글자는 에디터 상에서 네모로 표시되지만, 빌드 후 실행해 보면 그 글자만 없어진 채로 단어가 표시됐다.

 

먼저 중국어 폰트를 찾았다.
NotoSans
에 종류가 많기 때문에 한자를 표현할 수 있는 폰트를 찾아보기로 했다.
간체는 NotoSansSC, 번체는 NotoSansTC를 사용하기로 했다.

이제 이 폰트를 어떻게 언어에 맞게 보이게 적용할지 고민했다.

우선 Fallback Font Family에 설정해 봤다. 이 경우 누락된 글자는 알아서 보여줬다.
하지만 나는 굵기마다 다른 폰트를 사용해야 했기 때문에 이를 위해 Sub-Font Family를 사용하기로 했다.

이전에 폰트 굵기에 따라 01_Regular, 02_Medium, 03_Bold라고 이름을 지어줬었는데, 적용할 굵기에 맞춰 같은 이름으로 서브 폰트 이름을 지어주면 된다.

그리고 어떤 문자를 서브 폰트로 보여줄지 글자 범위를 지정해야 한다.

콤보박스에는 다양한 옵션이 있는데 한자를 위해서 CJK Unified Ideographs를 선택했다.

https://en.wikipedia.org/wiki/CJK_Unified_Ideographs

 

CJK Unified Ideographs - Wikipedia

From Wikipedia, the free encyclopedia Encoding for shared Han characters CJKV character 次 in traditional and simplified Chinese, Korean, Vietnamese and Japanese forms The Chinese, Japanese and Korean (CJK) scripts share a common background, collectively

en.wikipedia.org

이렇게 하니 모든 글자가 잘 보이게 되었다.

 

[2025-01-05]

UI 소리를 추가했다. 컴포넌트가 호버링, 확인, 취소될 때 소리가 나게 했다.
이때쯤 블루프린트 라이브러리의 개념에 대해 알게 되어서 여기에 적용해 보았다.

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/blueprint-function-libraries-in-unreal-engine

 

블루프린트 라이브러리는 정적함수의 모음이다. 덕분에 어떠한 블루프린트에서도 함수를 호출할 수 있다.

UI를 구성하는 컴포넌트 종류가 많았기 때문에 여기에 BFL이 적합하다고 생각했다.

이렇게 함수를 만들고 호출하면 끝이다.

 

사운드에 대해 이야기해 보자면 게임에 맞는 소리를 찾는데 오래 걸렸다.
평소 험블번들 등에서 에셋 꾸러미를 사는데, 수천 개의 사운드 에셋이 있지만 그중에서 내 게임의 특정 장면에 맞는 고품질의 효과음을 찾는게 여간 쉬운 일이 아니었다.

 

[2025-01-06]

Build Configuration이 Development일 때만 디버그 키가 작동하게 수정했다.

Build Configuration Development, Shipping 등 어떤 상태로 빌드를 할지 정하는 환경설정이다.

빌드할 때 지정 해주거나 프로젝트 설정에서 수정할 수 있다.

 

디버깅을 위해 키를 누르면 명령어가 실행되게 했다.

그런데 디버깅 키가 한두 개가 아니어서 이걸 변수를 넣어 작동 여부를 확인해야 하나 고민했다.

그러다 Build Configuration을 비교하는 방법을 알게 되어서 이를 매크로로 만들고 각 키마다 연결해 주었다.

 

[2025-01-08]

문득 아이디어가 떠올랐다.
쌓인 나무를 볼 수 있도록 하는 것이 더 나을 것이라는 생각이 들었다.
출시가 얼마 안 남아서 빠르게 작업했고 시작-엔딩의 중간 지점쯤에 W, S 키로 카메라를 움직일 수 있게 했다.

두 개의 키가 할당되어 있기 때문에 번갈아 가며 보여주고 싶었다.
UI
이미지가 변경되는 Flipbook에 해당되어 Paper2D를 쓰면 될까 싶어서 UI에 넣어보려고 했는데 위젯에 넣을 수 없다는 걸 알았다. 그래서 Flipbook 재질을 직접 만들었다.

 

[2025-01-12]

RuntimeDependencies.Add를 통해 빌드 시에 steam_api64.dll이 포함되게 하였다.

Steamworks SDK가 작동하기 위해서는 exe파일이 있는 위치에 dll파일이 함께 있어야 한다.

지금까지 빌드 후 dll을 직접 넣어줬는데, RuntimeDependencies.Add를 알게 된 후 번거로운 작업을 없앨 수 있었다.

직접 만든 Steamworks SDK 플러그인의 Build.cs 파일이다.

이렇게 특정 폴더에 있는 dll파일을 빌드할 때 특정 위치에 포함되도록 할 수 있다.

 

[2025-01-18]

Stove SDK를 추가했다.
에픽게임즈 스토어에 출시하기로 했었지만 업적 연동 과정에서 문제가 있어 출시를 하지 않고 스토브에 출시하기로 했다. 게임에 업적이 2개 있는데, 출시 전에 각 업적마다 XP를 할당해야 한다. 업적 XP의 합이 1000XP이면서 각 업적의 최대 XP 200XP이다.
문제는 내 게임은 업적이 2개라 해당 조건을 만족하는 것이 불가능했고 아예 업적을 없애기에는 스토어마다 다른 경험을 주는 거라 하기 싫었다. 그리고 스토어 출시 시 다른 스토어와 동등한 경험을 제공해야 한다라는 조항도 있어서 이걸 어기고 싶지 않았다. 추가로 업적이 없으면 에픽 퍼스트런이 불가능하다.
출시 후 알게 되었지만 The Witness도 업적이 2개 있는데 스팀에는 업적이 있고 에픽에는 없다. 스토어 초창기에 발매해서 가능했던 건지 모르겠지만 없애고 출시한다고 해도 검수 과정에서 일일이 확인할 것 같지는 않다.

 

이참에 한국 사정에 맞는 도움을 받을 수 있는 스토브에 출시하기로 했다.

이제 SDK 적용은 많이 해봐서 어느 정도 감이 있었다. 스토브의 경우 따라하기 문서가 친절하게 되어 있어서 좋았다.

스팀, 에픽은 Init 하는 것부터 막혔었는데 공식적인 문서에서 Unreal, Unity, Native C++ 등 따라하기 문서가 제작되어 있으니 감사할 따름이었다. 다만 문서가 많이 파편화되어 있어서 불편한 점이 있었다.

비슷한 내용인데 노션과 스튜디오 문서로 나뉘어 있어 당황스러웠다. 노션 쪽에 훨씬 디테일한 내용이 있어서 우선 스튜디오 문서를 먼저 따라 하고 부족한 부분은 노션에서 찾았다.

https://studio-docs.onstove.com/pc/GettingStarted/tutorial_unreal.html

 

PC SDK Unreal 따라하기 | STOVE Store Developer Guide

PC SDK Unreal 따라하기 UNREAL 기반 게임에 STOVE PC SDK 2.0을 적용하는 방법을 알아보기 위해 HelloStove 프로젝트에 STOVE PC SDK를 연동하고 SDK API를 이용하는 방법에 대해 설명합니다. 이 예제를 완료하려

studio-docs.onstove.com

https://studiodocs.onstove.com/1d2a1ce1-ef98-4b66-a220-34e5e10c470b

 

Unreal Engine 연동

 

studiodocs.onstove.com

따라하기 완료 후 내 프로젝트에 적용했다.
이 과정에서 GameMode에 작성했던 기능을 GameInstance로 옮겼다.
EOS
기능을 GameMode에 넣었기 때문에 Stove기능을 여기에 따라 넣었는데 게임 세이브를 리셋할 때 문제가 됐다.
두 클래스는 생애주기가 다르다. 게임모드는 레벨 로드, 언로드시에 생성, 삭제된다.
인스턴스는 프로그램 시작, 종료와 연관이 있다.
게임모드 BeginPlay시에 EOS에 로그인되도록 만들었는데 이걸 따라 Stove SDK Init을 하려고 하니 오류가 뜨는 것이었다. 스토브는 Init, Uninit을 철저히 해주어야 오류가 나지 않았다.

게임모드로는 이걸 문제없이 해결할 수 없을 것 같아서 게임 인스턴스로 옮긴 것이다. 덕분에 SDK를 사용하는 블루프린트도 모두 다시 수정해야 했다. Instance를 사용해서 게임 시작할 때 Init, 종료될 때 UnInit 하게 했다.

 
그다음으로
Stove 기능을 구현했다. 에픽과 비슷한 면이 많았다. 무수한 게임 ID 등이 필요한 것과 콜백을 쓰는 것이다.

다만 콜백은 전역 함수를 사용하고 있어서 게임 인스턴스에 정의된 델리게이트를 쓰기 위해서는 이 인스턴스를 찾는 과정이 추가되어야 했었다.

FindAPIInstance()는 전역함수이고 게임 내에 있는 GameInstance를 찾아 반환한다.
해당 함수는 스토브 언리얼 따라하기 예제 프로젝트를 뒤지면서 찾아냈다.
분명 콜백 함수는 전역함수로 만들어야 할 텐데 클래스 내부에 콜백함수 내용을 작성하고 이를 호출할 수 있게 되어 있어서 이게 어떻게 가능한 걸까… 찾아보며 알게 되었다.

 

SDK 추가로 인해 문제가 생겼다. 콜백 함수와 UnInit의 존재로 게임종료할 때 문제가 되었다.
빌드 후 확인을 해보니 게임이 종료되면서 Fatal Error 창이 떴다. 공포의 Fatal Error..

다행히 로그가 기록되어 있어 Stove SDK 쪽에 문제가 있다는 것을 알았다.

원인은 SetStat 한 후 바로 UnInit을 하는 것이었다.
해결을 위해서는 SetStat의 모든 콜백이 불린 후 UnInit을 해야 했다.
게임 종료 시에 SetStat 할 때 Count를 하고 이 Count만큼 다시 콜백이 불린 뒤 게임이 종료되게 만들었다.
게임 개발하기 너무 어렵다.

 

[2025-01-26]

Steamworks 버전을 업데이트했다. (1.59 -> 1.61)
근데 이렇게 하니까 스팀덱에서 튕겼다. 로그를 보니 Steamworks SDK 쪽 문제였다.
발매가 하루 남았는데 치명적인 오류가 생겨서 화들짝 놀랐다. 다운그레이드 해보았고 오류는 사라졌다.

SDK가 업데이트되면서 RequestCurrentStats()를 없앴던데 그게 문제가 되는 것 같았다.

 

[2025-01-27]

발매일 아침이다. 계속해서 폴리싱을 하고 있다.

우선 파티클을 수정했다.

빌드 후 테스트 하는데 비 파티클이 안보였다. 원인은 프레임… 60프레임에서 벗어나면 비 파티클 개수가 적어졌다.

Fixed Tick Delta Time이 60fps에 맞춰져 있었는데 이를 144fps(0.006944초)로 수정했다.

144fps에 맞게 하니까 다른 프레임으로 바꿔도 봐줄 만했다. 완벽하게 해결된 건 아니고 약간의 개수 차이가 보인다. 그래도 이전보다 훨씬 나아졌다.

그 외 자잘한 변수들을 수정하고 테스트 하는 과정을 거쳤다.

 

그리고 출시했다.
스토브는 출시 시간에 자동으로 출시가 가능했고 이를 알리는 메일이 왔다.

 

스팀은 자동 출시가 안되므로 스팀웍스 페이지에서 앱 출시 버튼을 눌러 게임을 출시했다.

 

https://store.steampowered.com/app/2918490/ChopChop/

 

ChopChop on Steam

Pick up your axe and chop wood without thinking.

store.steampowered.com

https://store.onstove.com/ko/games/4752

 

ChopChop | STOVE 스토어

도끼를 들고 아무 생각 없이 나무를 패보세요.

store.onstove.com

 

다음은 출시 버전의 모습이다.

 

https://www.youtube.com/watch?v=6YBc2QBhpEI

 

출시까지의 과정을 영상으로 요약 해봤다.


 

모든 것이 끝난 것 같았다.

 

그런데 출시하고 나니 최적화 문제가 머릿속에서 맴돌았다.

아무리 생각해도 이건 아닌 것 같아서 제대로 연구해보기로 했다.

'개발일지 > ChopChop' 카테고리의 다른 글

[ChopChop] 5. 게임 최적화 하기  (0) 2025.02.18
[ChopChop] 3. SDK 적용  (0) 2025.02.16
[ChopChop] 2. UI로 고통받기  (0) 2025.02.16
[ChopChop] 1. 게임 개발 시작하기  (0) 2025.02.15