분류 전체보기 489

멀티 플레이 게임서버 구현 2편: 클라이언트측 예측과 서버측 재조정

들어가며 이 글은 https://www.gabrielgambetta.com/client-side-prediction-server-reconciliation.html 글을 공부하면서 옮긴 것으로, 번역과 의역이 섞여있습니다. 이전 글에서는 권위 있는 서버와 입력만 서버로 보내고 서버가 업데이트된 게임 상태를 보낼 때까지 렌더링하는 멍청한 클라이언트를 가진 클라이언트-서버 모델을 알아보았습니다. 그러나 이런 시스템을 그냥 구현하게 되면 사용자 입력과 화면 변경 사이에 지연이 발생하게 됩니다. 예를 들어, 플레이어가 오른쪽 화살표 키를 누르면 캐릭터가 움직이기 시작하기 전에 0.5초 정도의 시간이 걸립니다. 이는 클라이언트 입력이 먼저 서버로 이동하고, 서버가 입력을 처리하고 새로운 상태를 계산하며, 업데이트..

멀티플레이 게임서버 구현 1편: 클라이언트 - 서버 게임 아키텍쳐

들어가며 이 글은 https://www.gabrielgambetta.com/client-server-game-architecture.html 글을 공부하면서 옮긴 것으로, 번역과 의역이 섞여있습니다. 어떤 종류든 게임을 개발하는 것 자체가 어려운 일이지만, 멀티플레이어 게임은 완전히 새로운 문제를 다루어야하는 독특한 어려움이 있습니다. 호흡이 빠른 멀티플레이어 게임의 클라이언트 - 서버 아키텍쳐를 구성하는 방법에 대해서 알아보겠습니다. 부정행위 문제 (The Problem of cheating) 모든 것은 부정행위에서 시작됩니다. 게임 개발자로서, 싱글 플레이 게임에서 플레이어가 부정행위를 행하는지 여부에는 관심을 두지 않습니다. 그러나 멀티 플레이 게임은 다릅니다. 경쟁 게임에서 부정을 저지르는 플레이..

간단하게 살펴보는 HTTP의 진화과정

HTTP/1.0 HTTP/1.0에서는 클라이언트/서버간 각 요청/응답에 대해 새로운 TCP 연결을 생성한다. 그래서 각 요청전에 TCP 및 TLS 핸드셰이크가 완료되어야 했고, 모든 요청에 대기시간 패널티가 발생했다 HTTP/1.1 한번의 TCP 연결을 유지하고자 Keep-alive가 등장했다. 하지만 HTTP/1.1에서는 클라이언트가 한 번에 하나의 HTTP 요청/응답 교환만 허용했으므로 네트워크 계층에서 동시성을 얻는 유일한 방법은 TCP 연결을 병렬로 사용하는 것인데, Pipelining을 통해 여러 요청을 전송했을때, 첫번째 요청에 대한 응답이 지연되면 뒤에 따라오는 모든 응답도 같이 지연되었는데 이를 “Head of line Blocking”이라고 한다. 이는 RFC 2616에서 서버는 반드시 ..

마인크래프트 광물 / 블록 좌표 바이옴 정리

이 글은 2023년 1.20.1 업데이트 기준으로 새로 업데이트 되었습니다! 컴퓨터 마인크래프트에서 F3키를 누르면 X, Y 좌표를 볼 수 있는 화면이 뜹니다. 여기서 두번째 문단을 보시면 현재 플레이어가 위치한 X, Y, Z 좌표를 볼 수 있습니다. 이중에서도 Y는 위아래, 깊이와 높이 즉 고도(Altitude)를 말합니다. 즉 땅으로 파고 들어갈 수록 더욱 낮아지는 수치입니다. v1.20 이후 자원 별 Best Y좌표 자원 추천 Y 좌표 비고 석탄 44, 95, 136 구리 48 청금석 -1 철 15, 232 -8 ~ -56 사이에서 많이 발견됨 금 -16 악지 지형에서는 32 ~ 256 레드스톤 -59 에메랄드 236 (네더) 석영 10 ~ 114 (네더) 금 15 (네더) 고대잔해 13 ~ 17 ..

[안드로이드] 순서보장 무한 페이저(Endless Pager) 만들기 with Jetpack Compose

무한 페이저를 만들때 아주 단순하게 생각하면 이렇게 만들기 쉽다. 하지만 이 경우, 초기 페이지가 내가 원하는 페이지가 되지 않는다. 실제 배열의 0번째부터 시작해야하는데, 실제 배열의 길이가 바뀌면 초기 페이지도 어떻게 될지 보장 할 수 없게 된다. val pageCount = Int.MAX_VALUE val pagerState = rememberPagerState( initialPage = Int.MAX_VALUE / 2 ) 무한 페이저는 한 두번이 아니라 나도 초기 페이지 계산하는 공식을 때려 맞추고는 했는데 빡대가리라 뭔가 수학적으로 설명을 하는게 안되서… 헤메고 있던 차, Jetpack Compose Endless Pager만들기 YouTube 강의 영상에서 아주 좋은 댓글을 발견했다. 이 방법..

[안드로이드] 부채꼴 카드처럼 돌아가는 Pager 만들기 (with Jetpack Compose Horizontal Pager)

오랜만의 Android 포스팅이다...ㅋㅋㅋ 도전적인 UI를 받아볼때 머리아프면서도 신나는 그런게 있다. 이번에 만들어본 건 손에 쥔 카드처럼 돌아가는 Pager다. (뭐라고 해야할까..? 용어를 아시는분은 댓글!) Jetpack Compose를 사용한지 3개월 남짓이라 숙련도가 다소 낮았기 때문에 간단한 이해부터 하고 작업에 들어갔다. “Jetpack Compose Pager Animation” 키워드로 검색해서 나오는 글들 중에 개인적으로 가장 깔끔했던 이 글의 설명을 빌려 Page Offset을 계산하는 방식을 후술해보려 한다. Page Offset 계산하기 Pager State 에는 currentPageOffsetFraction이라는 멤버변수가 제공된다. 이름에서 알 수 있듯이, 현재 페이지에 대..

[서울대 입구] 진순자계란말이 김밥 - 김밥

진순자 계란말이 김밥이 먹고싶을때는 대체제를 찾을 수 없다.. 단무지, 햄, 계란...단순한 재료의 김밥으로 NFT를 만들어내다니 신기한 집이다 ㅋㅋㅋ 김밥은 입안에 쏙들어가는 충무김밥보다 1.5배정도 더 큰 사이즈고, 항상 무 장아찌를 같이 주시는데 이 장아찌와 김밥의 조합의 중독성이 대박이다. 글 쓰다보니까 다시 장아찌의 감칠맛이 생각나는군.... 매장에서 먹으면 칼칼한 우동국물 같은것도 주시는데 우동은 아니고 다시다 국물도아니지만..오뎅국물? 비슷하다. 그것도 맛있다.

[방배] 핏제리아오 - 피자, 파스타

피자는 내가 싫어하는 음식이지만, 이탈리안 피자는 누가 먹자고 하면 먹는편이다. 핏제리아오는 전체적으로 간이 적당~하다. 짜거나, 감칠맛이 압도하거나, 어느 하나 튀는것 없이 잘 조율된 그 맛이 다음 한입을 더 먹게 하는 것같다. ㅋㅋㅋ 또 도우가 아주얇아서 피자 먹었을때 특유의 더부룩함이 덜하다. 파스타도 파스타집 뺨치게 맛있는 편이라 같이 먹기 좋다. 체인점인데, 방배점은 콜라도 중간에 먼저 더 채워주시고, 서비스 피자도 주시고... 뭔가 서비스가 좋았다!

Stream의 개념을 설명할 수 있나요? (의역)

"Stream"이라는 단어는 실제로 그걸 사용할때 전달하고자하는 의미와 비슷해서 선택된 것입니다. 그냥 다 잊어버리고, 물줄기(Water stream)에 대해서 생각해봅시다. 강에 흐르는 물처럼, 우리는 흐르는 데이터를 받을 수 있습니다. 이 데이터가 어디서 왔는지 알 필요는 없죠. 이게 파일에서 오든, 소켓에서 왔든, 다른 어떤 것이든...정말 알 필요가 없습니다. 뭐 물을 받을 때도 마찬가지입니다. 이 물이 호수에서 오든, 분수에서 왔든간에 알 필요가 없습니다. 즉, 이 데이터가 어디서 왔는지 관계없이 데이터를 받는데에만 신경을 쓰게된다는 겁니다. 데이터의 흐름이 추상화된 것이 "Stream"이라는 것이죠. int ReadInt(StreamReader reader) { return Int32.Pars..

메멘토 패턴 (Memento Pattern): Rust로 구현

메멘토는 세부 구현을 드러내지 않으면서 객체의 이전 상태를 복원하고, 저장할 수 있게 해주는 디자인 패턴이다. 문제 간단한 텍스트 편집기를 개발한다고 가정해보자. 상태 스냅샷을 만드는것을 간단히 생각해보면, 저장소에 모든 필드들을 저장소에 저장하는 것을 생각할 수 있다. 하지만 아래와 같은 문제들이 있을 수 있다. 캡슐화로 인해 모든 필드들에 접근할 수 없을지도 모른다. 나중에 텍스트 편집기 클래스를 리팩토링하거나 일부 필드를 추가/제거 한다고 했을때 상태 복사를 담당하는 클래스도 같이 변경해야하는 번거로움이 생긴다. 상태를 저장 및 복원하기 위해 스냅샷도 필드들을 모두 열어놓아야(public)한다. 솔루션 메멘토 패턴은 앞에서 생각했던 것 처럼 다른 객체가 외부에서 에디터의 상태를 복사하려고 시도하는 ..