Skip to content

boostcampwm2025/ios05-cosmic-adventure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

358 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Cosmic Adventure

cosmicMockup

์–ธ์ œ๋‚˜, ์–ด๋””์„œ๋‚˜ ํ™˜๊ฒฝ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  ์šฐ์ฃผ๋ฅผ ํƒํ—˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”์Šค๋ฏน ์–ด๋“œ๋ฒค์ฒ˜์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!


๋ชฉ์ฐจ


์ฃผ์š” ๊ธฐ๋Šฅ ์†Œ๊ฐœ

์˜จ๋ณด๋”ฉ

์‚ฌ์šฉ ๊ถŒํ•œ ์„ค์ • ํ”„๋กœํ•„ ์„ค์ •
์‚ฌ์šฉ ๊ถŒํ•œ ์„ค์ • ํ”„๋กœํ•„ ์„ค์ •
์นด๋ฉ”๋ผ / ๊ทผ๊ฑฐ๋ฆฌ ํ†ต์‹  / ์•Œ๋ฆผ ๊ถŒํ•œ ์•ˆ๋‚ด ๋ฐ ์„ค์ • ๋‹‰๋„ค์ž„ + ์บ๋ฆญํ„ฐ ์„ ํƒ์œผ๋กœ ๋‚˜๋งŒ์˜ ๋˜์ž‰๋˜์ž‰์Šค ์ƒ์„ฑ

ํ™ˆ: ๋™๋ฃŒ ์ฐพ๊ธฐ

๋กœ๋น„ ๋ทฐ
A) ์ฑ„๋„ ๋งค์นญ(์„œ๋ฒ„ ๊ธฐ๋ฐ˜)

- ์„œ๋ฒ„ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ
- ์›๊ฑฐ๋ฆฌ ํ”Œ๋ ˆ์ด์–ด์™€ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ
- ์ฑ„๋„ ํ˜ผ์žก๋„ ๊ธฐ๋ฐ˜ ์˜คํ† ์Šค์ผ€์ผ๋ง
ย ย ย ย - Scale-Out: ์ฑ„๋„ ์ ์œ ์œจ์ด 80% ์ดˆ๊ณผ ์‹œ, ์ถ”๊ฐ€ ์ฑ„๋„ ํ• ๋‹น
ย ย ย ย - Scale-In: ๋น„์–ด์žˆ๋Š” ์ฑ„๋„ ๋ฐœ์ƒ ์‹œ ์ž์› ์ •๋ฆฌ

B) ๊ทผ๊ฑฐ๋ฆฌ ํƒ์ƒ‰(P2P)

- ์ธํ„ฐ๋„ท ์—†์ด๋„ ๊ฐ€๋Šฅ
- ์ฃผ๋ณ€ ์œ ์ €๋ฅผ ์ง์ ‘ ํƒ์ƒ‰ํ•ด์„œ ์—ฐ๊ฒฐ

๋งค์นญ ํ๋ฆ„

๊ฒŒ์ž„ ์ดˆ๋Œ€ ๋ฐ ์ˆ˜๋ฝ
- ์›ํ•˜๋Š” ์œ ์ €์—๊ฒŒ ์ดˆ๋Œ€ ์š”์ฒญ
- ์ƒ๋Œ€๊ฐ€ ์ˆ˜๋ฝํ•˜๊ณ , ๋‘ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ค€๋น„ ์™„๋ฃŒ ์‹œ ๊ฒŒ์ž„ ๋งต ์ง„์ž…
- ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ์˜ค๋ฉด ์•Œ๋ฆผ ๋ชฉ๋ก์—์„œ ํ•œ๊บผ๋ฒˆ์— ๊ด€๋ฆฌ
ย ย ย ย - ๋ชฉ๋ก์—์„œ๋„ ์ˆ˜๋ฝ/๊ฑฐ์ ˆ ๊ฐ€๋Šฅ
ย ย ย ย - ๋ชฉ๋ก ๋ณด๋Š” ์ค‘ ์ƒˆ ์š”์ฒญ์ด ์˜ค๋ฉด ์ฆ‰์‹œ ์ฒ˜๋ฆฌ UI ์ œ๊ณต

๊ฒŒ์ž„ ์˜จ๋ณด๋”ฉ

๊ฒŒ์ž„ ๊ฐ€์ด๋“œ๋ทฐ
๊ฒŒ์ž„ ์˜จ๋ณด๋”ฉ
- ๊ณ ๊ฐœ ๊ฐธ์›ƒ(์ขŒ/์šฐ): ์ขŒ์šฐ ์ด๋™
- ์ž… ์˜ค๋ฏ€๋ฆฌ๊ธฐ: ์ ํ”„
ย ย ย ย - 1๋‹จ ์ ํ”„: ์ž…์ˆ  ๋‚ด๋ฐ€๊ธฐ
ย ย ย ย - ์—ฐ์† ๋™์ž‘์œผ๋กœ ์ตœ๋Œ€ 2๋‹จ ์ ํ”„๊นŒ์ง€ ๊ฐ€๋Šฅ
- 2์ธ ๋ชจ๋“œ ์Šน๋ฆฌ ์กฐ๊ฑด: ๋ชฌ์Šคํ„ฐ๋ฅผ ํ”ผํ•ด ๋” ๋น ๋ฅด๊ฒŒ ๊ฒฐ์Šน์  ๋„๋‹ฌํ•˜๋Š” ์‚ฌ๋žŒ์ด ์Šน๋ฆฌ

๊ฒŒ์ž„ ๋ชจ๋“œ & ํ”Œ๋ ˆ์ด ๊ฒฝํ—˜

2์ธ ๋ชจ๋“œ 1์ธ ๋ชจ๋“œ ๊ฒฐ๊ณผ ํ™”๋ฉด
- ์ƒ๋Œ€์˜ ๋น„๋””์˜ค ํ”ผ๋“œ + ์บ๋ฆญํ„ฐ ์ƒํƒœ๊ฐ€ ์‹ค์‹œ๊ฐ„ ๋™๊ธฐํ™”
- ์ƒ๋Œ€ ์บ๋ฆญํ„ฐ๋Š” ๋ฐ˜ํˆฌ๋ช… ์ฒ˜๋ฆฌ
ย ย ย ย - ์‹œ์•ผ ๋ฐฉํ•ด ์ตœ์†Œํ™”
ย ย ย ย - โ€œํ•จ๊ป˜โ€ ํ”Œ๋ ˆ์ดํ•˜๋Š” ๋А๋‚Œ ๊ฐ•ํ™”
- ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ํ”Œ๋ ˆ์ด ๊ฐ€๋Šฅ
- ๋ชฌ์Šคํ„ฐ์— ๋‹ฟ์œผ๋ฉด ์ฆ‰์‹œ ๋ฆฌ์Šคํฐ
- ์šฐ์ธก ์ƒ๋‹จ ๋ฒ„ํŠผ์œผ๋กœ ์ˆ˜๋™ ๋ฆฌ์Šคํฐ๋„ ์ง€์›
- ํ”Œ๋ ˆ์ด ์ค‘ ์ดˆ๋Œ€๊ฐ€ ์˜ค๋ฉด ๋ฐฐ๋„ˆ ์•Œ๋ฆผ์œผ๋กœ ๋ฐ”๋กœ ์ฐธ์—ฌ ๊ฐ€๋Šฅ
- ๊ฒŒ์ž„ ์ข…๋ฃŒ ์‹œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ 
- ๊ฒฐ์Šน์ ์—๋Š” ๋˜์ž‰๋˜์ž‰์Šค๋ฅผ ํƒˆ์ถœ์‹œ์ผœ์ค„ ์šฐ์ฃผ์„ ์ด ๋Œ€๊ธฐ

ํ™˜๊ฒฝ ์„ค์ •(ํŠœ๋‹/ํ…Œ์ŠคํŠธ)

ํ™˜๊ฒฝ ์„ค์ •๋ทฐ
- ๊ฐ๋„ ์กฐ์ ˆ
- PIP ํฌ๊ธฐ ์กฐ์ ˆ
- ์‚ฌ์šด๋“œ ๋ณผ๋ฅจ ์กฐ์ ˆ
- ํ…Œ์ŠคํŠธ ๋ทฐ(๊ฒŒ์ž„ ๋ฏธ๋ฆฌ๋ณด๊ธฐ)
ย ย ย ย - ์„ค์ •๊ฐ’์ด ์‹ค์ œ ํ”Œ๋ ˆ์ด์— ์–ด๋–ป๊ฒŒ ์ ์šฉ๋˜๋Š”์ง€ ์ฆ‰์‹œ ํ™•์ธ

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๋ฐ ๋ฒ„์ „ ์ •๋ณด

Swift
iOS
Xcode
Vapor
Tuist


ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

ํด๋” ๊ตฌ์กฐ

โ”œโ”€โ”€ iOS/
โ”‚   โ”œโ”€โ”€ App/
โ”‚   โ”‚   โ”œโ”€โ”€ Sources/
โ”‚   โ”‚   โ”œโ”€โ”€ Resources/
โ”‚   โ”‚   โ””โ”€โ”€ Tests/
โ”‚   โ”œโ”€โ”€ Modules/
โ”‚   โ”‚   โ”œโ”€โ”€ GameEngineCore/
โ”‚   โ”‚   โ”œโ”€โ”€ InputSystem/
โ”‚   โ”‚   โ”œโ”€โ”€ NetworkKit/
โ”‚   โ”‚   โ”œโ”€โ”€ VideoKit/
โ”‚   โ”‚   โ”œโ”€โ”€ StorageKit/
โ”‚   โ”‚   โ””โ”€โ”€ Games/
โ”‚   โ””โ”€โ”€ Tuist/
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ Sources/
โ”‚   โ”œโ”€โ”€ Tests/
โ”‚   โ””โ”€โ”€ Public/
โ”œโ”€โ”€ fastlane/
โ”œโ”€โ”€ docs/
โ”œโ”€โ”€ Project.swift
โ””โ”€โ”€ cosmic-adventure.xcworkspace

๋ชจ๋“ˆํ™”

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2026-02-01 แ„‹แ…ฉแ„’แ…ฎ 10 46 06

๋ชจ๋“ˆํ™” ๋„์ž… ์ด์œ  ๋ฐ ์„ค๊ณ„ ์›์น™

๊ณ ๋„ํ™”๋œ ๊ฒŒ์ž„ ๊ฒฝํ—˜๊ณผ ์œ ์ง€๋ณด์ˆ˜์˜ ํšจ์œจ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์กฐ๋ฅผ ๋ชจ๋“ˆํ™” ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹จ์ˆœํžˆ ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์„ ๋„˜์–ด, SOLID ์›์น™์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง€์† ๊ฐ€๋Šฅํ•œ ํ™•์žฅ์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ๋ฐ ์ดˆ์ ์„ ๋งž์ถ”์—ˆ์Šต๋‹ˆ๋‹ค

  • SRP (Single Responsibility Principle): ๊ฐ ๋ชจ๋“ˆ์€ ๋ฌผ๋ฆฌ ์—”์ง„, ๋„คํŠธ์›Œํฌ, UI ๋“ฑ ๋…๋ฆฝ์ ์ธ ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ฝ”๋“œ์˜ ์‘์ง‘๋„๋ฅผ ๋†’์˜€์Šต๋‹ˆ๋‹ค.
  • DIP (Dependency Inversion Principle): ์ƒ์œ„ ๋ชจ๋“ˆ์€ ํ•˜์œ„์˜ ๊ตฌ์ฒด ๊ธฐ์ˆ ์ด ์•„๋‹Œ Protocol ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์˜ ์ˆ˜์ • ์—†์ด ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค.
  • OCP (Open-Closed Principle): ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ํ”„๋กœํ† ์ฝœ ํ™•์žฅ์„ ํ†ตํ•ด ๊ธฐ๋Šฅ์„ ๋”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ถ•ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ชจ๋“ˆ๋ณ„ ์—ญํ• 

Application & UI

  • App: ํ”„๋กœ์ ํŠธ์˜ ์ง„์ž…์ ์œผ๋กœ, ์ „์ฒด ์•ฑ์˜ ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์ „์—ญ ์„ค์ •์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • Presentation: SwiftUI ๊ธฐ๋ฐ˜์˜ UI์™€ ViewModel์„ ํฌํ•จํ•˜๋ฉฐ, ์ƒํƒœ ๊ด€๋ฆฌ์™€ ๋ชจ๋“ˆ ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ฃผ์ž…(DI)ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Domain (Business Logic)

  • Domain: ๊ฒŒ์ž„์˜ ๊ทœ์น™ ๋ฐ ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ๊ธฐ์ˆ  ์Šคํƒ์— ์ข…์†๋˜์ง€ ์•Š๋Š” ์ˆœ์ˆ˜ ๋กœ์ง์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • Games: ๊ฒŒ์ž„์˜ ๊ตฌ์ฒด์ ์ธ ๋ฃฐ์„ ์ •์˜ํ•˜๋Š” ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.

Infrastructure (๊ตฌ์ฒด ๊ธฐ์ˆ  ๊ตฌํ˜„)

  • InputSystem: ARKit ๊ธฐ๋ฐ˜์˜ ์–ผ๊ตด ํ‘œ์ • ํŠธ๋ž˜ํ‚น ๋ฐ ์ž…๋ ฅ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์˜ ๊ธฐ๋ฐ˜์„ ๋งˆ๋ จํ•ฉ๋‹ˆ๋‹ค.
  • GameEngineCore: ๊ฒŒ์ž„ ๋ฌผ๋ฆฌ ์—ฐ์‚ฐ ๋ฐ ์—”์ง„์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜์—ฌ ์•ˆ์ •์ ์ธ ๊ฒŒ์ž„ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • NetworkKit: P2P(Local) ๋ฐ WebSocket(Remote) ํ†ต์‹ ์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.
  • VideoKit: ์˜์ƒ ๋ฐ์ดํ„ฐ์˜ ๊ณ ํšจ์œจ ์ธ์ฝ”๋”ฉ/๋””์ฝ”๋”ฉ ๋ฐ ์‹ค์‹œ๊ฐ„ ์ „์†ก์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • StorageKit: SwiftData๋ฅผ ํ™œ์šฉํ•œ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ ์˜์†์„ฑ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋ฉฐ ์ •ํ˜•ํ™”๋œ ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


๊ธฐ์ˆ  ์Šคํƒ ๋ฐ ๋„์ž… ์ด์œ 

๐ŸŒ ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๋ฐ ๋„คํŠธ์›Œํฌ

  • Network.framework
    • ๋„์ž… ์ด์œ : URLSession๋ณด๋‹ค ๋‚ฎ์€ ์ˆ˜์ค€(Low-level)์—์„œ TCP/UDP ๋ฐ TLS ์—ฐ๊ฒฐ์„ ์ง์ ‘ ์ œ์–ดํ•˜์—ฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ , ์ €์ง€์—ฐ ์‹ค์‹œ๊ฐ„ P2P ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: Bonjour๋ฅผ ํ†ตํ•œ ์ฃผ๋ณ€ ๊ธฐ๊ธฐ ํƒ์ƒ‰๊ณผ TCP ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ๋ณ„๋„์˜ ์ค‘์•™ ์„œ๋ฒ„ ์—†์ด ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์–ด ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.
  • WebSocket
    • ๋„์ž… ์ด์œ : ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ตํ™˜์„ ์œ„ํ•ด ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: Vapor ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ๋˜์–ด ์‹ค์‹œ๊ฐ„ ์‚ฌ์šฉ์ž ์ƒํƒœ ๋™๊ธฐํ™”, ๋งค์นญ ์‹œ์Šคํ…œ ๋ฐ ๊ฒŒ์ž„ ๋ฐ์ดํ„ฐ ์ค‘๊ณ„๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽฅ ๋น„๋””์˜ค ๋ฐ ๋ฏธ๋””์–ด ์ฒ˜๋ฆฌ

  • VideoToolbox
    • ๋„์ž… ์ด์œ : ํ•˜๋“œ์›จ์–ด ๊ฐ€์†์„ ํ™œ์šฉํ•ด ๋น„๋””์˜ค๋ฅผ ์ธ์ฝ”๋”ฉ/๋””์ฝ”๋”ฉํ•จ์œผ๋กœ์จ CPU ๋ถ€ํ•˜์™€ ๊ธฐ๊ธฐ ๋ฐœ์—ด์„ ์ตœ์†Œํ™”ํ•˜๊ณ , ๊ณ ํ•ด์ƒ๋„ ์˜์ƒ์„ ๋งค๋„๋Ÿฝ๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: H.264 ์ฝ”๋ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ์„ ์••์ถ•ํ•˜๊ณ  ์ „์†กํ•จ์œผ๋กœ์จ ๋„คํŠธ์›Œํฌ ๋Œ€์—ญํญ ํšจ์œจ์„ ๋†’์ด๊ณ  ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽฎ ๊ฒŒ์ž„ ์—”์ง„ ๋ฐ AR

  • SpriteKit & ARKit
    • ๋„์ž… ์ด์œ : ํ˜„์‹ค ์„ธ๊ณ„์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์ฆ๊ฐ•ํ˜„์‹ค(AR) ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๊ณ , 2D ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋ฅผ ๊ฐ€๋ณ๊ณ  ์ง๊ด€์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ๋‘ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: ARKit์˜ Face Tracking ๊ธฐ์ˆ ๋กœ ์‚ฌ์šฉ์ž์˜ ํ‘œ์ •๊ณผ ์›€์ง์ž„์„ ์ถ”์ ํ•ด ์‹ค์‹œ๊ฐ„ ๊ฒŒ์ž„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉฐ, SpriteKit ๊ธฐ๋ฐ˜์˜ ๋ฌผ๋ฆฌ ์—”์ง„๊ณผ ์• ๋‹ˆ๋ฉ”์ด์…˜์œผ๋กœ ๋ชฐ์ž…๊ฐ ์žˆ๋Š” ๊ฒŒ์ž„ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ— ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ๋ฐ ์ž๋™ํ™”

  • Tuist
    • ๋„์ž… ์ด์œ : Xcode ํ”„๋กœ์ ํŠธ ํŒŒ์ผ(.xcodeproj)์˜ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ๋ชจ๋“ˆํ˜• ์•„ํ‚คํ…์ฒ˜๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: Project.swift ์ •์˜๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ(NetworkKit, VideoKit, Games ๋“ฑ) ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ํŒ€์› ๊ฐ„ ์ผ๊ด€๋œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • Fastlane
    • ๋„์ž… ์ด์œ : ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜์—ฌ ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ณ  ๋ฐ˜๋ณต์ ์ธ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ํ™œ์šฉ: Match๋ฅผ ํ†ตํ•œ ์ธ์ฆ์„œ ๊ด€๋ฆฌ์™€ TestFlight ์—…๋กœ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ž๋™ํ™”ํ•˜์—ฌ ์ง€์†์ ์ธ ๋ฐฐํฌ(CD) ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ–ˆ์Šต๋‹ˆ๋‹ค.


๋ฌธ์ œ ํ•ด๊ฒฐ ๊ธฐ๋ก

P2P + WebSocket ํ†ตํ•ฉ ๋„คํŠธ์›Œํ‚น ๋ ˆ์ด์–ด

๋ฌธ์ œ

ํ”„๋กœ์ ํŠธ๋Š” ๊ทผ๊ฑฐ๋ฆฌ P2P(Network.framework) ์™€ ์›๊ฑฐ๋ฆฌ ์„œ๋ฒ„ ํ†ต์‹ (WebSocket) ์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋งŒ ๋‘ ๋ฐฉ์‹์€ ์ „์†ก ๋ฐฉ์‹๊ณผ ๋ฐ์ดํ„ฐ ํฌ๋งท์ด ๋‹ฌ๋ผ(์˜ˆ: P2P๋Š” Data, WebSocket์€ String/JSON) ๋‹ค์Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋™์ผ ๊ธฐ๋Šฅ(์ดˆ๋Œ€/์ž…๋ ฅ/์˜์ƒ)์„ ๋ชจ๋“œ๋ณ„๋กœ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•˜๋ฉฐ ์ฝ”๋“œ ์ค‘๋ณต ์ฆ๊ฐ€
  • ViewModel/UI๊ฐ€ โ€œํ˜„์žฌ ํ†ต์‹  ๋ฐฉ์‹โ€์„ ์•Œ์•„์•ผ ํ•ด์„œ UI ๋กœ์ง์ด ๋„คํŠธ์›Œํฌ ๊ตฌํ˜„์— ์ข…์†
  • ์ „์†ก ํฌ๋งท ๋ณ€ํ™˜ ๋กœ์ง์ด ๊ณณ๊ณณ์— ํผ์ ธ ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ํ…Œ์ŠคํŠธ ๋น„์šฉ ์ฆ๊ฐ€

์›์ธ

  • ํ†ต์‹  ๋ฐฉ์‹๋ณ„ API๊ฐ€ ๋‹ฌ๋ผ ์ƒ์œ„ ๋ ˆ์ด์–ด์—์„œ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ(์„œ๋ฒ„ ๋ชจ๋“œ/P2P ๋ชจ๋“œ)๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ „์†ก ๋‹จ์œ„๊ฐ€ ๋‹ค๋ฆ„(Binary Data vs JSON String) โ†’ ๋ณ€ํ™˜ ์ฑ…์ž„์ด ์ƒ์œ„ ๋ ˆ์ด์–ด๋กœ ์ƒˆ์–ด ๋‚˜์™”์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ

1) ํ”„๋กœํ† ์ฝœ ์ถ”์ƒํ™”๋กœ ์ธํ„ฐํŽ˜์ด์Šค ํ‘œ์ค€ํ™”

์ƒ์œ„ ๋ ˆ์ด์–ด๊ฐ€ ๊ตฌ์ฒด ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ผ ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•˜๋„๋ก ์ตœ์ƒ์œ„ ํ”„๋กœํ† ์ฝœ์„ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

image
  • ConnectionSessionManaging
    • ์—ฐ๊ฒฐ ๊ด€๋ฆฌ: activate, deactivate
    • ์ด๋ฒคํŠธ ์ˆ˜์‹ (๊ตฌ๋…): onInviteReceived, onInputReceived, onVideoReceived
    • ์•ก์…˜ ๋ฐœ์‹ : sendInvite(), sendInput(), sendVideo()

๋˜ํ•œ ๋ชจ๋“œ๋ณ„ ์ „์šฉ ๊ธฐ๋Šฅ์€ ํ•˜์œ„ ํ”„๋กœํ† ์ฝœ๋กœ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • NetworkSessionManaging (P2P ์ „์šฉ)
  • WebSocketSessionManaging (์„œ๋ฒ„ ์ „์šฉ)

๊ฒฐ๊ณผ์ ์œผ๋กœ ViewModel์€ P2P/์„œ๋ฒ„ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ API๋กœ ๋™์ž‘ํ•˜๋„๋ก ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

2) ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์œผ๋กœ ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋‹จ์ผํ™”(Data)

์ƒ์œ„ ๋ ˆ์ด์–ด์—์„œ๋Š” ์ „์†ก ๋‹จ์œ„๋ฅผ Data๋กœ ํ†ต์ผํ–ˆ์Šต๋‹ˆ๋‹ค. image

  • P2P: Data ๊ธฐ๋ฐ˜ โ†’ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
  • WebSocket: ๋‚ด๋ถ€์—์„œ String โ†” Data ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ ์—ญํ•  ๋‹ด๋‹น

์ „์†ก ํฌ๋งท ์ฐจ์ด๋ฅผ ํ•˜์œ„ ๋ ˆ์ด์–ด๋กœ ์ˆจ๊ฒจ, ์ƒ์œ„ ๋กœ์ง์˜ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ๋ณ€ํ™˜ ์ฑ…์ž„์„ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์•˜์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

  • ๋ชจ๋“œ(P2P/์„œ๋ฒ„)์— ๊ด€๊ณ„์—†์ด ์ดˆ๋Œ€/์ž…๋ ฅ/์˜์ƒ ํ๋ฆ„์„ ๋™์ผ ์ฝ”๋“œ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • UI/ViewModel์ด ํ†ต์‹  ๋ฐฉ์‹์— ์ข…์†๋˜์ง€ ์•Š์•„ ๊ด€์‹ฌ์‚ฌ๊ฐ€ ๋ถ„๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜์ด๋ผ Mock ์ฃผ์ž…์ด ์‰ฌ์›Œ์ ธ ๋„คํŠธ์›Œํฌ ์—†์ด๋„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ํ™•๋ณดํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ ๋ฌธ์„œ: ํ†ตํ•ฉ ๋„คํŠธ์›Œํฌ ๋ ˆ์ด์–ด


๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด ํ”Œ๋žซํผ ์ฐฉ์ง€ ๋ถˆ์ผ์น˜(One-Way Platform) ์•ˆ์ •ํ™”

๋ฌธ์ œ

๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์—์„œ ํ”Œ๋žซํผ ์ถฉ๋Œ ํ™œ์„ฑ ์—ฌ๋ถ€๊ฐ€ ๋กœ์ปฌ ์บ๋ฆญํ„ฐ ๊ธฐ์ค€์œผ๋กœ๋งŒ ํŒ๋‹จ๋˜๋ฉด์„œ, ์›๊ฒฉ ์บ๋ฆญํ„ฐ๊ฐ€ ๋กœ์ปฌ ๊ธฐ์ค€์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋œ ํ”Œ๋žซํผ์„ ๋ฐŸ์ง€ ๋ชปํ•˜๊ฑฐ๋‚˜(์ฐฉ์ง€ ์‹คํŒจ), ๋กœ์ปฌ/์›๊ฒฉ ๊ฐ„ ์ถฉ๋Œ ์ƒํƒœ๊ฐ€ ๋‹ฌ๋ผ ์ฐฉ์ง€ ๋™์ž‘์ด ๋ถˆ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ํ”Œ๋žซํผ์„ ์ƒ์Šน ์‹œ ํ†ต๊ณผ / ํ•˜๊ฐ• ์‹œ ์ฐฉ์ง€(One-Way)๋กœ ๋™์ž‘์‹œํ‚ค๋Š” ๊ณผ์ •์—์„œ, ๋น ๋ฅธ ๋‚™ํ•˜ ์‹œ ์ถฉ๋Œ ํ™œ์„ฑ ํƒ€์ด๋ฐ์„ ๋†“์ณ ๊ด€ํ†ต์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์›์ธ

  • ๋กœ์ปฌ/์›๊ฒฉ์ด ๊ณต์œ ํ•˜๋Š” ๋‹จ์ผ ์ถฉ๋Œ ํŒ๋‹จ ๋กœ์ง์œผ๋กœ ์ธํ•ด ์บ๋ฆญํ„ฐ๋ณ„ ์ถฉ๋Œ ์ƒํƒœ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ œ์–ดํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.
  • One-Way ํ”Œ๋žซํผ ๊ตฌํ˜„ ์‹œ, ํ”„๋ ˆ์ž„ ์‚ฌ์ด ์ด๋™๋Ÿ‰์ด ํฐ ๊ฒฝ์šฐ(๋น ๋ฅธ ๋‚™ํ•˜) ํ™œ์„ฑ ์กฐ๊ฑด์„ ๋†“์ณ ๊ด€ํ†ต์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ

1) ๋กœ์ปฌ/์›๊ฒฉ ์ถฉ๋Œ ์นดํ…Œ๊ณ ๋ฆฌ ๋ถ„๋ฆฌ ํ”Œ๋žซํผ ์ถฉ๋Œ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์บ๋ฆญํ„ฐ ํƒ€์ž…๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ, ๋™์ผ ํ”Œ๋žซํผ์ด๋ผ๋„ ๋กœ์ปฌ/์›๊ฒฉ์ด ์„œ๋กœ ๋‹ค๋ฅธ ์ถฉ๋Œ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • groundMe: ๋กœ์ปฌ ์ „์šฉ
  • groundOther: ์›๊ฒฉ ์ „์šฉ

2) ํ•˜๊ฐ• ์ค‘์—๋งŒ ์ฐฉ์ง€(One-Way Platform) collisionBitMask๋Š” ํ•ญ์ƒ ํ”Œ๋ ˆ์ด์–ด์™€์˜ ์ถฉ๋Œ ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•˜๊ณ , ์‹ค์ œ ์ฐฉ์ง€ ์—ฌ๋ถ€๋Š” categoryBitMask๋ฅผ ํ”„๋ ˆ์ž„ ๋‹จ์œ„๋กœ ON/OFF ํ•˜์—ฌ ์ œ์–ดํ–ˆ์Šต๋‹ˆ๋‹ค. image

  • ํ•˜๊ฐ• ์‹œ(dy <= 0): category ON โ†’ ์ฐฉ์ง€
  • ์ƒ์Šน ์‹œ(dy > 0): category OFF โ†’ ํ†ต๊ณผ

์„ ์ • ์ด์œ 
collisionBitMask๋ฅผ ๋งค ํ”„๋ ˆ์ž„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฌผ๋ฆฌ ๋™์ž‘ ์˜ˆ์ธก์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์–ด,
์ถฉ๋Œ ๊ด€๊ณ„๋Š” ๊ณ ์ •ํ•œ ์ฑ„ categoryBitMask๋งŒ ํ† ๊ธ€ํ•˜์—ฌ โ€œ์ฐฉ์ง€ ๊ฐ€๋Šฅํ•œ ํ”Œ๋žซํผโ€์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

3) ๋น ๋ฅธ ๋‚™ํ•˜ ๊ด€ํ†ต ๋ฐฉ์ง€(Fall Buffer) ๋น ๋ฅธ ๋‚™ํ•˜๋กœ ํ”„๋ ˆ์ž„ ์‚ฌ์ด ๊ด€ํ†ต์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋‚™ํ•˜ ์†๋„์— ๋น„๋ก€ํ•ด buffer๋ฅผ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

  • buffer = min(200, 20 + |dy| * dt * 1.5) (ํ•˜๊ฐ• ์‹œ์—๋งŒ)

๊ฒฐ๊ณผ

  • ๋กœ์ปฌ/์›๊ฒฉ ์บ๋ฆญํ„ฐ์˜ ํ”Œ๋žซํผ ์ถฉ๋Œ์„ ๋…๋ฆฝ์ ์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์—์„œ ๋ฐœ์ƒํ•˜๋˜ ์ฐฉ์ง€ ๋ถˆ์ผ์น˜์™€ ์ฒด๊ฐ ์ด์งˆ๊ฐ์ด ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.
  • One-Way ๋™์ž‘(์ƒ์Šน ํ†ต๊ณผ/ํ•˜๊ฐ• ์ฐฉ์ง€)์„ ์•ˆ์ •์ ์œผ๋กœ ๋ณด์žฅํ•˜๊ณ , ๋น ๋ฅธ ๋‚™ํ•˜ ์ƒํ™ฉ์—์„œ์˜ ๊ด€ํ†ต ํ˜„์ƒ์„ ์œ ์˜๋ฏธํ•˜๊ฒŒ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

(์—ฐ๊ด€) ์›๊ฒฉ ์ ํ”„ ํ™•์ • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”

๋„คํŠธ์›Œํฌ ์ง€์—ฐ์œผ๋กœ ์›๊ฒฉ ์ ํ”„ ์ž…๋ ฅ์ด ๋ˆ„๋ฝ/์ง€์—ฐ๋  ์ˆ˜ ์žˆ์–ด, ์›๊ฒฉ ์ ํ”„๋ฅผ โ€œ์ž…๋ ฅโ€์ด ์•„๋‹Œ ํ™•์ • ์ด๋ฒคํŠธ(jumpTriggered) ๋กœ ์ „์†กยท์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณด์™„ํ–ˆ์Šต๋‹ˆ๋‹ค. image

  • NetworkGameInputDTO.Kind.jumpTriggered
  • GameplayManager.applyJumpTriggered
  • MultiplayerNetworkIO.installLocalJumpTriggeredSender

๊ด€๋ จ ๋ฌธ์„œ: ํ”Œ๋žซํผ ์ถฉ๋Œ ๋ถ„๋ฆฌ ๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด ๋ฆฌ์Šคํฐ ๋™๊ธฐํ™”


๋น„๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ ๊ตฌํ˜„ ๋ฐฉ์‹ - MJPEG vs WebRTC vs Native H.264 VideoToolbox

๊ธฐ์ˆ  ์Šคํƒ ์„ ์ • ๋น„๊ต ๋ถ„์„ํ‘œ๋น„๊ต ํ•ญ๋ชฉ

๋น„๊ต ํ•ญ๋ชฉ 1. MJPEG (๊ธฐ์กด POC) 2. WebRTC (์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) 3. Native H.264 (์ œ์•ˆ)
์••์ถ• ๋ฐฉ์‹ ๋งค ํ”„๋ ˆ์ž„ ์ „์ฒด ์ „์†ก (I-Frame Only) ์ฐจ์ด๊ฐ’ ์ „์†ก (Inter-frame) ์ฐจ์ด๊ฐ’ ์ „์†ก (Inter-frame)
๋Œ€์—ญํญ (30fps) ๋งค์šฐ ๋†’์Œ (~1.5 MB/s) ๋‚ฎ์Œ (~0.1 MB/s) ๋‚ฎ์Œ (~0.1 MB/s)
์•ฑ ์šฉ๋Ÿ‰ ์ฆ๊ฐ€ ์—†์Œ (0 MB) ํผ (+50~100 MB)
โ†’ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ธํ•ด ๋นŒ๋“œ ์†๋„ ์ €ํ•˜ ๋ฐ ์˜์กด์„ฑ ์ฆ๊ฐ€
์—†์Œ (0 MB)
๋„คํŠธ์›Œํฌ ํ†ตํ•ฉ ์‰ฌ์›€ ๋ณ„๋„ ์ฑ„๋„ ํ•„์š” ๊ธฐ์กด ํŒจํ‚ท ํ™œ์šฉ
โ†’ ping/pong ์‹œ๊ทธ๋„๋ง ํ™œ์šฉ
ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์ง€์› ์•ˆ ํ•จ (CPU ๋ถ€ํ•˜ ํผ) ์ง€์›ํ•จ ์ง€์›ํ•จ (OS ๋ ˆ๋ฒจ ์ตœ์ ํ™”)
๊ฒฐ๋ก  โŒ ๋น„ํšจ์œจ์  (ํ๊ธฐ) โš ๏ธ Overkill (๊ณผ์ž‰) โœ… Best Fit (์ตœ์ )

๊ฒฐ๋ก : Native H.264 VideoToolbox ์‚ฌ์šฉ

๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋„˜์–ด ์•ฑ์˜ ํ•ต์‹ฌ ์„œ๋น„์Šค๋ฅผ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ๋„ค์ดํ‹ฐ๋ธŒ ํ™˜๊ฒฝ์—์„œ ์ง์ ‘ ๊ตฌ์ถ•ํ•จ์œผ๋กœ์จ ํ”„๋กœ์ ํŠธ ์ตœ์ ํ™”์™€ ๊ธฐ์ˆ ์  ์„ฑ์žฅ์„ ๋™์‹œ์— ๋„๋ชจํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์— ๋ฌด๊ฑฐ์šด WebRTC ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Œ€์‹ , ์• ํ”Œ์˜ **VideoToolbox**๋ฅผ ์ง์ ‘ ์ œ์–ดํ•˜์—ฌ ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ๊ธฐ๋ฐ˜์˜ H.264 ์••์ถ•์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉํ–ฅ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด MJPEG ๋Œ€๋น„ ๋ฐ์ดํ„ฐ ์†Œ๋ชจ๋Ÿ‰์„ 1/30 ์ˆ˜์ค€์œผ๋กœ ์ ˆ๊ฐํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ํšจ์œจ์„ ๊ทน๋Œ€ํ™”ํ•˜๊ณ , ์ €์ˆ˜์ค€(Low-level) API๋ฅผ ๋Šฅ๋™์ ์œผ๋กœ ์„ค๊ณ„ํ•จ์œผ๋กœ์จ ๊ธฐ๊ธฐ ๋ฐœ์—ด ์ตœ์†Œํ™”์™€ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ง์ ‘ ์ด๋Œ์–ด๋‚ด๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ํŽธ๋ฆฌํ•จ ๋Œ€์‹ , ์„œ๋น„์Šค์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์„ค๊ณ„๋ฅผ ํ†ตํ•ด ๊ธฐ์ˆ ์  ์™„์„ฑ๋„๋ฅผ ๋†’์ด๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ๋ฌธ์„œ: VideoToolbox ์‚ฌ์šฉ ์ด์œ 



ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ๋ฐฉ์‹

์ฝ”์Šค๋ฏน ์–ด๋“œ๋ฒค์ฒ˜๋Š” โ€œ์™„์„ฑ๋„๋ฅผ ๋น ๋ฅด๊ฒŒ ๋Œ์–ด์˜ฌ๋ฆฌ๋˜, ๋ฆฌ์Šคํฌ๋Š” ์ž‘๊ฒŒโ€ ๊ฐ€์ ธ๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜ 3๊ฐ€์ง€๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ค๊ณ„ํ•˜๊ณ  ์šด์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

1) ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ํ•œ ์ ์ง„์  ๊ฐœ์„  (Iterative Improvement)

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2026-02-01 แ„‹แ…ฉแ„’แ…ฎ 10 39 15

์ €ํฌ๋Š” TestFlight/๋ฐ๋ชจ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋ฅผ ์งง๊ฒŒ ๊ฐ€์ ธ๊ฐ€๋ฉฐ, ์ž‘์€ ๋‹จ์œ„๋กœ ๋ฐฐํฌโ†’๊ด€์ฐฐโ†’๊ฐœ์„ ์„ ๋ฐ˜๋ณตํ–ˆ์Šต๋‹ˆ๋‹ค.
ํŠนํžˆ AR ์ž…๋ ฅ/๋ฉ€ํ‹ฐํ”Œ๋ ˆ์ด์ฒ˜๋Ÿผ ํŠœ๋‹์ด ์ค‘์š”ํ•œ ์˜์—ญ์€ ์ฒด๊ฐ ํ’ˆ์งˆ(์˜ค์ž‘๋™ยท์ง€์—ฐยท๋ชฐ์ž…๊ฐ) ๊ธฐ์ค€์œผ๋กœ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์กฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

A. ํ”Œ๋ ˆ์ด ๋ฒ„๊ทธ ํ”ผ๋“œ๋ฐฑ โ†’ ๋ฃฐ/์นด๋ฉ”๋ผ/๋ฌผ๋ฆฌ ์•ˆ์ •ํ™”

  • ํ”ผ๋“œ๋ฐฑ: โ€œ์˜คํ”„๋ผ์ธ/๊ทผ๊ฑฐ๋ฆฌโ€ ์ค‘์‹ฌ์œผ๋กœ ์„ค๋ช…ํ–ˆ์ง€๋งŒ, ์„œ๋น„์Šค ๊ฒฝํ—˜์„ ๊ทผ๊ฑฐ๋ฆฌ๋กœ๋งŒ ์ œํ•œํ•  ํ•„์š”๋Š” ์—†๊ฒ ๋‹ค๋Š” ์˜๊ฒฌ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ์„ : ๋ฉ”์‹œ์ง€๋ฅผ โ€˜์–ด๋””์„œ๋‚˜/์–ด๋А ํ™˜๊ฒฝ์—์„œ๋‚˜ ํ•จ๊ป˜โ€™ ๋กœ ํ™•์žฅํ•˜๊ณ ,
    ์ธํ„ฐ๋„ท์ด ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” ์„œ๋ฒ„ ๊ธฐ๋ฐ˜ ์ฑ„๋„ ๋งค์นญ์œผ๋กœ ์žฅ๊ฑฐ๋ฆฌ ํ”Œ๋ ˆ์ด,
    ๋ถˆ์•ˆ์ •/๋‹จ์ ˆ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ทผ๊ฑฐ๋ฆฌ P2P๋กœ ์ฆ‰์‹œ ์—ฐ๊ฒฐ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ฐฉํ–ฅ์„ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

B. UX ํ”ผ๋“œ๋ฐฑ โ†’ ์ดํƒˆ ํฌ์ธํŠธ ์ œ๊ฑฐ

  • ํ”ผ๋“œ๋ฐฑ: ํ”Œ๋ ˆ์ด ์ค‘ ํ™”๋ฉด ์ž๋™ ๊บผ์ง(ํ™”๋ฉด๋ณดํ˜ธ๊ธฐ๋Šฅ), ๋™๋ฃŒ ์„ ํƒ ํ•ด์ œ, ์‚ฌ์šฉ๋ฒ• ์•ˆ๋‚ด(๋‹ค์‹œ๋ณด์ง€ ์•Š๊ธฐ), ํ‚ค๋ณด๋“œ ํฌ์ปค์Šค ํ•ด์ œ, PIP ํฌ๊ธฐ/์œ„์น˜, ์บ /์ ์ˆ˜ ๋ ˆ์ด์•„์›ƒ, ๊ฐ€๋กœ๋ชจ๋“œ, โ€œ๋” ๋จผ ์€ํ•˜โ€ ๋„ค์ด๋ฐ/๋’ค๋กœ๊ฐ€๊ธฐ ํ˜ผ๋ž€, ๊ถŒํ•œ ์žฌ์š”์ฒญ ๋“ฑ์ด ๋ถˆํŽธ ์š”์†Œ๋กœ ๋‚˜์™”์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ์„ : ๊ฒŒ์ž„ ํ๋ฆ„์„ ์ง์ ‘ ๋Š๋Š” ์ด์Šˆ(๊ถŒํ•œ/ํšŒ์ „, ํ๋ฆ„/๋„ค์ด๋ฐ)๋ฅผ ์šฐ์„ ์ˆœ์œ„ ์ƒ๋‹จ์œผ๋กœ ๋‘๊ณ , ์„ ํƒ/์ž…๋ ฅ/์•ˆ๋‚ด UX๋ฅผ ๋ฌถ์–ด ๋ฉˆ์นซํ•˜๋Š” ์ง€์ ์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.

    PR: #92 #97 #148

C. ์ดˆ๋Œ€ ์ˆ˜์‹  ๊ฒฝํ—˜ ๊ฐœ์„ (์‹ฑ๊ธ€ ํ”Œ๋ ˆ์ด ์ค‘)

  • ํ”ผ๋“œ๋ฐฑ: ์•Œ๋ฆผ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹์€ ๊ฒŒ์ž„ ์ค‘ ์ดˆ๋Œ€๋ฅผ ๋†“์น˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์˜๊ฒฌ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ์„ : ์‹ฑ๊ธ€ ํ”Œ๋ ˆ์ด ๋„์ค‘์—๋„ ์ดˆ๋Œ€๋ฅผ ์ฆ‰์‹œ ์ธ์ง€ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก Local Notification + ์ธ์•ฑ Top Modal ๋ฐฉํ–ฅ์„ ๊ฒ€ํ† /์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

    PR: #168


2) ํƒœ์Šคํฌ ๊ด€๋ฆฌ ๋ฐ ๋ถ„๋ฐฐ (Task Management & Ownership)

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2026-02-01 แ„‹แ…ฉแ„’แ…ฎ 11 26 07
  • Linear ๊ธฐ๋ฐ˜ ์ด์Šˆ ํŠธ๋ž˜ํ‚น์œผ๋กœ ์ž‘์—…์„ ์ชผ๊ฐœ๊ณ , ๊ฐ ํƒœ์Šคํฌ์— ๋‹ด๋‹น์ž(Owner)์™€ ์™„๋ฃŒ ์กฐ๊ฑด(DoD) ์„ ๋ช…ํ™•ํžˆ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ ์ „, ๊ธฐ์ˆ  ๊ฒฝํ—˜์„ ๋น ๋ฅด๊ฒŒ ๋งž์ถ”๊ธฐ ์œ„ํ•ด PoC ์ „์šฉ ๋ธŒ๋žœ์น˜๋ฅผ ์šด์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
    ํŒ€์›๋“ค์ด SpriteKit / Network.framework / Video(H.264) ํ•ต์‹ฌ ์˜์—ญ์„ ๊ฐ๊ฐ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ํ•ด๋ณด๊ณ , ์ดํ›„ ๋ณธ ๊ฐœ๋ฐœ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ๊ณตํ†ต ์ดํ•ด๋„๋ฅผ ํ™•๋ณดํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ณธ ๊ฐœ๋ฐœ ๋‹จ๊ณ„์—์„œ๋Š” ๋ชจ๋“ˆ ๊ตฌ์กฐ(App / GameEngineCore / Games / InputSystem / NetworkKit / StorageKit / VideoKit`)์— ๋งž์ถฐ
    ๊ฒฝ๊ณ„๊ฐ€ ๊นจ์ง€์ง€ ์•Š๋„๋ก ํƒœ์Šคํฌ๋ฅผ ๋ถ„๋ฐฐํ•ด ๋ณ‘๋ ฌ ๊ฐœ๋ฐœ ํšจ์œจ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค.
  • ๋˜ํ•œ ํŠน์ • ์‚ฌ๋žŒ์—๊ฒŒ ์ง€์‹์ด ์ ๋ฆฌ์ง€ ์•Š๋„๋ก, ํŒ€์› ๋ชจ๋‘๊ฐ€ ๊ฐ ๋ชจ๋“ˆ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ
    ๋‹ด๋‹นํ•˜์ง€ ์•Š์•˜๋˜ ์˜์—ญ๋„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ๊ฐœ์„ /์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์šด์˜ํ–ˆ์Šต๋‹ˆ๋‹ค(๋ฒ„์Šค ํŒฉํ„ฐ ๊ฐ์†Œ).
  • PR์€ โ€œ๋ฆฌ๋ทฐ ๊ฐ€๋Šฅํ•œ ํฌ๊ธฐโ€๋ฅผ ์œ ์ง€ํ•˜๊ณ , ๋ณ‘ํ•ฉ ํ›„์—๋Š” ๋ณ€๊ฒฝ ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ๊ณต์œ ํ•ด ๋ฆฌ๊ทธ๋ ˆ์…˜์„ ์ตœ์†Œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

3) AI ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„์ž… (CodeRabbit)

image
  • ๋ฐ˜๋ณต์ ์œผ๋กœ ๋†“์น˜๊ธฐ ์‰ฌ์šด ๋ถ€๋ถ„(๋„ค์ด๋ฐ/๋ฌธ์„œํ™”/์ปจ๋ฒค์…˜/์ž ์žฌ ๋ฒ„๊ทธ)์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด
    CodeRabbit ๊ธฐ๋ฐ˜ AI ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ CI ํ๋ฆ„์— ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ๋žŒ ๋ฆฌ๋ทฐ๋Š” ์„ค๊ณ„/๊ฒฝ๊ณ„/์˜๋„(Why) ์ค‘์‹ฌ์œผ๋กœ, AI ๋ฆฌ๋ทฐ๋Š” ์„ธ๋ถ€ ํ’ˆ์งˆ(์ผ๊ด€์„ฑ/์•ˆ์ „์„ฑ/๋ˆ„๋ฝ) ์„ ๋ณด์กฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์—ญํ• ์„ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌ๋ทฐ ์šด์˜ ๋ฐฉ์‹ (P1 / P2)

  • ์‚ฌ๋žŒ ๋ฆฌ๋ทฐ ์ฝ”๋ฉ˜ํŠธ๋Š” P1 / P2๋กœ ๋ถ„๋ฆฌํ•ด ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค.
    • P1: ๊ผญ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ์‚ฌํ•ญ(๋ฒ„๊ทธ ๊ฐ€๋Šฅ์„ฑ, ์„ค๊ณ„/๊ฒฝ๊ณ„ ์œ„๋ฐ˜, ์•ˆ์ •์„ฑ/๋™์‹œ์„ฑ ์ด์Šˆ ๋“ฑ)
    • P2: ์‚ฌ์†Œํ•˜์ง€๋งŒ ๊ฐœ์„ ํ•˜๋ฉด ์ข‹์€ ์‚ฌํ•ญ(์Šคํƒ€์ผ, ๋„ค์ด๋ฐ, ์ฃผ์„/๋ฌธ์„œํ™”, ๋ฏธ์„ธํ•œ ๋ฆฌํŒฉํ„ฐ๋ง ๋“ฑ)
  • ๋ฐ˜์˜ ๋ฐฉ์‹๋„ ๊ตฌ๋ถ„ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • P1 ์ˆ˜์ •์€ ๋ณ„๋„ ์ปค๋ฐ‹์œผ๋กœ ๋‚จ๊ฒจ ๋ณ€๊ฒฝ ์˜๋„์™€ ์˜ํ–ฅ์„ ๋ช…ํ™•ํžˆ ์ถ”์  ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • P2๋Š” ๊ธฐ์กด ์ปค๋ฐ‹์„ ์ •๋ฆฌ(reword/fixup)ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค.

CodeRabbit ๋„์ž… ํšจ๊ณผ

image
  • PR์—์„œ ๋†“์น˜๊ธฐ ์‰ฌ์šด ๋ฌธ์„œ/๋„ค์ด๋ฐ/์ปจ๋ฒค์…˜ ๋ˆ„๋ฝ์„ ์ž๋™์œผ๋กœ ์žก์•„์ค˜, ๊ธฐ๋ณธ ํ’ˆ์งˆ์„ ์•ˆ์ •์ ์œผ๋กœ ๋Œ์–ด์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค.
  • ๋™์‹œ์„ฑ/์•ˆ์ „์„ฑ ๊ด€์ ์˜ ์ž ์žฌ ๋ฆฌ์Šคํฌ๋ฅผ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•ด, ์ˆ˜์ • ๋น„์šฉ์ด ๋‚ฎ์„ ๋•Œ ๋น ๋ฅด๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ๋žŒ ๋ฆฌ๋ทฐ๋Š” โ€œ์ค‘์š”ํ•œ ๋…ผ์ (P1)โ€์— ์ง‘์ค‘ํ•˜๊ณ , AI๊ฐ€ โ€œ์ž์ž˜ํ•œ ํ’ˆ์งˆ(P2)โ€์„ ๋ณด์กฐํ•˜๋ฉด์„œ
    ๋ฆฌ๋ทฐ ์†๋„์™€ ๋ฐ€๋„๊ฐ€ ํ•จ๊ป˜ ์ข‹์•„์กŒ๊ณ , ๋ฐ˜๋ณต ํ”ผ๋“œ๋ฐฑ(์ปจ๋ฒค์…˜/์Šคํƒ€์ผ)์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ๋น„์šฉ์ด ์ค„์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ, PR ๋‹น ๋ฆฌ๋ทฐ ์‚ฌ์ดํด์ด ๋” ์˜ˆ์ธก ๊ฐ€๋Šฅํ•ด์กŒ๊ณ , ํ’ˆ์งˆ ๊ธฐ์ค€์„ ํŒ€ ์ „์ฒด์— ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.



Development

์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ

brew install tuist

์ดˆ๊ธฐ ์„ค์ •

make setup

์‹คํ–‰

make ios        # iOS ์•ฑ ์‹คํ–‰
make backend    # ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์‹คํ–‰

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

make generate   # ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ์ƒ์„ฑ
make migrate    # DB์— ์ ์šฉ
make db-reset   # DB ์ดˆ๊ธฐํ™”

๊ธฐํƒ€

make test       # ํ…Œ์ŠคํŠธ ์‹คํ–‰
make clean      # ์ •๋ฆฌ

About

๐Ÿ›ธ ์–ธ์ œ, ์–ด๋””์„œ๋‚˜ ํ™˜๊ฒฝ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  ์ฆ๊ธธ ์ˆ˜ ์žˆ๋Š” ์ฝ”์Šค๋ฏน ์–ด๋“œ๋ฒค์ฒ˜

Resources

Stars

10 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages