Minecraft screenshot with moon setting in y=-59

안녕하세요!
김영웅이라고 합니다.

이메일: [email protected]

주로 가명인 한고훈이라는 이름으로 활동합니다.
이 곳에서는 제가 진행했던, 혹은 참여했던 프로젝트의 간략한 기록을 확인하실 수 있습니다.

아래로 스크롤하여 시작하시거나, 오른쪽 목록(모바일 환경에서는 우하단의 햄버거를 눌러서 표시합니다)에서 관심이 가시는 프로젝트를 클릭하여 바로 이동해보세요.

HoonKun
훈쿤
재미있어 보이는 이것저것을 살피는 햇병아리 멍발자

NextJS 기반 WebRTC 통신 웹 어플리케이션

WebRTC 기술을 사용해 P2P 음성/영상 통신을 구현하고, 기타 관리자 페이지 및 친구 시스템을 포함한 웹 어플리케이션의 개발, 유지보수했습니다.

Typescript
NextJS
WebRTC

2022년에 시작하여 현재까지 진행중인 프로젝트로, 프론트와 WebRTC의 시그널링 웹소켓 서버를 담당했으며 아래와 같은 기술/프레임워크를 사용했습니다.

  • NextJS (React)
  • GraphQL (클라이언트 부분)
  • WebRTC (클라이언트 부분, 시그널링을 위한 WebSocket 포함)
  • Spring + Kotlin (WebRTC 시그널링의 웹소켓 서버)

프론트의 주된 기능으로는 WebRTC 연결을 중개하는 시그널링 WebSocket 서버를 통해 WebRTC 의 Offer/Answer 를 비롯한 여러 메시지를 각 Peer 에게 전달하여 연결을 수립하고, 기타 통신 내 미디어 제어 및 권한 제어의 수행 등이 있습니다.

추가적인 기능으로는 회원 간 친구 등록, 게시판 등의 시스템이 포함되며, 특히 하나의 웹 서버 인스턴스로 여러 서브 도메인을 통해 서로 다른 서비스 영역을 제공하기도 합니다.

예를 들면, kiwi.dummy.com 으로 접속했을 때와 dummy.com 으로 접속했을 때 제공되는 서비스의 영역이나 UI 테마 등이 다르며, 서브도메인 자체도 회원이 지정할 수 있고 해당 서브 도메인에 접근할 수 있는 사용자도 회원이 제어할 수 있습니다.

이 기능을 구현하기 위해, 프론트 단에서 iframe 을 사용하여 localStorage 가 같은 베이스 도메인 간에 공유되도록 하는 작업도 진행한 바가 있습니다.

WebRTC 시그널링 서버는, 기존의 Java 로 작성되어 다소 장황하고 유지보수하기 어려웠던 코드를 Kotlin 으로 재작성하였습니다.

Kotlin 의 Coroutine 을 적극적으로 활용하여 스레드 제어 및 비동기 코드 작성에 신경썼고, 기존 코드의 불필요하거나 과도한 예외처리 로직을 삭제하거나 Kotlin 의 간소화된 문법으로 대치하여로직의 흐름을 쉽게 파악할 수 있도록 하였습니다.

React Native 기반, mp3 음원 믹싱 및 소켓을 통해 실시간으로 송수신하는 어플리케이션

실시간으로 여러 Mp3를 PCM 으로 변환하고, 믹싱 후 다시 Mp3로 인코드하여 소켓을 통해 전송, 재생하는 어플리케이션을 개발했습니다.

Typescript
React Native
Socket Communication

2023년에 진행된 프로젝트로, React Native의 JS 단 프론트 및 Kotlin 을 사용한 Android Native 코드를 담당했으며 아래와 같은 기술/프레임워크가 사용되었습니다.

  • React Native
  • lame Mp3 Encode/Decoder
  • Byte 단위 Socket 통신

주된 기능으로는 음원 재생 장치와 통신하여 장치의 상태 등을 UI에 표시하고, Mp3 음원 데이터를 실시간으로 소켓을 통해 장치에 전송하여 장치로 하여금 음원을 재생하도록 합니다.
특히, 장치에 보내는 음원은 하나가 아니어도 되며, 여러 Mp3 를 동시에 재생하여도 PCM + 믹싱을 통해 합쳐 전송합니다.

기타 전송 음원 자체의 볼륨 제어, 소켓 통신을 통한 장치의 설정 수정 등이 포함됩니다.

React Native 로 만들어졌기 때문에, 적절한 백그라운드 핸들링을 위해 UI만 React 를 통해 작성하고 실제 믹싱, 소켓 통신 등의 부분은 Kotlin(Native 코드)를 통해 작성했습니다.
Coroutine 과 Event 기반의 코드로 React Native 와의 불협음을 최소화하고, 음원의 원활한 재생을 위해 성능에 신경을 쓰게 된 프로젝트입니다.

Electron 기반 협업용 2D 경로 에디터 툴 프로그램

CSV 로 주어지는 경로 데이터를 편집하고, 편집자와 검수자를 분리하여 협업을 위한 작업 플로우가 존재하는 프로그램을 개발했습니다.

Typescript
Electron
Python
Django

2022년에 진행된 프로젝트로, Electron 을 사용하여 JS 프론트 및 Django 를 사용한 백엔드 개발을 담당했으며 아래와 같은 기술/프레임워크가 사용되었습니다.

  • Electron (Front)
  • Django (Back)
  • Kakao Map 연동

주된 기능은 아래와 같습니다:

  • 관리자의 CSV 입력 파일 관리(업로드, 삭제, 검색 및 필터 등)
  • 편집자의 CSV 편집 에디터
    • 경로 편집: 경로를 구성하는 점의 선택 삭제
    • 고리표 추가: 경로를 구성하는 점 각각에 의미를 부여
    • 실행취소/다시실행 등 에디터의 기본 기능
    • CSV 메타 데이터 편집
  • 검수자의 CSV 검수 지원
    • 검수 후 적절하면 다음 단계(관리자)로, 그렇지 않으면 이전 단계(작업자)로 반려하는 간단한 워크플로우 기능
  • 관리자의 최종 편집 완료 파일 관리(다운로드, 삭제, 검색 및 필터 등)

백엔드는 Django, SQLite3 를 사용하여 개발했고,
각 CSV 파일을 DB에 레코드로 추가하고 현재 진행 워크플로우 설정 및 여러 작업자/검수자 중 담당할 사용자를 할당할 수 있도록 설계했습니다. 부가기능으로 작업자나 검수자의 작업 시간 통계를 위한 API 도 개발했습니다.

프론트에서는 작업자의 파일 중간 저장, 작업시간 기록 등을 위해 Electron 의 ipc 패턴을 사용했으며, 기타 일반적인 UI 및 상태 관리는 React 를 통해 이루어졌습니다.
CSV 파일 각각은 대량의 데이터를 다루기 때문에, 리스트 가상화 등을 통해 최적화도 일부 진행한 바가 있습니다.

NextJS 기반 세탁물 관리 시스템 웹 어플리케이션

NextJS 를 사용하여 세탁 회사의 세탁물 처리 현황 및 거래 클라이언트를 관리하는 페이지를 개발했습니다.

Typescript
NextJS

2022년에 진행된 프로젝트로, 프론트 전체와 백엔드 일부를 담당했으며 프론트에서는 간단하게 NextJS 만 사용된 프로젝트입니다.
백엔드에서는 Django 를 사용했으며 도커를 통해 배포되었습니다.

의류를 세탁하는 세탁 회사가 관리자가 되고, 세탁 회사의 작업자는 당일 진행된 세탁 업무를 기록하며, 거래 클라이언트는 해당 페이지에서 일부 보고서 등을 확인할 수 있는 페이지입니다.

주된 기능으로는 세탁 회사의 작업자 각각이 어떤 클라이언트의 어떤 세탁물을 처리했는지를 날짜와 함께 표 형태로 기록하고, 그 기록을 취합하여 일별 / 월별 / 월간 보고서를 생성합니다.
클라이언트 별로, 또 세탁물 별로 단가가 차등 설정될 수 있도록 설계되었고, 보고서는 세탁물 처리 현황 및 단가표, 연간 전체 보고서 등으로 구성됩니다.

하나의 소스 코드로 여러 도커 컨테이너를 통해 여러 세탁 회사에게 서비스를 제공할 수 있도록 설계되었기도 합니다.

마인크래프트 월드 데이터를 git으로 버전관리할 수 있게 하는 마인크래프트 서버 플러그인

Kotlin 으로 작성된, 마인크래프트 월드를 git을 통해 버전관리, 브랜치 분기, 병합 등을 수행할 수 있게 하는 서버 플러그인을 작성했습니다.

Kotlin
Minecraft Server Plugin
마인크래프트 월드 데이터를 git으로 버전관리할 수 있게 하는 마인크래프트 서버 플러그인

2022년에 진행한 개인 프로젝트로, 저장소는 이쪽 입니다.

복잡한 월드의 백업 및 복구를 간략화하고, '코드를 작성할 때 사용하는 브랜치를 월드에도 적용시킬 수 있다면 어떨까?' 라는 생각에서 시작된 프로젝트입니다.
git 에 대해 잘 알지 못했을 때 그에 대해 좀 더 잘 이해하고자 했던 목표와 함께 시작했던 이 프로젝트는 지금까지 진행한 프로젝트 중 가장 완성도있고 바람직하게 마무리한 프로젝트로 평가하고 있습니다.

Spigot 이라는 마인크래프트 서버 플러그인 개발 프레임워크를 사용했고, Git 관련 조작을 위해 JGit 을 사용했습니다.
개발 중 마주친 벽이나 고민해서 해결했던 문제들 등 더 자세한 사항은 저장소의 README.md, 혹은 블로그의 이 게시글 을 참조하시는 것도 괜찮을 것 같습니다.

CoreKeeper 리모트 플레이어

즐겨 하던 게임을 WebRTC 를 통해 iOS 에서 플레이할 수 있게 하는 리모트 플레이어를 개발했습니다.

SwiftUI
Ktor
GStreamer
WebRTC
CoreKeeper 리모트 플레이어

플레이어 클라이언트 일반적인 iOS 어플리케이션으로 아래와 같은 기술을 사용했고:

  • Swift + SwiftUI
  • WebRTC.framework

실제 게임의 구동이 이루어지는 리모트 서버는 아래와 같은 기술을 사용하여 구현했습니다:

  • GStreamer + WebRTCBin: 플레이 영상 송수신
  • WebRTC DataChannel + Python 의 uinput 바인딩: 클라이언트가 보내는 키 입력을 재현
  • Ktor: WebRTC 의 시그널링 웹 소켓 서버
  • Coturn 및 기타

대략, '우분투 환경에서 돌아가는 게임의 영상을 GStreamer 의 WebRTCBin 을 통해 클라이언트(iOS 앱)에 전달하고, 클라이언트가 보내는 키 입력을 DataChannel 로 받아 Python 의 uinput 바인딩이 우분투에서의 키 입력을 재현' 으로 요약되는 프로젝트입니다.

GStreamer 나 uinput, TURN 서버 구성 등에서 여러 쉽지 않은 문제를 만났지만 개인 프로젝트인데도 어떻게든 돌아가는 명확한 아웃풋이 나온 몇 안되는 프로젝트 중 하나입니다.

개발 후 남긴 기록으로는 서버의 개발에 대한 게시글, 클라이언트의 개발에 대한 게시글, 총 후기 게시글이 있습니다.

Jetpack Compose 기반 Minecraft Dungeons 세이브 파일 에디터 프로그램

Kotlin(JetpackCompose) 를 사용해 작성한, Minecraft Dungeons 의 세이브 데이터를 수정하는 프로그램을 개발했습니다.

Kotlin Multiplatform
Jetpack Compose
Jetpack Compose 기반 Minecraft Dungeons 세이브 파일 에디터 프로그램

2023년에 진행한 개인 프로젝트로, 저장소는 이쪽 입니다.
기존에 다른 사람이 개발해놓은 에디터가 마음에 들지 않아 독자적으로 다시 개발한 프로그램입니다.

Jetpack Compose 를 사용하여 반응형 UI로 구성했으며, 그것이 제공하는 구성 가능 함수인 AnimatedContent 등을 사용하여 화면 전환에 신경을 쓴 프로젝트입니다.
실질 Json을 GUI를 통해 수정하는 프로그램으로, Jetpack Compose 의 StateHolder 라는 패턴을 사용하여 구현했습니다.

또, 툴 내에서 게임의 이미지 등을 표시하지만 그 어떤 인게임 리소스도 프로그램 내에 직접 포함하지 않고 프로그램 사용자의 환경에 정식으로 설치된 게임의 리소스를 직접 해제하여 그것을 사용하도록 했습니다.
관련하여 작성한 Unreal 엔진으로 개발된 게임의 리소스 형식은 Pak 파일을 읽는 PakReader 모듈은 기존 C#으로 작성된 것을 Kotlin 으로 번역하였습니다.

개발 후 작성한 후기 비슷한 블로그 게시글도 있습니다.

Unity 엔진 기반 2D 리듬게임

판정선을 포함한 필드가 제한없이 이동하고, 판정선의 위/아래에서 각각 노트가 출현하는 2D 리듬게임을 개발했습니다.

Unity
2d
C#
Unity 엔진 기반 2D 리듬게임

Static Field 라는 이름의, Unity 엔진 기반 필드 이동 상하 비대칭 건반형 리듬게임을 개발했습니다.

'과도하지 않게 절제되었지만 풍부한 필드 기믹 + 채보 자체로 난이도를 조절' 을 목표로했고, 실제로 그렇게 되었다고 생각합니다.
첫 구현 이후 일정 시간이 지난 뒤 코드를 정리할 기회가 생겨 좀 더 최적화를 진행하고 일부 기믹을 추가할 수도 있었지만, 제대로 서비스를 해보지는 못했으며 개인 프로젝트로 남게 되었습니다.

어디까지나 2D로 제작된, 기하학적인 도형 기반으로 이루어진 단순한 리듬게임이지만, 변속 시스템 및 노트의 겹침 판정 등 여러 리듬게임 개발 시 만날 수 있는 벽들, 실제 서비스 할 때 만날 수 있는 벽도 일부 경험했다고 생각합니다.

Kotlin 기반 Midi 파일을 마인크래프트의 McFunction 으로 변환하는 프로그램

Kotlin 으로 작성된, Midi 파일을 읽어 반복 커맨드블럭에 연결하여 재생시킬 수 있는 McFunction 파일로 변환하는 프로그램을 개발했습니다.

Kotlin Console
Minecraft Commands
Kotlin 기반 Midi 파일을 마인크래프트의 McFunction 으로 변환하는 프로그램

2023년에 진행한 개인 프로젝트로, 저장소는 이쪽입니다.

jfugue 라이브러리를 사용하여 Midi 파일을 읽고, 그것을 하나의 McFunction 으로 재작성합니다.
이 McFunction 은 하나의 반복 커맨드 블럭에 연결되어 일정한 위치에서 마인크래프트의 노트블럭을 스폰하고 그 음을 Midi 에 맞게 설정, 재생합니다.

Kotlin 으로 마인크래프트의 커맨드 집합을 출력하는 프로그램이지만, 결국 출력물을 가져다가 실행하는 것안 마인크래프트 클라이언트이기 때문에 무겁지 않게 작성해야 했고 첫 구현에 이어 커맨드 셋의 최적화가 일부 진행된 바 있습니다.

관련하여 블로그에 이런 게시글도 있습니다.

Deemo(리듬게임) 플레이의 어시스트를 위한 Android 전용 가리개 어플리케이션

Java 로 작성된, Deemo 플레이에 사용 되는 종이 가리개의 어플리케이션 버전을 개발했습니다.

Java
Android
Deemo(리듬게임) 플레이의 어시스트를 위한 Android 전용 가리개 어플리케이션

2017년에 진행한 개인 프로젝트로, Java 로 작성되었으며 Android 의 Service 와 WindowManager 를 사용하여 항상 화면에 표시되는 화면 가리개 어플리케이션입니다.

원래는 일본의 Nanoflower 님이 처음으로 사용하기 시작한 것으로 알려진 Deemo 플레이 중 사용하는 종이 가리개를, 종이 없이 어플리케이션을 통해 사용할 수 있도록 했습니다.

처음으로 실제 Google Play 스토어에 정식으로 배포했던 어플리케이션으로, 지원은 종료하여 몇 년 째 업데이트가 진행되고있지 않지만 스토어에서 검색하면 찾아보실 수 있습니다.