비정상적인 좌표 이동에 대한 검증(Validation)
아직 패킷 암호화 등의 처리를 하지 않았다.
어차피 막아도 뚫린다는 생각이 있어서 먼저 로직상의 검증부터 구현했다.
객체의 좌표 이동시 이전 위치와 speed를 고려해서 검사하고, 통과해야 움직여준다.
로직상 비용이 드는 연산이 아니라 부담은 없다.
그러나 시작할때 생성되는 병종들과 충돌해서 사용자가 밀려나는데, 서버에서는 위치 검증에 실패해서 비정상적인 이동으로 판단함.
물론 안 겹치게 병종들을 떨어트려서 생성하면 당장은 그럴듯하겠지만 근본적인 문제를 해결하진 못한다.
충돌(Collision) 등의 물리 연산도 서버에서 진행해야하는건지 의구심이 들기 시작함..
Csharp ↔ Cpp 마샬링 문제
std::string과 C#의 string 간에 충돌로 인해 Unity3d Editor가 강제 종료되는 현상
마샬링(Marshalling) : 서로 다른 실행 환경 또는 언어간에 데이터를 전달하는 과정
그냥 string 안쓰고 일일이 int 값 주면서 해결하는게 맘편하다
능력치별 세부 기능 구현 (생명력 흡수율, 방어력 계수)
생명력 흡수율과 방어력 능력치를 구현했다.
생명력 흡수율(Attack AbsorptionRate)은 0에서 1의 수치로, 기본 공격으로 입힌 최종 피해에서 최대 100%만큼 체력을 회복한다.
방어력과 능력치에 대한 세부 공식은 제공하지 않는다.
상태 이상 (CC기) 구현
TickInterval(=1000ms)마다 value만큼 변하는 메서드를 구현해서 다음과 같은 상황에서 쓸 수 있도록 설계했다.
1. 독이나 출혈 등의 도트 데미지 구현
2. 슬로우 등의 이동 속도 저하 구현
3. 스턴 등의 기절 구현
totalTick을 초과해서 지속 시간이 지나면 다시 원래 값으로 복원한다.
기본적으로 C++의 람다 함수는 캡처해온 변수를 const 상수로 취급하기에, 수정 가능하도록 명시적으로 mutable을 선언해줘야한다.
람다 외부의 원래 변수에는 영향을 주지 않으며, 내부에서만 변경된다.
[client, field, value, totalTicks, interval, timerId]() mutable {}
백엔드에 의한 로비 Banner 동적 갱신
클라이언트에서는 슬라이드 형태로 최신 공지사항 n개와 현재 진행중인 모든 이벤트를 동적으로 받아와 표시하도록 의도했다.
공지사항과 개선 사항, 패치노트는 관리자가 작성하여 백엔드에 등록하기만 하면 모든 클라이언트에 적용된다.
서버 단에서 쿼리문을 통해 작성한 함수
1. 공지사항에서 가장 최신 n개를 가져오는 findLatestAnnouncement(Integer count) 함수
2. 이벤트의 시작일 ~ 마감일 Timestamp가 현재 진행중인 이벤트를 모두 가져오는 findInProgressEvent 함수
Controller에서 미리 더미 데이터를 생성하는 함수를 작성해서 준비했다.
findLatestAnnouncement를 통해 가져온 최신 공지사항은 4개로, 더미는 5개를 생성해서 잘 Slice하는지도 같이 확인하겠다.
이벤트는 Timestamp가 지난 이벤트와 진행중, 예정인 이벤트를 모두 생성해서 현재 진행중인 이벤트만 정제하는지 확인할 계획이다.
백엔드 단에서 클라이언트 배너에 쓰일 Banner 클래스도 준비했다.
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Banner {
@JsonProperty("Name")
private String name;
@JsonProperty("Url")
private String url;
@JsonProperty("ImageUrl")
private String imageUrl;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BannerListWrapper {
private List<Banner> banners;
}
ImageUrl에는 보기 좋으라고 원신에서 진행한 이벤트 중 일부를 불펌해서 표시했다.
이제 클라이언트는 업데이트하지 않아도, 동적으로 표시되는 Banner의 개수와 이미지를 업데이트할 수 있다.
기존에 의도한대로 공지사항 4개와 현재 진행중인 이벤트 3개가 잘 표시된다.
이미지는 보기좋으라고 원신 이벤트를 불펌했지만.. 나 원신 안해봤다.
실제 배포할때는 모든 리소스를 직접 만들 계획이고 보기좋게 테스트하기 위해서 잠깐 가져온거다ㅜ
Addressable 패치
클라이언트의 업데이트할때마다 파일을 다시 내려받아야 하는 번거로움은 현대 사회에서 최악이다.
당연히 위의 배너 시스템이 백엔드에서 동적으로 받아오도록 의도한 것도 같은 이유로 만든거다.
클라이언트의 오류 해결, 성능 개선, 시스템 추가 등의 유지 보수를 위해서라도 잦은 업데이트는 필수적인데 매번 다음 버전 파일을 다운로드하라고 하면 사용자들의 불편함이 이만저만이 아닐 것이다.
Unity에서 제공하는 Addressables 에셋 관리를 활용해서 Prefab, Texture, Audio 등의 Unity 에셋을 업데이트할 수 있다.
AWS S3 버킷을 활용해서 다음 패치에 관한 리소스가 존재한다면 빌드 과정을 거치지 않고도 업데이트하도록 구성했다.
활용처를 생각해보니… 사실 맵 추가나 챔프들의 스킨 추가 정도밖에 못 쓸거같다.
정작 제일 중요한 챔프와 병종 추가시에는 CSharp 파일을 컴파일하기 위해서라도 애플리케이션 재빌드는 필수적이다.
패치를 위한 프로그램을 따로 만들면 되긴 하는데, 귀찮다. 그건 인게임 구현이 좀 더 말끔해져서 배포 가능한 수준이 되면 시도하겠다.
1. Addressable 설치 및 설정
Windows > Package Manager(Packages: Unity Registry) > Addressables 설치
1. Windows > Asset Management > Addressbles > Groups > Create Addressables Settings
2. Materials, Models, Prefabs, Shaders, Textures 분류
2. AWS S3 연동
2-1. 버킷 정책 설정하기
2-2. Profile 생성해서 Remote(Custom) > RemoteLoadPath에 버킷 URL/{BuildTarget} 입력 → Set Active
3. Addressable 코드 작성
작성한 CSharp 코드를 통해 Addressable로 된 녀석을 가지고 오면 된다.
Addressables Groups > Build를 통해서 업로드할 데이터(ServerData/StandaloneWindows64)를 S3에 업로드하기만 하면 된다
서버에서 다운로드 받은 파일은 C:/User/user/AppData/LocalLow/Unity/{ProjectName} 경로에 있다.
Docker in Windows
Visual Studio 빌드 시스템 사용 (.vcsproj 프로젝트 파일)
사용한 외부 라이브러리들의 경로를 옮기는게 번거로울 예정
mysql :
- *\MySQL\MySQL Server 8.0\include;
- *\MySQL\MySQL Server 8.0\lib;
rdkafka :
- *\modern-cpp-kafka-main\modern-cpp-kafka-main\include;
- *\librdkafka.redist.2.3.0\build\native\include\librdkafka;
- *\librdkafka.redist.2.3.0\build\native\lib\win\x64\win-x64-Release\v142;
Kubernetes(EKS 환경)에서 Windows 노드 그룹을 생성하면 혼용 가능
- nodeSelector를 사용하여 Windows 노드에서만 이 Pod가 실행되도록 지정
얼른 CI/CD Pipeline 설계하고 배포 환경을 구축하고 싶지만, 정작 서비스의 핵심인 게임 서비스가 미완성이라 미뤄지고 있다.
'project > wargame' 카테고리의 다른 글
포탑의 공격 우선순위와 병종 시스템 개선 (feat. Kafka 메시지 유실) (0) | 2025.01.17 |
---|---|
매칭 서버의 대규모 트래픽 시험 검증하기 (feat. Kafka 성능 튜닝) (2) | 2025.01.04 |
게임서버 개선을 위한 시행착오들 (feat. 게임서버 타이머, 매치메이킹 정책) (1) | 2025.01.04 |
CQRS 패턴을 이용한 데이터 쿼리 - 게임 전적과 통계 구현 (0) | 2025.01.03 |
MSA? 이길 수 없다면 합류해라 (feat. Kafka IPC 트러블슈팅) (1) | 2025.01.03 |